From e71ace994cc913455fb85e19bcb6d8ff859c1188 Mon Sep 17 00:00:00 2001 From: Valentin Le Moign Date: Thu, 8 May 2025 11:58:35 +0200 Subject: [PATCH] transfer depuis gogs --- .dependencies | 34 + .editorconfig | 18 + .gitignore | 43 + .htaccess | 75 + .phan/config.php | 44 + .phan/internal_stubs/Redis.phan_php | 5153 +++++++++ .phan/internal_stubs/memcache.phan_php | 460 + .phan/internal_stubs/memcached.phan_php | 1308 +++ .travis.yml | 104 + CHANGELOG.md | 4162 +++++++ CODE_OF_CONDUCT.md | 133 + CONTRIBUTING.md | 138 + LICENSE.txt | 21 + README.md | 156 + SECURITY.md | 38 + assets/.gitkeep | 1 + backup/.gitkeep | 0 bin/composer.phar | Bin 0 -> 2977479 bytes bin/gpm | 46 + bin/grav | 42 + bin/plugin | 43 + cache/.gitkeep | 0 codeception.yml | 16 + composer.json | 130 + composer.lock | 6405 +++++++++++ images/.gitkeep | 0 index.php | 51 + logs/.gitkeep | 0 now.json | 4 + robots.txt | 12 + system/assets/debugger/clockwork.css | 61 + system/assets/debugger/clockwork.js | 37 + system/assets/debugger/phpdebugbar.css | 67 + system/assets/grav.png | Bin 0 -> 1612 bytes system/assets/jquery/jquery-2.1.4.min.js | 4 + system/assets/jquery/jquery-2.x.min.js | 4 + system/assets/jquery/jquery-3.x.min.js | 2 + system/assets/responsive-overlays/1x.png | Bin 0 -> 3238 bytes system/assets/responsive-overlays/2x.png | Bin 0 -> 7593 bytes system/assets/responsive-overlays/3x.png | Bin 0 -> 13002 bytes system/assets/responsive-overlays/4x.png | Bin 0 -> 15545 bytes system/assets/responsive-overlays/unknown.png | Bin 0 -> 5241 bytes system/assets/whoops.css | 19 + system/blueprints/config/backups.yaml | 125 + system/blueprints/config/media.yaml | 5 + system/blueprints/config/scheduler.yaml | 78 + system/blueprints/config/security.yaml | 119 + system/blueprints/config/site.yaml | 124 + system/blueprints/config/streams.yaml | 8 + system/blueprints/config/system.yaml | 1894 ++++ system/blueprints/flex/accounts.yaml | 8 + system/blueprints/flex/configure/compat.yaml | 17 + system/blueprints/flex/pages.yaml | 212 + system/blueprints/flex/shared/configure.yaml | 70 + system/blueprints/flex/user-accounts.yaml | 155 + system/blueprints/flex/user-groups.yaml | 124 + system/blueprints/pages/default.yaml | 381 + system/blueprints/pages/external.yaml | 52 + system/blueprints/pages/modular.yaml | 36 + .../blueprints/pages/partials/security.yaml | 67 + system/blueprints/pages/root.yaml | 16 + system/blueprints/user/account.yaml | 157 + system/blueprints/user/account_new.yaml | 18 + system/blueprints/user/group.yaml | 55 + system/blueprints/user/group_new.yaml | 23 + system/config/backups.yaml | 15 + system/config/media.yaml | 223 + system/config/mime.yaml | 1986 ++++ system/config/permissions.yaml | 53 + system/config/security.yaml | 47 + system/config/site.yaml | 35 + system/config/system.yaml | 233 + system/defines.php | 104 + system/images/media/thumb-3dm.png | Bin 0 -> 3013 bytes system/images/media/thumb-3ds.png | Bin 0 -> 3116 bytes system/images/media/thumb-3g2.png | Bin 0 -> 3006 bytes system/images/media/thumb-3gp.png | Bin 0 -> 2853 bytes system/images/media/thumb-7z.png | Bin 0 -> 1648 bytes system/images/media/thumb-aac.png | Bin 0 -> 3218 bytes system/images/media/thumb-ai.png | Bin 0 -> 1595 bytes system/images/media/thumb-aif.png | Bin 0 -> 1691 bytes system/images/media/thumb-apk.png | Bin 0 -> 2557 bytes system/images/media/thumb-app.png | Bin 0 -> 2360 bytes system/images/media/thumb-asf.png | Bin 0 -> 2635 bytes system/images/media/thumb-asp.png | Bin 0 -> 2913 bytes system/images/media/thumb-aspx.png | Bin 0 -> 3726 bytes system/images/media/thumb-asx.png | Bin 0 -> 3287 bytes system/images/media/thumb-avi.png | Bin 0 -> 2448 bytes system/images/media/thumb-bak.png | Bin 0 -> 2814 bytes system/images/media/thumb-bat.png | Bin 0 -> 2182 bytes system/images/media/thumb-bin.png | Bin 0 -> 1841 bytes system/images/media/thumb-bmp.png | Bin 0 -> 2573 bytes system/images/media/thumb-cab.png | Bin 0 -> 3056 bytes system/images/media/thumb-cad.png | Bin 0 -> 3021 bytes system/images/media/thumb-cdr.png | Bin 0 -> 2713 bytes system/images/media/thumb-cer.png | Bin 0 -> 2367 bytes system/images/media/thumb-cfg.png | Bin 0 -> 2764 bytes system/images/media/thumb-cfm.png | Bin 0 -> 2589 bytes system/images/media/thumb-cgi.png | Bin 0 -> 2626 bytes system/images/media/thumb-com.png | Bin 0 -> 3292 bytes system/images/media/thumb-cpl.png | Bin 0 -> 2174 bytes system/images/media/thumb-cpp.png | Bin 0 -> 2425 bytes system/images/media/thumb-crx.png | Bin 0 -> 2965 bytes system/images/media/thumb-csr.png | Bin 0 -> 3158 bytes system/images/media/thumb-css.png | Bin 0 -> 3235 bytes system/images/media/thumb-csv.png | Bin 0 -> 3317 bytes system/images/media/thumb-cue.png | Bin 0 -> 2271 bytes system/images/media/thumb-cur.png | Bin 0 -> 2716 bytes system/images/media/thumb-dat.png | Bin 0 -> 2188 bytes system/images/media/thumb-db.png | Bin 0 -> 1964 bytes system/images/media/thumb-dbf.png | Bin 0 -> 1947 bytes system/images/media/thumb-dds.png | Bin 0 -> 2815 bytes system/images/media/thumb-dem.png | Bin 0 -> 2215 bytes system/images/media/thumb-dll.png | Bin 0 -> 1352 bytes system/images/media/thumb-dmg.png | Bin 0 -> 3064 bytes system/images/media/thumb-dmp.png | Bin 0 -> 2527 bytes system/images/media/thumb-doc.png | Bin 0 -> 3051 bytes system/images/media/thumb-docx.png | Bin 0 -> 3865 bytes system/images/media/thumb-drv.png | Bin 0 -> 2728 bytes system/images/media/thumb-dtd.png | Bin 0 -> 1949 bytes system/images/media/thumb-dwg.png | Bin 0 -> 3530 bytes system/images/media/thumb-dxf.png | Bin 0 -> 2392 bytes system/images/media/thumb-elf.png | Bin 0 -> 663 bytes system/images/media/thumb-eot.png | Bin 0 -> 2002 bytes system/images/media/thumb-eps.png | Bin 0 -> 2276 bytes system/images/media/thumb-exe.png | Bin 0 -> 1813 bytes system/images/media/thumb-fla.png | Bin 0 -> 1724 bytes system/images/media/thumb-flv.png | Bin 0 -> 1720 bytes system/images/media/thumb-fnt.png | Bin 0 -> 1254 bytes system/images/media/thumb-fon.png | Bin 0 -> 2402 bytes system/images/media/thumb-gam.png | Bin 0 -> 3203 bytes system/images/media/thumb-gbr.png | Bin 0 -> 2849 bytes system/images/media/thumb-ged.png | Bin 0 -> 2269 bytes system/images/media/thumb-gif.png | Bin 0 -> 1751 bytes system/images/media/thumb-gpx.png | Bin 0 -> 2972 bytes system/images/media/thumb-gz.png | Bin 0 -> 2134 bytes system/images/media/thumb-gzip.png | Bin 0 -> 2451 bytes system/images/media/thumb-hqz.png | Bin 0 -> 2604 bytes system/images/media/thumb-html.png | Bin 0 -> 1740 bytes system/images/media/thumb-icns.png | Bin 0 -> 3212 bytes system/images/media/thumb-ico.png | Bin 0 -> 2769 bytes system/images/media/thumb-ics.png | Bin 0 -> 2787 bytes system/images/media/thumb-iff.png | Bin 0 -> 601 bytes system/images/media/thumb-indd.png | Bin 0 -> 2475 bytes system/images/media/thumb-iso.png | Bin 0 -> 2864 bytes system/images/media/thumb-jar.png | Bin 0 -> 2583 bytes system/images/media/thumb-jpg.png | Bin 0 -> 2435 bytes system/images/media/thumb-js.png | Bin 0 -> 2046 bytes system/images/media/thumb-json.png | Bin 0 -> 7818 bytes system/images/media/thumb-jsp.png | Bin 0 -> 2498 bytes system/images/media/thumb-key.png | Bin 0 -> 2130 bytes system/images/media/thumb-kml.png | Bin 0 -> 2346 bytes system/images/media/thumb-kmz.png | Bin 0 -> 2701 bytes system/images/media/thumb-lnk.png | Bin 0 -> 1971 bytes system/images/media/thumb-log.png | Bin 0 -> 2762 bytes system/images/media/thumb-lua.png | Bin 0 -> 2117 bytes system/images/media/thumb-m3u.png | Bin 0 -> 2909 bytes system/images/media/thumb-m4a.png | Bin 0 -> 2754 bytes system/images/media/thumb-m4v.png | Bin 0 -> 2738 bytes system/images/media/thumb-max.png | Bin 0 -> 3213 bytes system/images/media/thumb-mdb.png | Bin 0 -> 2691 bytes system/images/media/thumb-mdf.png | Bin 0 -> 2243 bytes system/images/media/thumb-mid.png | Bin 0 -> 2199 bytes system/images/media/thumb-mim.png | Bin 0 -> 2284 bytes system/images/media/thumb-mov.png | Bin 0 -> 3221 bytes system/images/media/thumb-mp3.png | Bin 0 -> 2801 bytes system/images/media/thumb-mp4.png | Bin 0 -> 2221 bytes system/images/media/thumb-mpa.png | Bin 0 -> 2734 bytes system/images/media/thumb-mpe.png | Bin 0 -> 1971 bytes system/images/media/thumb-mpg.png | Bin 0 -> 2811 bytes system/images/media/thumb-msg.png | Bin 0 -> 3319 bytes system/images/media/thumb-msi.png | Bin 0 -> 2594 bytes system/images/media/thumb-nes.png | Bin 0 -> 2320 bytes system/images/media/thumb-obj.png | Bin 0 -> 2716 bytes system/images/media/thumb-odb.png | Bin 0 -> 2912 bytes system/images/media/thumb-odc.png | Bin 0 -> 3239 bytes system/images/media/thumb-odf.png | Bin 0 -> 2496 bytes system/images/media/thumb-odg.png | Bin 0 -> 3069 bytes system/images/media/thumb-odi.png | Bin 0 -> 2453 bytes system/images/media/thumb-odp.png | Bin 0 -> 2871 bytes system/images/media/thumb-ods.png | Bin 0 -> 3257 bytes system/images/media/thumb-odt.png | Bin 0 -> 2414 bytes system/images/media/thumb-odx.png | Bin 0 -> 3133 bytes system/images/media/thumb-ogg.png | Bin 0 -> 3577 bytes system/images/media/thumb-pct.png | Bin 0 -> 2248 bytes system/images/media/thumb-pdb.png | Bin 0 -> 2354 bytes system/images/media/thumb-pdf.png | Bin 0 -> 1823 bytes system/images/media/thumb-pif.png | Bin 0 -> 1103 bytes system/images/media/thumb-pkg.png | Bin 0 -> 2660 bytes system/images/media/thumb-pl.png | Bin 0 -> 1066 bytes system/images/media/thumb-png.png | Bin 0 -> 2530 bytes system/images/media/thumb-pps.png | Bin 0 -> 2497 bytes system/images/media/thumb-ppt.png | Bin 0 -> 1573 bytes system/images/media/thumb-pptx.png | Bin 0 -> 2560 bytes system/images/media/thumb-ps.png | Bin 0 -> 2285 bytes system/images/media/thumb-psd.png | Bin 0 -> 2613 bytes system/images/media/thumb-pub.png | Bin 0 -> 2137 bytes system/images/media/thumb-py.png | Bin 0 -> 1776 bytes system/images/media/thumb-ra.png | Bin 0 -> 2223 bytes system/images/media/thumb-rar.png | Bin 0 -> 2695 bytes system/images/media/thumb-raw.png | Bin 0 -> 3433 bytes system/images/media/thumb-rm.png | Bin 0 -> 2181 bytes system/images/media/thumb-rom.png | Bin 0 -> 3088 bytes system/images/media/thumb-rpm.png | Bin 0 -> 2566 bytes system/images/media/thumb-rss.png | Bin 0 -> 3091 bytes system/images/media/thumb-rtf.png | Bin 0 -> 1364 bytes system/images/media/thumb-sav.png | Bin 0 -> 3204 bytes system/images/media/thumb-sdf.png | Bin 0 -> 2444 bytes system/images/media/thumb-sql.png | Bin 0 -> 2929 bytes system/images/media/thumb-srt.png | Bin 0 -> 2366 bytes system/images/media/thumb-svg.png | Bin 0 -> 3359 bytes system/images/media/thumb-swf.png | Bin 0 -> 3181 bytes system/images/media/thumb-sys.png | Bin 0 -> 3128 bytes system/images/media/thumb-tar.png | Bin 0 -> 2165 bytes system/images/media/thumb-tex.png | Bin 0 -> 1716 bytes system/images/media/thumb-tga.png | Bin 0 -> 2655 bytes system/images/media/thumb-thm.png | Bin 0 -> 1666 bytes system/images/media/thumb-tiff.png | Bin 0 -> 690 bytes system/images/media/thumb-tmp.png | Bin 0 -> 2040 bytes system/images/media/thumb-ttf.png | Bin 0 -> 615 bytes system/images/media/thumb-txt.png | Bin 0 -> 1853 bytes system/images/media/thumb-uue.png | Bin 0 -> 1632 bytes system/images/media/thumb-vb.png | Bin 0 -> 2074 bytes system/images/media/thumb-vcd.png | Bin 0 -> 3040 bytes system/images/media/thumb-vcf.png | Bin 0 -> 2581 bytes system/images/media/thumb-wav.png | Bin 0 -> 3601 bytes system/images/media/thumb-webm.png | Bin 0 -> 3843 bytes system/images/media/thumb-wma.png | Bin 0 -> 3552 bytes system/images/media/thumb-wmv.png | Bin 0 -> 3789 bytes system/images/media/thumb-woff.png | Bin 0 -> 3421 bytes system/images/media/thumb-woff2.png | Bin 0 -> 3927 bytes system/images/media/thumb-wpd.png | Bin 0 -> 3127 bytes system/images/media/thumb-wps.png | Bin 0 -> 3368 bytes system/images/media/thumb-wsf.png | Bin 0 -> 3028 bytes system/images/media/thumb-xls.png | Bin 0 -> 2562 bytes system/images/media/thumb-xlsx.png | Bin 0 -> 3481 bytes system/images/media/thumb-xml.png | Bin 0 -> 2557 bytes system/images/media/thumb-yuv.png | Bin 0 -> 2741 bytes system/images/media/thumb-zip.png | Bin 0 -> 1628 bytes system/images/media/thumb.png | Bin 0 -> 1200 bytes system/images/watermark.png | Bin 0 -> 95789 bytes system/install.php | 15 + system/languages/ar.yaml | 93 + system/languages/bg.yaml | 72 + system/languages/ca.yaml | 87 + system/languages/cs.yaml | 147 + system/languages/da.yaml | 90 + system/languages/de.yaml | 147 + system/languages/el.yaml | 144 + system/languages/en.yaml | 121 + system/languages/eo.yaml | 40 + system/languages/es.yaml | 107 + system/languages/et.yaml | 108 + system/languages/eu.yaml | 62 + system/languages/fa.yaml | 62 + system/languages/fi.yaml | 134 + system/languages/fr.yaml | 147 + system/languages/gl.yaml | 147 + system/languages/he.yaml | 99 + system/languages/hr.yaml | 104 + system/languages/hu.yaml | 97 + system/languages/id.yaml | 147 + system/languages/is.yaml | 80 + system/languages/it.yaml | 147 + system/languages/ja.yaml | 81 + system/languages/ko.yaml | 90 + system/languages/lt.yaml | 78 + system/languages/lv.yaml | 84 + system/languages/mn.yaml | 147 + system/languages/my.yaml | 147 + system/languages/nb.yaml | 4 + system/languages/nl.yaml | 147 + system/languages/no.yaml | 82 + system/languages/pl.yaml | 100 + system/languages/pt.yaml | 147 + system/languages/ro.yaml | 96 + system/languages/ru.yaml | 114 + system/languages/si.yaml | 120 + system/languages/sk.yaml | 144 + system/languages/sl.yaml | 85 + system/languages/sr.yaml | 147 + system/languages/sv.yaml | 100 + system/languages/sw.yaml | 147 + system/languages/th.yaml | 147 + system/languages/tr.yaml | 100 + system/languages/uk.yaml | 63 + system/languages/vi.yaml | 63 + system/languages/zh-cn.yaml | 146 + system/languages/zh-tw.yaml | 79 + system/languages/zh.yaml | 146 + system/pages/notfound.md | 6 + system/router.php | 55 + system/src/DOMLettersIterator.php | 165 + system/src/DOMWordsIterator.php | 158 + system/src/Grav/Common/Assets.php | 595 + system/src/Grav/Common/Assets/BaseAsset.php | 283 + system/src/Grav/Common/Assets/BlockAssets.php | 207 + system/src/Grav/Common/Assets/Css.php | 52 + system/src/Grav/Common/Assets/InlineCss.php | 44 + system/src/Grav/Common/Assets/InlineJs.php | 44 + .../src/Grav/Common/Assets/InlineJsModule.php | 46 + system/src/Grav/Common/Assets/Js.php | 48 + system/src/Grav/Common/Assets/JsModule.php | 49 + system/src/Grav/Common/Assets/Link.php | 43 + system/src/Grav/Common/Assets/Pipeline.php | 347 + .../Common/Assets/Traits/AssetUtilsTrait.php | 215 + .../Assets/Traits/LegacyAssetsTrait.php | 137 + .../Assets/Traits/TestingAssetsTrait.php | 350 + system/src/Grav/Common/Backup/Backups.php | 322 + system/src/Grav/Common/Browser.php | 153 + system/src/Grav/Common/Cache.php | 690 ++ system/src/Grav/Common/Composer.php | 67 + .../src/Grav/Common/Config/CompiledBase.php | 269 + .../Grav/Common/Config/CompiledBlueprints.php | 131 + .../src/Grav/Common/Config/CompiledConfig.php | 114 + .../Grav/Common/Config/CompiledLanguages.php | 83 + system/src/Grav/Common/Config/Config.php | 156 + .../Grav/Common/Config/ConfigFileFinder.php | 273 + system/src/Grav/Common/Config/Languages.php | 107 + system/src/Grav/Common/Config/Setup.php | 423 + system/src/Grav/Common/Data/Blueprint.php | 594 + .../src/Grav/Common/Data/BlueprintSchema.php | 429 + system/src/Grav/Common/Data/Blueprints.php | 121 + system/src/Grav/Common/Data/Data.php | 343 + system/src/Grav/Common/Data/DataInterface.php | 84 + system/src/Grav/Common/Data/Validation.php | 1236 +++ .../Grav/Common/Data/ValidationException.php | 67 + system/src/Grav/Common/Debugger.php | 1148 ++ system/src/Grav/Common/Errors/BareHandler.php | 33 + system/src/Grav/Common/Errors/Errors.php | 85 + .../Grav/Common/Errors/Resources/error.css | 52 + .../Common/Errors/Resources/layout.html.php | 30 + .../Grav/Common/Errors/SimplePageHandler.php | 122 + .../src/Grav/Common/Errors/SystemFacade.php | 67 + system/src/Grav/Common/File/CompiledFile.php | 195 + .../src/Grav/Common/File/CompiledJsonFile.php | 33 + .../Grav/Common/File/CompiledMarkdownFile.php | 21 + .../src/Grav/Common/File/CompiledYamlFile.php | 21 + .../src/Grav/Common/Filesystem/Archiver.php | 108 + system/src/Grav/Common/Filesystem/Folder.php | 548 + .../RecursiveDirectoryFilterIterator.php | 82 + .../RecursiveFolderFilterIterator.php | 55 + .../Grav/Common/Filesystem/ZipArchiver.php | 135 + .../src/Grav/Common/Flex/FlexCollection.php | 28 + system/src/Grav/Common/Flex/FlexIndex.php | 29 + system/src/Grav/Common/Flex/FlexObject.php | 74 + .../Flex/Traits/FlexCollectionTrait.php | 51 + .../Common/Flex/Traits/FlexCommonTrait.php | 54 + .../Grav/Common/Flex/Traits/FlexGravTrait.php | 74 + .../Common/Flex/Traits/FlexIndexTrait.php | 20 + .../Common/Flex/Traits/FlexObjectTrait.php | 62 + .../Flex/Types/Generic/GenericCollection.php | 24 + .../Flex/Types/Generic/GenericIndex.php | 24 + .../Flex/Types/Generic/GenericObject.php | 22 + .../Flex/Types/Pages/PageCollection.php | 839 ++ .../Common/Flex/Types/Pages/PageIndex.php | 1198 ++ .../Common/Flex/Types/Pages/PageObject.php | 744 ++ .../Flex/Types/Pages/Storage/PageStorage.php | 700 ++ .../Types/Pages/Traits/PageContentTrait.php | 75 + .../Types/Pages/Traits/PageLegacyTrait.php | 236 + .../Types/Pages/Traits/PageRoutableTrait.php | 122 + .../Types/Pages/Traits/PageTranslateTrait.php | 108 + .../Types/UserGroups/UserGroupCollection.php | 56 + .../Flex/Types/UserGroups/UserGroupIndex.php | 24 + .../Flex/Types/UserGroups/UserGroupObject.php | 134 + .../Types/Users/Storage/UserFileStorage.php | 47 + .../Types/Users/Storage/UserFolderStorage.php | 37 + .../Users/Traits/UserObjectLegacyTrait.php | 94 + .../Flex/Types/Users/UserCollection.php | 135 + .../Common/Flex/Types/Users/UserIndex.php | 206 + .../Common/Flex/Types/Users/UserObject.php | 1059 ++ system/src/Grav/Common/Form/FormFlash.php | 107 + .../Grav/Common/GPM/AbstractCollection.php | 41 + .../GPM/Common/AbstractPackageCollection.php | 50 + .../Common/GPM/Common/CachedCollection.php | 43 + system/src/Grav/Common/GPM/Common/Package.php | 99 + system/src/Grav/Common/GPM/GPM.php | 1270 +++ system/src/Grav/Common/GPM/Installer.php | 544 + system/src/Grav/Common/GPM/Licenses.php | 116 + .../GPM/Local/AbstractPackageCollection.php | 34 + system/src/Grav/Common/GPM/Local/Package.php | 51 + system/src/Grav/Common/GPM/Local/Packages.php | 29 + system/src/Grav/Common/GPM/Local/Plugins.php | 33 + system/src/Grav/Common/GPM/Local/Themes.php | 33 + .../GPM/Remote/AbstractPackageCollection.php | 81 + .../src/Grav/Common/GPM/Remote/GravCore.php | 151 + system/src/Grav/Common/GPM/Remote/Package.php | 66 + .../src/Grav/Common/GPM/Remote/Packages.php | 34 + system/src/Grav/Common/GPM/Remote/Plugins.php | 32 + system/src/Grav/Common/GPM/Remote/Themes.php | 32 + system/src/Grav/Common/GPM/Response.php | 3 + system/src/Grav/Common/GPM/Upgrader.php | 138 + system/src/Grav/Common/Getters.php | 170 + system/src/Grav/Common/Grav.php | 829 ++ system/src/Grav/Common/GravTrait.php | 34 + system/src/Grav/Common/HTTP/Client.php | 130 + system/src/Grav/Common/HTTP/Response.php | 96 + system/src/Grav/Common/Helpers/Base32.php | 141 + system/src/Grav/Common/Helpers/Excerpts.php | 196 + system/src/Grav/Common/Helpers/Exif.php | 48 + system/src/Grav/Common/Helpers/LogViewer.php | 167 + system/src/Grav/Common/Helpers/Truncator.php | 344 + system/src/Grav/Common/Helpers/YamlLinter.php | 122 + system/src/Grav/Common/Inflector.php | 363 + system/src/Grav/Common/Iterator.php | 264 + system/src/Grav/Common/Language/Language.php | 663 ++ .../Grav/Common/Language/LanguageCodes.php | 246 + system/src/Grav/Common/Markdown/Parsedown.php | 43 + .../Grav/Common/Markdown/ParsedownExtra.php | 46 + .../Common/Markdown/ParsedownGravTrait.php | 319 + .../Media/Interfaces/AudioMediaInterface.php | 25 + .../Interfaces/ImageManipulateInterface.php | 120 + .../Media/Interfaces/ImageMediaInterface.php | 17 + .../Interfaces/MediaCollectionInterface.php | 115 + .../Media/Interfaces/MediaFileInterface.php | 53 + .../Media/Interfaces/MediaInterface.php | 17 + .../Media/Interfaces/MediaLinkInterface.php | 17 + .../Media/Interfaces/MediaObjectInterface.php | 227 + .../Media/Interfaces/MediaPlayerInterface.php | 56 + .../Media/Interfaces/MediaUploadInterface.php | 73 + .../Media/Interfaces/VideoMediaInterface.php | 32 + .../Common/Media/Traits/AudioMediaTrait.php | 53 + .../Media/Traits/ImageDecodingTrait.php | 40 + .../Media/Traits/ImageFetchPriorityTrait.php | 40 + .../Common/Media/Traits/ImageLoadingTrait.php | 37 + .../Common/Media/Traits/ImageMediaTrait.php | 428 + .../Common/Media/Traits/MediaFileTrait.php | 139 + .../Common/Media/Traits/MediaObjectTrait.php | 630 ++ .../Common/Media/Traits/MediaPlayerTrait.php | 113 + .../Grav/Common/Media/Traits/MediaTrait.php | 153 + .../Common/Media/Traits/MediaUploadTrait.php | 680 ++ .../Common/Media/Traits/StaticResizeTrait.php | 40 + .../Media/Traits/ThumbnailMediaTrait.php | 149 + .../Common/Media/Traits/VideoMediaTrait.php | 68 + system/src/Grav/Common/Page/Collection.php | 710 ++ system/src/Grav/Common/Page/Header.php | 38 + .../Interfaces/PageCollectionInterface.php | 310 + .../Page/Interfaces/PageContentInterface.php | 267 + .../Page/Interfaces/PageFormInterface.php | 33 + .../Common/Page/Interfaces/PageInterface.php | 25 + .../Page/Interfaces/PageLegacyInterface.php | 475 + .../Page/Interfaces/PageRoutableInterface.php | 180 + .../Interfaces/PageTranslateInterface.php | 38 + .../Page/Interfaces/PagesSourceInterface.php | 56 + .../Grav/Common/Page/Markdown/Excerpts.php | 343 + system/src/Grav/Common/Page/Media.php | 286 + .../Grav/Common/Page/Medium/AbstractMedia.php | 344 + .../Grav/Common/Page/Medium/AudioMedium.php | 36 + .../Grav/Common/Page/Medium/GlobalMedia.php | 150 + .../src/Grav/Common/Page/Medium/ImageFile.php | 212 + .../Grav/Common/Page/Medium/ImageMedium.php | 499 + system/src/Grav/Common/Page/Medium/Link.php | 102 + system/src/Grav/Common/Page/Medium/Medium.php | 140 + .../Grav/Common/Page/Medium/MediumFactory.php | 220 + .../Common/Page/Medium/ParsedownHtmlTrait.php | 44 + .../Page/Medium/RenderableInterface.php | 41 + .../Common/Page/Medium/StaticImageMedium.php | 48 + .../Common/Page/Medium/StaticResizeTrait.php | 24 + .../Page/Medium/ThumbnailImageMedium.php | 21 + .../Common/Page/Medium/VectorImageMedium.php | 68 + .../Grav/Common/Page/Medium/VideoMedium.php | 36 + system/src/Grav/Common/Page/Page.php | 2935 +++++ system/src/Grav/Common/Page/Pages.php | 2258 ++++ .../Grav/Common/Page/Traits/PageFormTrait.php | 126 + system/src/Grav/Common/Page/Types.php | 179 + system/src/Grav/Common/Plugin.php | 472 + system/src/Grav/Common/Plugins.php | 330 + .../Common/Processors/AssetsProcessor.php | 41 + .../Common/Processors/BackupsProcessor.php | 41 + .../Processors/DebuggerAssetsProcessor.php | 40 + .../Processors/Events/RequestHandlerEvent.php | 82 + .../Common/Processors/InitializeProcessor.php | 461 + .../Grav/Common/Processors/PagesProcessor.php | 115 + .../Common/Processors/PluginsProcessor.php | 41 + .../Grav/Common/Processors/ProcessorBase.php | 70 + .../Common/Processors/ProcessorInterface.php | 20 + .../Common/Processors/RenderProcessor.php | 71 + .../Common/Processors/RequestProcessor.php | 66 + .../Common/Processors/SchedulerProcessor.php | 42 + .../Grav/Common/Processors/TasksProcessor.php | 71 + .../Common/Processors/ThemesProcessor.php | 40 + .../Grav/Common/Processors/TwigProcessor.php | 40 + system/src/Grav/Common/Scheduler/Cron.php | 577 + .../Grav/Common/Scheduler/IntervalTrait.php | 404 + system/src/Grav/Common/Scheduler/Job.php | 566 + .../src/Grav/Common/Scheduler/Scheduler.php | 447 + system/src/Grav/Common/Security.php | 287 + .../Service/AccountsServiceProvider.php | 157 + .../Common/Service/AssetsServiceProvider.php | 32 + .../Common/Service/BackupsServiceProvider.php | 35 + .../Common/Service/ConfigServiceProvider.php | 206 + .../Common/Service/ErrorServiceProvider.php | 30 + .../Service/FilesystemServiceProvider.php | 32 + .../Common/Service/FlexServiceProvider.php | 121 + .../Service/InflectorServiceProvider.php | 32 + .../Common/Service/LoggerServiceProvider.php | 42 + .../Common/Service/OutputServiceProvider.php | 39 + .../Common/Service/PagesServiceProvider.php | 140 + .../Common/Service/RequestServiceProvider.php | 103 + .../Service/SchedulerServiceProvider.php | 32 + .../Common/Service/SessionServiceProvider.php | 134 + .../Common/Service/StreamsServiceProvider.php | 56 + .../Common/Service/TaskServiceProvider.php | 55 + system/src/Grav/Common/Session.php | 202 + system/src/Grav/Common/Taxonomy.php | 181 + system/src/Grav/Common/Theme.php | 87 + system/src/Grav/Common/Themes.php | 417 + .../Common/Twig/Exception/TwigException.php | 21 + .../Twig/Extension/FilesystemExtension.php | 387 + .../Common/Twig/Extension/GravExtension.php | 1756 +++ .../Grav/Common/Twig/Node/TwigNodeCache.php | 93 + .../Grav/Common/Twig/Node/TwigNodeLink.php | 114 + .../Common/Twig/Node/TwigNodeMarkdown.php | 52 + .../Grav/Common/Twig/Node/TwigNodeRender.php | 84 + .../Grav/Common/Twig/Node/TwigNodeScript.php | 142 + .../Grav/Common/Twig/Node/TwigNodeStyle.php | 133 + .../Grav/Common/Twig/Node/TwigNodeSwitch.php | 88 + .../Grav/Common/Twig/Node/TwigNodeThrow.php | 52 + .../Common/Twig/Node/TwigNodeTryCatch.php | 67 + .../Twig/TokenParser/TwigTokenParserCache.php | 74 + .../Twig/TokenParser/TwigTokenParserLink.php | 109 + .../TokenParser/TwigTokenParserMarkdown.php | 59 + .../TokenParser/TwigTokenParserRender.php | 74 + .../TokenParser/TwigTokenParserScript.php | 132 + .../Twig/TokenParser/TwigTokenParserStyle.php | 119 + .../TokenParser/TwigTokenParserSwitch.php | 132 + .../Twig/TokenParser/TwigTokenParserThrow.php | 55 + .../TokenParser/TwigTokenParserTryCatch.php | 81 + system/src/Grav/Common/Twig/Twig.php | 578 + .../Common/Twig/TwigClockworkDataSource.php | 58 + .../Grav/Common/Twig/TwigClockworkDumper.php | 72 + .../src/Grav/Common/Twig/TwigEnvironment.php | 60 + system/src/Grav/Common/Twig/TwigExtension.php | 21 + .../Grav/Common/Twig/WriteCacheFileTrait.php | 56 + system/src/Grav/Common/Uri.php | 1527 +++ system/src/Grav/Common/User/Access.php | 52 + .../src/Grav/Common/User/Authentication.php | 61 + system/src/Grav/Common/User/DataUser/User.php | 329 + .../Common/User/DataUser/UserCollection.php | 163 + system/src/Grav/Common/User/Group.php | 172 + .../User/Interfaces/AuthorizeInterface.php | 26 + .../Interfaces/UserCollectionInterface.php | 40 + .../User/Interfaces/UserGroupInterface.php | 18 + .../Common/User/Interfaces/UserInterface.php | 189 + .../src/Grav/Common/User/Traits/UserTrait.php | 233 + system/src/Grav/Common/User/User.php | 144 + system/src/Grav/Common/Utils.php | 2227 ++++ system/src/Grav/Common/Yaml.php | 65 + .../Grav/Console/Application/Application.php | 138 + .../CommandLoader/PluginCommandLoader.php | 103 + .../Console/Application/GpmApplication.php | 42 + .../Console/Application/GravApplication.php | 52 + .../Console/Application/PluginApplication.php | 116 + system/src/Grav/Console/Cli/BackupCommand.php | 138 + system/src/Grav/Console/Cli/CleanCommand.php | 411 + .../Grav/Console/Cli/ClearCacheCommand.php | 104 + .../src/Grav/Console/Cli/ComposerCommand.php | 64 + .../src/Grav/Console/Cli/InstallCommand.php | 302 + .../src/Grav/Console/Cli/LogViewerCommand.php | 96 + .../Grav/Console/Cli/NewProjectCommand.php | 75 + .../Cli/PageSystemValidatorCommand.php | 299 + .../src/Grav/Console/Cli/SandboxCommand.php | 347 + .../src/Grav/Console/Cli/SchedulerCommand.php | 223 + .../src/Grav/Console/Cli/SecurityCommand.php | 102 + system/src/Grav/Console/Cli/ServerCommand.php | 154 + .../Grav/Console/Cli/YamlLinterCommand.php | 124 + system/src/Grav/Console/ConsoleCommand.php | 46 + system/src/Grav/Console/ConsoleTrait.php | 338 + .../Grav/Console/Gpm/DirectInstallCommand.php | 321 + system/src/Grav/Console/Gpm/IndexCommand.php | 335 + system/src/Grav/Console/Gpm/InfoCommand.php | 191 + .../src/Grav/Console/Gpm/InstallCommand.php | 726 ++ .../Grav/Console/Gpm/SelfupgradeCommand.php | 344 + .../src/Grav/Console/Gpm/UninstallCommand.php | 312 + system/src/Grav/Console/Gpm/UpdateCommand.php | 289 + .../src/Grav/Console/Gpm/VersionCommand.php | 125 + system/src/Grav/Console/GpmCommand.php | 68 + system/src/Grav/Console/GravCommand.php | 52 + .../Grav/Console/Plugin/PluginListCommand.php | 69 + .../Grav/Console/TerminalObjects/Table.php | 38 + .../Grav/Events/BeforeSessionStartEvent.php | 36 + system/src/Grav/Events/FlexRegisterEvent.php | 45 + system/src/Grav/Events/PageEvent.php | 18 + .../Grav/Events/PermissionsRegisterEvent.php | 45 + system/src/Grav/Events/PluginsLoadedEvent.php | 53 + system/src/Grav/Events/SessionStartEvent.php | 36 + system/src/Grav/Events/TypesEvent.php | 18 + system/src/Grav/Framework/Acl/Access.php | 231 + system/src/Grav/Framework/Acl/Action.php | 204 + system/src/Grav/Framework/Acl/Permissions.php | 249 + .../Grav/Framework/Acl/PermissionsReader.php | 186 + .../Framework/Acl/RecursiveActionIterator.php | 64 + .../Grav/Framework/Cache/AbstractCache.php | 32 + .../Framework/Cache/Adapter/ChainCache.php | 210 + .../Framework/Cache/Adapter/DoctrineCache.php | 118 + .../Framework/Cache/Adapter/FileCache.php | 266 + .../Framework/Cache/Adapter/MemoryCache.php | 83 + .../Framework/Cache/Adapter/SessionCache.php | 107 + .../Grav/Framework/Cache/CacheInterface.php | 71 + .../src/Grav/Framework/Cache/CacheTrait.php | 373 + .../Cache/Exception/CacheException.php | 21 + .../Exception/InvalidArgumentException.php | 20 + .../Collection/AbstractFileCollection.php | 238 + .../Collection/AbstractIndexCollection.php | 574 + .../Collection/AbstractLazyCollection.php | 97 + .../Framework/Collection/ArrayCollection.php | 117 + .../Collection/CollectionInterface.php | 69 + .../Framework/Collection/FileCollection.php | 97 + .../Collection/FileCollectionInterface.php | 33 + .../Grav/Framework/Compat/Serializable.php | 47 + .../Framework/ContentBlock/ContentBlock.php | 303 + .../ContentBlock/ContentBlockInterface.php | 90 + .../Grav/Framework/ContentBlock/HtmlBlock.php | 502 + .../ContentBlock/HtmlBlockInterface.php | 130 + .../Contracts/Media/MediaObjectInterface.php | 52 + .../Contracts/Object/IdentifierInterface.php | 27 + .../RelationshipIdentifierInterface.php | 28 + .../Relationships/RelationshipInterface.php | 81 + .../Relationships/RelationshipsInterface.php | 53 + .../ToManyRelationshipInterface.php | 55 + .../ToOneRelationshipInterface.php | 37 + .../Traits/ControllerResponseTrait.php | 307 + system/src/Grav/Framework/DI/Container.php | 35 + .../src/Grav/Framework/File/AbstractFile.php | 444 + system/src/Grav/Framework/File/CsvFile.php | 40 + system/src/Grav/Framework/File/DataFile.php | 78 + system/src/Grav/Framework/File/File.php | 35 + .../File/Formatter/AbstractFormatter.php | 117 + .../Framework/File/Formatter/CsvFormatter.php | 170 + .../File/Formatter/FormatterInterface.php | 12 + .../Framework/File/Formatter/IniFormatter.php | 68 + .../File/Formatter/JsonFormatter.php | 170 + .../File/Formatter/MarkdownFormatter.php | 161 + .../File/Formatter/SerializeFormatter.php | 98 + .../File/Formatter/YamlFormatter.php | 129 + system/src/Grav/Framework/File/IniFile.php | 40 + .../Interfaces/FileFormatterInterface.php | 72 + .../File/Interfaces/FileInterface.php | 180 + system/src/Grav/Framework/File/JsonFile.php | 31 + .../src/Grav/Framework/File/MarkdownFile.php | 40 + system/src/Grav/Framework/File/YamlFile.php | 40 + .../Grav/Framework/Filesystem/Filesystem.php | 356 + .../Interfaces/FilesystemInterface.php | 84 + system/src/Grav/Framework/Flex/Flex.php | 334 + .../Grav/Framework/Flex/FlexCollection.php | 733 ++ .../src/Grav/Framework/Flex/FlexDirectory.php | 1187 ++ .../Grav/Framework/Flex/FlexDirectoryForm.php | 509 + system/src/Grav/Framework/Flex/FlexForm.php | 610 + .../src/Grav/Framework/Flex/FlexFormFlash.php | 130 + .../Grav/Framework/Flex/FlexIdentifier.php | 75 + system/src/Grav/Framework/Flex/FlexIndex.php | 930 ++ system/src/Grav/Framework/Flex/FlexObject.php | 1288 +++ .../Interfaces/FlexAuthorizeInterface.php | 33 + .../Interfaces/FlexCollectionInterface.php | 144 + .../Flex/Interfaces/FlexCommonInterface.php | 79 + .../Interfaces/FlexDirectoryFormInterface.php | 27 + .../Interfaces/FlexDirectoryInterface.php | 228 + .../Flex/Interfaces/FlexFormInterface.php | 51 + .../Flex/Interfaces/FlexIndexInterface.php | 64 + .../Flex/Interfaces/FlexInterface.php | 100 + .../Interfaces/FlexObjectFormInterface.php | 27 + .../Flex/Interfaces/FlexObjectInterface.php | 211 + .../Flex/Interfaces/FlexStorageInterface.php | 138 + .../Interfaces/FlexTranslateInterface.php | 51 + .../Flex/Pages/FlexPageCollection.php | 211 + .../Framework/Flex/Pages/FlexPageIndex.php | 48 + .../Framework/Flex/Pages/FlexPageObject.php | 496 + .../Flex/Pages/Traits/PageAuthorsTrait.php | 249 + .../Flex/Pages/Traits/PageContentTrait.php | 842 ++ .../Flex/Pages/Traits/PageLegacyTrait.php | 1124 ++ .../Flex/Pages/Traits/PageRoutableTrait.php | 550 + .../Flex/Pages/Traits/PageTranslateTrait.php | 291 + .../Storage/AbstractFilesystemStorage.php | 232 + .../Framework/Flex/Storage/FileStorage.php | 160 + .../Framework/Flex/Storage/FolderStorage.php | 708 ++ .../Framework/Flex/Storage/SimpleStorage.php | 507 + .../Flex/Traits/FlexAuthorizeTrait.php | 126 + .../Framework/Flex/Traits/FlexMediaTrait.php | 576 + .../Flex/Traits/FlexRelatedDirectoryTrait.php | 59 + .../Flex/Traits/FlexRelationshipsTrait.php | 61 + system/src/Grav/Framework/Form/FormFlash.php | 586 + .../src/Grav/Framework/Form/FormFlashFile.php | 266 + .../Form/Interfaces/FormFactoryInterface.php | 42 + .../Form/Interfaces/FormFlashInterface.php | 181 + .../Form/Interfaces/FormInterface.php | 187 + .../Grav/Framework/Form/Traits/FormTrait.php | 897 ++ .../Framework/Interfaces/RenderInterface.php | 38 + .../Logger/Processors/UserProcessor.php | 34 + .../Interfaces/MediaCollectionInterface.php | 23 + .../Media/Interfaces/MediaInterface.php | 37 + .../Interfaces/MediaManipulationInterface.php | 33 + .../Media/Interfaces/MediaObjectInterface.php | 47 + .../Grav/Framework/Media/MediaIdentifier.php | 150 + .../src/Grav/Framework/Media/MediaObject.php | 215 + .../Framework/Media/UploadedMediaObject.php | 172 + system/src/Grav/Framework/Mime/MimeTypes.php | 107 + .../Object/Access/ArrayAccessTrait.php | 66 + .../Object/Access/NestedArrayAccessTrait.php | 66 + .../Access/NestedPropertyCollectionTrait.php | 120 + .../Object/Access/NestedPropertyTrait.php | 180 + .../Object/Access/OverloadedPropertyTrait.php | 66 + .../src/Grav/Framework/Object/ArrayObject.php | 31 + .../Object/Base/ObjectCollectionTrait.php | 377 + .../Framework/Object/Base/ObjectTrait.php | 202 + .../Collection/ObjectExpressionVisitor.php | 240 + .../Object/Identifiers/Identifier.php | 66 + .../NestedObjectCollectionInterface.php | 64 + .../Interfaces/NestedObjectInterface.php | 60 + .../Interfaces/ObjectCollectionInterface.php | 126 + .../Object/Interfaces/ObjectInterface.php | 63 + .../src/Grav/Framework/Object/LazyObject.php | 34 + .../Framework/Object/ObjectCollection.php | 131 + .../src/Grav/Framework/Object/ObjectIndex.php | 281 + .../Object/Property/ArrayPropertyTrait.php | 115 + .../Object/Property/LazyPropertyTrait.php | 114 + .../Object/Property/MixedPropertyTrait.php | 121 + .../Object/Property/ObjectPropertyTrait.php | 213 + .../Grav/Framework/Object/PropertyObject.php | 32 + .../Pagination/AbstractPagination.php | 429 + .../Pagination/AbstractPaginationPage.php | 78 + .../Interfaces/PaginationInterface.php | 104 + .../Interfaces/PaginationPageInterface.php | 47 + .../Grav/Framework/Pagination/Pagination.php | 32 + .../Framework/Pagination/PaginationPage.php | 26 + .../src/Grav/Framework/Psr7/AbstractUri.php | 412 + system/src/Grav/Framework/Psr7/Request.php | 34 + system/src/Grav/Framework/Psr7/Response.php | 265 + .../src/Grav/Framework/Psr7/ServerRequest.php | 364 + system/src/Grav/Framework/Psr7/Stream.php | 43 + .../Psr7/Traits/MessageDecoratorTrait.php | 140 + .../Psr7/Traits/RequestDecoratorTrait.php | 112 + .../Psr7/Traits/ResponseDecoratorTrait.php | 82 + .../Traits/ServerRequestDecoratorTrait.php | 176 + .../Psr7/Traits/StreamDecoratorTrait.php | 153 + .../Traits/UploadedFileDecoratorTrait.php | 73 + .../Psr7/Traits/UriDecorationTrait.php | 188 + .../src/Grav/Framework/Psr7/UploadedFile.php | 70 + system/src/Grav/Framework/Psr7/Uri.php | 135 + .../Framework/Relationships/Relationships.php | 217 + .../Relationships/ToManyRelationship.php | 259 + .../Relationships/ToOneRelationship.php | 207 + .../Traits/RelationshipTrait.php | 128 + .../Exception/InvalidArgumentException.php | 49 + .../Exception/NotFoundException.php | 37 + .../Exception/NotHandledException.php | 20 + .../Exception/PageExpiredException.php | 32 + .../Exception/RequestException.php | 102 + .../RequestHandler/Middlewares/Exceptions.php | 78 + .../Middlewares/MultipartRequestSupport.php | 123 + .../RequestHandler/RequestHandler.php | 80 + .../Traits/RequestHandlerTrait.php | 64 + system/src/Grav/Framework/Route/Route.php | 452 + .../src/Grav/Framework/Route/RouteFactory.php | 236 + .../Session/Exceptions/SessionException.php | 20 + .../src/Grav/Framework/Session/Messages.php | 134 + system/src/Grav/Framework/Session/Session.php | 562 + .../Framework/Session/SessionInterface.php | 159 + system/src/Grav/Framework/Uri/Uri.php | 216 + system/src/Grav/Framework/Uri/UriFactory.php | 171 + .../src/Grav/Framework/Uri/UriPartsFilter.php | 145 + system/src/Grav/Installer/Install.php | 400 + .../src/Grav/Installer/InstallException.php | 29 + system/src/Grav/Installer/VersionUpdate.php | 83 + system/src/Grav/Installer/VersionUpdater.php | 133 + system/src/Grav/Installer/Versions.php | 329 + system/src/Grav/Installer/YamlUpdater.php | 431 + .../Installer/updates/1.7.0_2020-11-20_1.php | 24 + .../DeferredExtension/DeferredBlockNode.php | 43 + .../DeferredExtension/DeferredDeclareNode.php | 27 + .../DeferredExtension/DeferredExtension.php | 72 + .../DeferredInitializeNode.php | 27 + .../Twig/DeferredExtension/DeferredNode.php | 27 + .../DeferredExtension/DeferredNodeVisitor.php | 50 + .../DeferredNodeVisitorCompat.php | 67 + .../DeferredExtension/DeferredResolveNode.php | 27 + .../DeferredExtension/DeferredTokenParser.php | 77 + system/templates/default.html.twig | 4 + system/templates/external.html.twig | 1 + system/templates/flex/404.html.twig | 4 + .../flex/_default/collection/debug.html.twig | 5 + .../flex/_default/object/debug.html.twig | 4 + system/templates/modular/default.html.twig | 4 + system/templates/partials/messages.html.twig | 14 + system/templates/partials/metadata.html.twig | 3 + tests/_bootstrap.php | 35 + tests/_support/AcceptanceTester.php | 26 + tests/_support/FunctionalTester.php | 26 + tests/_support/Helper/Acceptance.php | 10 + tests/_support/Helper/Functional.php | 10 + tests/_support/Helper/Unit.php | 80 + tests/_support/UnitTester.php | 26 + tests/acceptance.suite.yml | 12 + tests/acceptance/_bootstrap.php | 2 + .../01.item1-1/01.item1-1-1/default.md | 10 + .../01.item1-1/02.item1-1-2/default.md | 10 + .../01.item1-1/03.item1-1-3/default.md | 10 + .../user/pages/01.item1/01.item1-1/default.md | 10 + .../02.item1-2/01.item1-2-1/default.md | 10 + .../02.item1-2/02.item1-2-2/default.md | 10 + .../02.item1-2/03.item1-2-3/default.md | 10 + .../user/pages/01.item1/02.item1-2/default.md | 10 + .../03.item1-3/01.item1-3-1/default.md | 10 + .../03.item1-3/02.item1-3-2/default.md | 10 + .../03.item1-3/03.item1-3-3/default.md | 10 + .../user/pages/01.item1/03.item1-3/default.md | 10 + .../user/pages/01.item1/default.md | 10 + .../user/pages/01.item1/existing-file.zip | Bin 0 -> 451 bytes .../user/pages/01.item1/home-cache-image.jpg | Bin 0 -> 156699 bytes .../user/pages/01.item1/home-sample-image.jpg | Bin 0 -> 156699 bytes .../01.item2-1/01.item2-1-1/default.md | 10 + .../01.item2-1/02.item2-1-2/default.md | 10 + .../01.item2-1/03.item2-1-3/default.md | 10 + .../user/pages/02.item2/01.item2-1/default.md | 10 + .../02.item2-2/01.item2-2-1/default.md | 10 + .../02.item2-2/02.item2-2-2/default.md | 10 + .../02.item2-2/03.item2-2-3/default.md | 10 + .../pages/02.item2/02.item2-2/cache-image.jpg | Bin 0 -> 156699 bytes .../user/pages/02.item2/02.item2-2/default.md | 10 + .../02.item2/02.item2-2/existing-file.zip | Bin 0 -> 451 bytes .../02.item2/02.item2-2/sample-image.jpg | Bin 0 -> 156699 bytes .../03.item2-3/01.item2-3-1/default.md | 10 + .../03.item2-3/02.item2-3-2/default.md | 10 + .../03.item2-3/03.item2-3-3/default.md | 10 + .../user/pages/02.item2/03.item2-3/default.md | 10 + .../user/pages/02.item2/default.md | 10 + .../01.item3-1/01.item3-1-1/default.md | 14 + .../01.item3-1/02.item3-1-2/default.md | 10 + .../01.item3-1/03.item3-1-3/default.md | 10 + .../user/pages/03.item3/01.item3-1/default.md | 10 + .../02.item3-2/01.item3-2-1/default.md | 10 + .../02.item3-2/02.item3-2-2/default.md | 10 + .../02.item3-2/03.item3-2-3/default.md | 10 + .../user/pages/03.item3/02.item3-2/default.md | 10 + .../03.item3-3/01.item3-3-1/default.md | 10 + .../03.item3-3/02.item3-3-2/default.md | 10 + .../03.item3-3/03.item3-3-3/default.md | 10 + .../user/pages/03.item3/03.item3-3/default.md | 10 + .../user/pages/03.item3/default.md | 10 + .../simple-site/user/pages/01.home/default.md | 10 + .../simple-site/user/pages/02.blog/blog.md | 10 + .../user/pages/02.blog/post-one/item.md | 10 + .../user/pages/02.blog/post-two/item.md | 10 + .../user/pages/03.about/default.md | 10 + .../single-pages/01.simple-page/default.md | 5 + tests/functional.suite.yml | 11 + .../Grav/Console/DirectInstallCommandTest.php | 40 + tests/functional/_bootstrap.php | 2 + tests/unit.suite.yml | 9 + tests/unit/Grav/Common/AssetsTest.php | 598 + tests/unit/Grav/Common/BrowserTest.php | 48 + tests/unit/Grav/Common/ComposerTest.php | 32 + tests/unit/Grav/Common/GPM/GPMTest.php | 323 + .../unit/Grav/Common/Helpers/ExcerptsTest.php | 85 + tests/unit/Grav/Common/InflectorTest.php | 147 + .../Common/Language/LanguageCodesTest.php | 24 + .../Grav/Common/Markdown/ParsedownTest.php | 744 ++ tests/unit/Grav/Common/Page/PagesTest.php | 281 + .../Grav/Common/Twig/TwigExtensionTest.php | 208 + tests/unit/Grav/Common/UriTest.php | 1135 ++ tests/unit/Grav/Common/UtilsTest.php | 333 + .../Grav/Console/Gpm/InstallCommandTest.php | 28 + tests/unit/_bootstrap.php | 4 + tmp/.gitkeep | 0 .../index.yaml | 121 + user/accounts/.gitkeep | 0 user/config/media.yaml | 0 user/config/plugins/youtube.yaml | 19 + user/config/site.yaml | 19 + user/config/streams.yaml | 0 user/config/system.yaml | 154 + user/config/versions.yaml | 6 + user/data/.gitkeep | 0 user/pages/01.home/RectoHD.jpg | Bin 0 -> 2057877 bytes .../_pourquoi-le-style-de-lours/text.md | 9 + user/pages/01.home/modular.md | 21 + user/pages/02.correction/blog.md | 42 + .../blog.md | 17 + .../items.md | 8 + .../02.chef-de-projet-print/items.md | 7 + .../03.etape-1/etape1.png | Bin 0 -> 56136 bytes .../03.etape-1/item-etapes.md | 18 + .../04.etape-2/etape2.png | Bin 0 -> 57341 bytes .../04.etape-2/item-etapes.md | 15 + .../05.etape-3/etape3.png | Bin 0 -> 67197 bytes .../05.etape-3/item-etapes.md | 9 + .../06.etape-4/etape4.png | Bin 0 -> 94396 bytes .../06.etape-4/item-etapes.md | 11 + .../07.fiabilite/blog.md | 10 + user/pages/04.nouvelle-section-1/blog.md | 15 + .../01.kakemonos/Kakemonos_Solifap.jpg | Bin 0 -> 167051 bytes .../01.sous-section-2-1/01.kakemonos/item.md | 18 + .../item.md | 7 + .../montage_depliants_SC.jpg | Bin 0 -> 604181 bytes .../Affiche_APF_DEF.jpg | Bin 0 -> 1468596 bytes .../item.md | 7 + .../Affiche_danceline.jpg | Bin 0 -> 197091 bytes .../item.md | 7 + .../Affiche_AFS.jpg | Bin 0 -> 249177 bytes .../item.md | 7 + .../Plaquette CRP 2021_C3.jpg | Bin 0 -> 176225 bytes .../item.md | 7 + ...RelationITMetier_Atlassian_Valiantys-1.jpg | Bin 0 -> 332887 bytes .../item.md | 7 + .../IMG_2368_CTN.jpg | Bin 0 -> 126252 bytes .../item.md | 7 + .../Wild_Bed_Presentation.jpg | Bin 0 -> 86526 bytes .../item.md | 7 + .../UAE_enveloppe_2019.jpg | Bin 0 -> 35263 bytes .../item.md | 8 + .../RAAction_Enfance.jpg | Bin 0 -> 140472 bytes .../item.md | 7 + .../Expo_jamboree_site.jpg | Bin 0 -> 1143301 bytes .../item.md | 7 + .../flyerA5_FEDEEH.jpg | Bin 0 -> 178131 bytes .../13.flyer-de-presentation-a5/item.md | 7 + .../Wild_Bed_Presentation.jpg | Bin 0 -> 86526 bytes .../14.identite-visuelle-wild-bed/item.md | 7 + .../HD_PARTAGE1_V3-1.jpg | Bin 0 -> 822845 bytes .../item.md | 7 + .../16.kakemono-80-x-200-cm/item.md | 7 + .../kakemono_FEDEEH.jpg | Bin 0 -> 352300 bytes .../Kakemono_Poissy.jpg | Bin 0 -> 143708 bytes .../17.kakemono-800-x-2000-mm/item.md | 7 + .../SOPRA_STERIA_Cahier_couv_siteLSO.jpg | Bin 0 -> 119232 bytes .../18.livre-88-pages/item.md | 7 + .../couv_Cactusdelame.jpg | Bin 0 -> 73071 bytes .../item.md | 7 + .../HD_CouvertureOK_LIVRE DELFOUR.jpg | Bin 0 -> 288845 bytes .../item.md | 7 + .../COUV_Livre_BARDET_V4.jpg | Bin 0 -> 223435 bytes .../item.md | 7 + .../Oracle_Alliancy.jpg | Bin 0 -> 216657 bytes .../item.md | 6 + .../Livret_Colibri_PDF.jpg | Bin 0 -> 178973 bytes .../item.md | 7 + .../Livret_Jeune_siteLSO.jpg | Bin 0 -> 360889 bytes .../item.md | 7 + .../VQ_AJT_AFP_siteLSO.jpg | Bin 0 -> 101461 bytes .../item.md | 7 + .../Affiche_APF_DEF.jpg | Bin 0 -> 1468596 bytes .../item.md | 7 + .../HD_Livret_Benedictines_V8.jpg | Bin 0 -> 273925 bytes .../item.md | 7 + .../Plaquette Massillon v5BD-1.jpg | Bin 0 -> 652284 bytes .../item.md | 7 + .../Plaquette_camping_WildBed.jpg | Bin 0 -> 189143 bytes .../item.md | 7 + .../Plaquette_CRP_siteLSO.jpg | Bin 0 -> 159190 bytes .../item.md | 7 + .../LivretA5_ouvgroupe_EXE_HD3-1.jpg | Bin 0 -> 315287 bytes .../31.livret-pedagogique-32-pages-a5/item.md | 7 + .../affiche_AFS_cartedumonde_v13.jpg | Bin 0 -> 1780787 bytes .../32.affiche-60-x-80-cm/item.md | 7 + .../Secours_catholique.jpg | Bin 0 -> 202099 bytes .../item.md | 7 + .../RA SC Paris 2017_V6-1.jpg | Bin 0 -> 822804 bytes .../34.rapport-dactivite-52-pages-a4/item.md | 7 + .../SIGNAL_HD-1.jpg | Bin 0 -> 351370 bytes .../item.md | 7 + .../RA_Solifap2018.jpg | Bin 0 -> 412053 bytes .../36.rapports-dactivite-60-pages-a4/item.md | 7 + .../depliant-v12_IMP_HD-1.jpg | Bin 0 -> 258742 bytes .../item.md | 7 + .../RA_Colibri_siteLSO.jpg | Bin 0 -> 95940 bytes .../item.md | 7 + .../COUV_RA_CSUD_siteLSO.jpg | Bin 0 -> 204896 bytes .../item.md | 7 + .../Rapport_ASE_LEPPI_V3_TBD.jpg | Bin 0 -> 194565 bytes .../item.md | 7 + .../Plan_strategique_SOLIFAP.jpg | Bin 0 -> 339561 bytes .../41.plan-strategique-20-pages-a4/item.md | 7 + .../01.sous-section-2-1/blog.md | 15 + .../LivretA5_ouvgroupe_EXE_HD3-1.jpg | Bin 0 -> 315287 bytes .../01.sous-section-2-1/projet-n-2/items.md | 9 + .../affiche_AFS_cartedumonde_v13.jpg | Bin 0 -> 1780787 bytes .../01.sous-section-2-1/projet-n-3/item.md | 7 + .../02.aude-cliente-sociologue/item.md | 7 + .../linkedin-red.svg | 1 + .../item.md | 7 + .../linkedin-red.svg | 1 + .../04.catherine-graphiste/item.md | 7 + .../04.catherine-graphiste/linkedin-red.svg | 1 + .../05.eric-photographe/item.md | 7 + .../05.eric-photographe/linkedin-red.svg | 1 + .../06.francoise-cliente-particuliere/item.md | 7 + .../oral-red.svg | 1 + .../07.isabelle-graphiste/item.md | 7 + .../07.isabelle-graphiste/linkedin-red.svg | 1 + .../item.md | 7 + .../oral-red.svg | 1 + .../09.jean-luc-imprimeur/item.md | 7 + .../09.jean-luc-imprimeur/linkedin-red.svg | 1 + .../10.lionel-imprimeur/item.md | 7 + .../10.lionel-imprimeur/linkedin-red.svg | 1 + .../11.ludovic-client/item.md | 7 + .../11.ludovic-client/malt-red.svg | 1 + .../12.antoine-client/item.md | 7 + .../12.antoine-client/malt-red.svg | 1 + .../item.md | 7 + .../linkedin-red.svg | 1 + .../item.md | 7 + .../linkedin-red.svg | 1 + .../item.md | 7 + .../linkedin-red.svg | 1 + .../16.virginie-cliente-biographe/item.md | 7 + .../linkedin-red.svg | 1 + .../item.md | 7 + .../linkedin-red.svg | 1 + .../02.recommandations/blog.md | 15 + .../03.clients/Alliancy.jpg | Bin 0 -> 54172 bytes .../03.clients/Colas.jpg | Bin 0 -> 71408 bytes .../05.nouvelle-section-2/03.clients/Csud.jpg | Bin 0 -> 54590 bytes .../03.clients/Danceline_2.jpg | Bin 0 -> 117872 bytes .../03.clients/Diocese_du_Mans.jpg | Bin 0 -> 90172 bytes .../05.nouvelle-section-2/03.clients/EetD.jpg | Bin 0 -> 106592 bytes .../05.nouvelle-section-2/03.clients/FSEF.jpg | Bin 0 -> 75275 bytes .../03.clients/Forus_OK.jpg | Bin 0 -> 51969 bytes .../03.clients/FroidNews_2.jpg | Bin 0 -> 57671 bytes .../03.clients/Kaolin.jpg | Bin 0 -> 56847 bytes .../03.clients/LOGO_Action_enfance.jpg | Bin 0 -> 116663 bytes .../03.clients/LOGO_LEPPI.jpg | Bin 0 -> 42750 bytes .../03.clients/Logo Groupe CTN.jpg | Bin 0 -> 47953 bytes .../03.clients/LogoINIRR.jpg | Bin 0 -> 60599 bytes .../03.clients/Logo_Benedictines_Vanves.jpg | Bin 0 -> 96048 bytes .../03.clients/Logo_Colibri.jpg | Bin 0 -> 53854 bytes .../03.clients/SGDF_OK.jpg | Bin 0 -> 94708 bytes .../03.clients/Wild_Bed.jpg | Bin 0 -> 87608 bytes .../05.nouvelle-section-2/03.clients/blog.md | 14 + .../03.clients/extreme_OK.jpg | Bin 0 -> 41797 bytes .../logo-carre_5Painset2poissons.jpg | Bin 0 -> 56609 bytes .../03.clients/logo-carre_ACI.jpg | Bin 0 -> 14662 bytes .../03.clients/logo-carre_AFS.jpg | Bin 0 -> 38081 bytes .../03.clients/logo-carre_APF.jpg | Bin 0 -> 31381 bytes .../03.clients/logo-carre_Caritas-France.jpg | Bin 0 -> 35511 bytes .../03.clients/logo-carre_Massillon.jpg | Bin 0 -> 68289 bytes .../logo-carre_Signal-Expertise.jpg | Bin 0 -> 15206 bytes .../03.clients/logo-carre_laFedeeh.jpg | Bin 0 -> 32851 bytes .../03.clients/logo-carre_solifap.jpg | Bin 0 -> 23550 bytes .../03.clients/logo_CMCPM_site_LSO.jpg | Bin 0 -> 57270 bytes .../03.clients/particuliersOK2.jpg | Bin 0 -> 68502 bytes user/pages/05.nouvelle-section-2/blog.md | 20 + .../06.contact/01.profil/EC_BD_modif.png | Bin 0 -> 571596 bytes .../06.contact/01.profil/facebook-red.svg | 77 + user/pages/06.contact/01.profil/items.md | 13 + .../06.contact/01.profil/linkedin-red.svg | 1 + user/pages/06.contact/02.profil-2/items.md | 33 + user/pages/06.contact/EC_BD_modif.png | Bin 0 -> 571596 bytes user/pages/06.contact/blog.md | 14 + .../conditions-generales-des-services/blog.md | 5 + .../07.pied-de-page/mentions-legales/blog.md | 21 + user/pages/07.pied-de-page/modular.md | 14 + user/plugins/.gitkeep | 0 user/themes/.gitkeep | 0 .../themes/le_style_de_lours_modif/.gitignore | 2 + .../le_style_de_lours_modif/CHANGELOG.md | 121 + user/themes/le_style_de_lours_modif/LICENSE | 21 + user/themes/le_style_de_lours_modif/README.md | 151 + .../assets/quark-screenshots.jpg | Bin 0 -> 198055 bytes .../le_style_de_lours_modif/blueprints.yaml | 174 + .../blueprints/blog.yaml | 105 + .../blueprints/default.yaml | 15 + .../blueprints/item.yaml | 113 + .../blueprints/modular/features.yaml | 38 + .../blueprints/modular/hero.yaml | 23 + .../blueprints/modular/text.yaml | 19 + .../blueprints/partials/blog-bits.yaml | 64 + .../css-compiled/spectre-exp.css | 369 + .../css-compiled/spectre-exp.min.css | 1 + .../css-compiled/spectre-icons.css | 172 + .../css-compiled/spectre-icons.min.css | 1 + .../css-compiled/spectre.css | 1244 +++ .../css-compiled/spectre.min.css | 1 + .../css-compiled/theme.css | 1593 +++ .../css-compiled/theme.css.map | 1 + .../css-compiled/theme.min.css | 1742 +++ .../css-compiled/theme.min.css.map | 1 + .../css/bricklayer.css | 49 + .../le_style_de_lours_modif/css/custom.css | 0 .../css/jquery.mCustomScrollbar.css | 1267 +++ .../css/line-awesome.min.css | 4 + .../css/owl.carousel.min.css | 6 + .../css/owl.theme.default.min.css | 6 + .../leaguegothic-condensed-italic-webfont.eot | Bin 0 -> 26393 bytes .../leaguegothic-condensed-italic-webfont.svg | 224 + .../leaguegothic-condensed-italic-webfont.ttf | Bin 0 -> 53764 bytes ...leaguegothic-condensed-italic-webfont.woff | Bin 0 -> 29564 bytes ...leaguegothic-condensed-regular-webfont.eot | Bin 0 -> 19318 bytes ...leaguegothic-condensed-regular-webfont.svg | 224 + ...leaguegothic-condensed-regular-webfont.ttf | Bin 0 -> 38832 bytes ...eaguegothic-condensed-regular-webfont.woff | Bin 0 -> 21844 bytes .../leaguegothic-italic-webfont.eot | Bin 0 -> 22859 bytes .../leaguegothic-italic-webfont.svg | 224 + .../leaguegothic-italic-webfont.ttf | Bin 0 -> 51900 bytes .../leaguegothic-italic-webfont.woff | Bin 0 -> 26000 bytes .../leaguegothic-regular-webfont.eot | Bin 0 -> 16961 bytes .../leaguegothic-regular-webfont.svg | 223 + .../leaguegothic-regular-webfont.ttf | Bin 0 -> 35664 bytes .../leaguegothic-regular-webfont.woff | Bin 0 -> 19548 bytes .../fonts/League_gothic/stylesheet.css | 50 + .../fonts/line-awesome.eot | Bin 0 -> 213245 bytes .../fonts/line-awesome.svg | 2954 +++++ .../fonts/line-awesome.ttf | Bin 0 -> 263504 bytes .../fonts/line-awesome.woff | Bin 0 -> 117372 bytes .../fonts/line-awesome.woff2 | Bin 0 -> 76372 bytes .../fonts/roboto/Roboto-Bold-webfont.eot | Bin 0 -> 36098 bytes .../fonts/roboto/Roboto-Bold-webfont.svg | 607 + .../fonts/roboto/Roboto-Bold-webfont.ttf | Bin 0 -> 35912 bytes .../fonts/roboto/Roboto-Bold-webfont.woff | Bin 0 -> 21320 bytes .../roboto/Roboto-BoldItalic-webfont.eot | Bin 0 -> 37078 bytes .../roboto/Roboto-BoldItalic-webfont.svg | 656 ++ .../roboto/Roboto-BoldItalic-webfont.ttf | Bin 0 -> 36864 bytes .../roboto/Roboto-BoldItalic-webfont.woff | Bin 0 -> 22312 bytes .../fonts/roboto/Roboto-Italic-webfont.eot | Bin 0 -> 35706 bytes .../fonts/roboto/Roboto-Italic-webfont.svg | 656 ++ .../fonts/roboto/Roboto-Italic-webfont.ttf | Bin 0 -> 35512 bytes .../fonts/roboto/Roboto-Italic-webfont.woff | Bin 0 -> 21948 bytes .../fonts/roboto/Roboto-Light-webfont.eot | Bin 0 -> 34598 bytes .../fonts/roboto/Roboto-Light-webfont.svg | 655 ++ .../fonts/roboto/Roboto-Light-webfont.ttf | Bin 0 -> 34392 bytes .../fonts/roboto/Roboto-Light-webfont.woff | Bin 0 -> 20904 bytes .../fonts/roboto/Roboto-Medium-webfont.eot | Bin 0 -> 35182 bytes .../fonts/roboto/Roboto-Medium-webfont.svg | 607 + .../fonts/roboto/Roboto-Medium-webfont.ttf | Bin 0 -> 34972 bytes .../fonts/roboto/Roboto-Medium-webfont.woff | Bin 0 -> 21184 bytes .../roboto/Roboto-MediumItalic-webfont.eot | Bin 0 -> 36218 bytes .../roboto/Roboto-MediumItalic-webfont.svg | 656 ++ .../roboto/Roboto-MediumItalic-webfont.ttf | Bin 0 -> 35996 bytes .../roboto/Roboto-MediumItalic-webfont.woff | Bin 0 -> 22104 bytes .../fonts/roboto/Roboto-Regular-webfont.eot | Bin 0 -> 34722 bytes .../fonts/roboto/Roboto-Regular-webfont.svg | 635 ++ .../fonts/roboto/Roboto-Regular-webfont.ttf | Bin 0 -> 34524 bytes .../fonts/roboto/Roboto-Regular-webfont.woff | Bin 0 -> 20924 bytes .../le_style_de_lours_modif/gulpfile.js | 39 + .../images/favicon.png | Bin 0 -> 4903 bytes .../images/grav-logo.svg | 418 + .../js/bricklayer.min.js | 1 + .../js/jquery-1.10.2.js | 9789 +++++++++++++++++ .../js/jquery.mCustomScrollbar.js | 2458 +++++ .../js/jquery.treemenu.js | 87 + .../js/owl.carousel.min.js | 7 + .../js/scopedQuerySelectorShim.min.js | 9 + .../le_style_de_lours_modif/js/scritps.js | 90 + .../js/singlepagenav.min.js | 8 + .../themes/le_style_de_lours_modif/js/site.js | 59 + .../js/smooth-scroll.min.js | 6 + .../le_style_de_lours_modif/languages.yaml | 240 + .../le_style_de_lours_modif.php | 56 + .../le_style_de_lours_modif.yaml | 12 + .../le_style_de_lours_modif/package-lock.json | 5178 +++++++++ .../le_style_de_lours_modif/package.json | 45 + .../le_style_de_lours_modif/screenshot.jpg | Bin 0 -> 159731 bytes .../le_style_de_lours_modif/scss/theme.scss | 22 + .../scss/theme/_animation.scss | 156 + .../scss/theme/_carousel.scss | 103 + .../scss/theme/_fonts.scss | 173 + .../scss/theme/_footer.scss | 57 + .../scss/theme/_header.scss | 190 + .../scss/theme/_media-quieries.scss | 302 + .../scss/theme/_menu.scss | 94 + .../scss/theme/_mixins.scss | 94 + .../scss/theme/_mobile.scss | 193 + .../scss/theme/_reset.scss | 375 + .../scss/theme/_start.scss | 396 + .../scss/theme/_typography.scss | 247 + .../scss/theme/_variables.scss | 62 + .../templates/blog.html.twig | 63 + .../templates/default.html.twig | 5 + .../templates/error.html.twig | 12 + .../forms/fields/checkbox/checkbox.html.twig | 32 + .../fields/checkboxes/checkboxes.html.twig | 44 + .../forms/fields/radio/radio.html.twig | 26 + .../forms/fields/switch/switch.html.twig | 3 + .../templates/item-etapes.html.twig | 21 + .../templates/item.html.twig | 40 + .../templates/items.html.twig | 21 + .../templates/macros/macros.html.twig | 22 + .../templates/modular.html.twig | 97 + .../templates/modular/features.html.twig | 30 + .../templates/modular/hero.html.twig | 4 + .../templates/modular/text.html.twig | 19 + .../templates/partials/archives.html.twig | 13 + .../templates/partials/base.html.twig | 156 + .../templates/partials/blog-item.html.twig | 34 + .../partials/blog-list-item.html.twig | 27 + .../templates/partials/blog/date.html.twig | 5 + .../partials/blog/page-summary.html.twig | 8 + .../partials/blog/taxonomy.html.twig | 7 + .../templates/partials/blog/title.html.twig | 11 + .../templates/partials/footer.html.twig | 5 + .../partials/form-messages.html.twig | 6 + .../templates/partials/hero.html.twig | 7 + .../templates/partials/layout.html.twig | 13 + .../templates/partials/login-status.html.twig | 4 + .../templates/partials/logo.html.twig | 7 + .../templates/partials/messages.html.twig | 17 + .../templates/partials/navigation.html.twig | 6 + .../templates/partials/no-gal.html.twig | 43 + .../templates/partials/relatedpages.html.twig | 15 + .../templates/partials/sidebar.html.twig | 43 + .../templates/partials/sous-gal.html.twig | 43 + .../templates/partials/taxonomylist.html.twig | 10 + .../le_style_de_lours_modif/thumbnail.jpg | Bin 0 -> 49487 bytes user/themes/le_style_de_lours_modif/yarn.lock | 2835 +++++ webserver-configs/Caddyfile | 31 + webserver-configs/Caddyfile-0.8.x | 33 + webserver-configs/htaccess.txt | 78 + webserver-configs/lighttpd.conf | 48 + webserver-configs/nginx.conf | 44 + webserver-configs/web.config | 42 + 1209 files changed, 172996 insertions(+) create mode 100644 .dependencies create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .htaccess create mode 100644 .phan/config.php create mode 100644 .phan/internal_stubs/Redis.phan_php create mode 100644 .phan/internal_stubs/memcache.phan_php create mode 100644 .phan/internal_stubs/memcached.phan_php create mode 100644 .travis.yml create mode 100644 CHANGELOG.md create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 SECURITY.md create mode 100644 assets/.gitkeep create mode 100644 backup/.gitkeep create mode 100755 bin/composer.phar create mode 100755 bin/gpm create mode 100755 bin/grav create mode 100755 bin/plugin create mode 100644 cache/.gitkeep create mode 100644 codeception.yml create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 images/.gitkeep create mode 100644 index.php create mode 100644 logs/.gitkeep create mode 100644 now.json create mode 100644 robots.txt create mode 100644 system/assets/debugger/clockwork.css create mode 100644 system/assets/debugger/clockwork.js create mode 100644 system/assets/debugger/phpdebugbar.css create mode 100644 system/assets/grav.png create mode 100644 system/assets/jquery/jquery-2.1.4.min.js create mode 100644 system/assets/jquery/jquery-2.x.min.js create mode 100644 system/assets/jquery/jquery-3.x.min.js create mode 100644 system/assets/responsive-overlays/1x.png create mode 100644 system/assets/responsive-overlays/2x.png create mode 100644 system/assets/responsive-overlays/3x.png create mode 100644 system/assets/responsive-overlays/4x.png create mode 100644 system/assets/responsive-overlays/unknown.png create mode 100644 system/assets/whoops.css create mode 100644 system/blueprints/config/backups.yaml create mode 100644 system/blueprints/config/media.yaml create mode 100644 system/blueprints/config/scheduler.yaml create mode 100644 system/blueprints/config/security.yaml create mode 100644 system/blueprints/config/site.yaml create mode 100644 system/blueprints/config/streams.yaml create mode 100644 system/blueprints/config/system.yaml create mode 100644 system/blueprints/flex/accounts.yaml create mode 100644 system/blueprints/flex/configure/compat.yaml create mode 100644 system/blueprints/flex/pages.yaml create mode 100644 system/blueprints/flex/shared/configure.yaml create mode 100644 system/blueprints/flex/user-accounts.yaml create mode 100644 system/blueprints/flex/user-groups.yaml create mode 100644 system/blueprints/pages/default.yaml create mode 100644 system/blueprints/pages/external.yaml create mode 100644 system/blueprints/pages/modular.yaml create mode 100644 system/blueprints/pages/partials/security.yaml create mode 100644 system/blueprints/pages/root.yaml create mode 100644 system/blueprints/user/account.yaml create mode 100644 system/blueprints/user/account_new.yaml create mode 100644 system/blueprints/user/group.yaml create mode 100644 system/blueprints/user/group_new.yaml create mode 100644 system/config/backups.yaml create mode 100644 system/config/media.yaml create mode 100644 system/config/mime.yaml create mode 100644 system/config/permissions.yaml create mode 100644 system/config/security.yaml create mode 100644 system/config/site.yaml create mode 100644 system/config/system.yaml create mode 100644 system/defines.php create mode 100644 system/images/media/thumb-3dm.png create mode 100644 system/images/media/thumb-3ds.png create mode 100644 system/images/media/thumb-3g2.png create mode 100644 system/images/media/thumb-3gp.png create mode 100644 system/images/media/thumb-7z.png create mode 100644 system/images/media/thumb-aac.png create mode 100644 system/images/media/thumb-ai.png create mode 100644 system/images/media/thumb-aif.png create mode 100644 system/images/media/thumb-apk.png create mode 100644 system/images/media/thumb-app.png create mode 100644 system/images/media/thumb-asf.png create mode 100644 system/images/media/thumb-asp.png create mode 100644 system/images/media/thumb-aspx.png create mode 100644 system/images/media/thumb-asx.png create mode 100644 system/images/media/thumb-avi.png create mode 100644 system/images/media/thumb-bak.png create mode 100644 system/images/media/thumb-bat.png create mode 100644 system/images/media/thumb-bin.png create mode 100644 system/images/media/thumb-bmp.png create mode 100644 system/images/media/thumb-cab.png create mode 100644 system/images/media/thumb-cad.png create mode 100644 system/images/media/thumb-cdr.png create mode 100644 system/images/media/thumb-cer.png create mode 100644 system/images/media/thumb-cfg.png create mode 100644 system/images/media/thumb-cfm.png create mode 100644 system/images/media/thumb-cgi.png create mode 100644 system/images/media/thumb-com.png create mode 100644 system/images/media/thumb-cpl.png create mode 100644 system/images/media/thumb-cpp.png create mode 100644 system/images/media/thumb-crx.png create mode 100644 system/images/media/thumb-csr.png create mode 100644 system/images/media/thumb-css.png create mode 100644 system/images/media/thumb-csv.png create mode 100644 system/images/media/thumb-cue.png create mode 100644 system/images/media/thumb-cur.png create mode 100644 system/images/media/thumb-dat.png create mode 100644 system/images/media/thumb-db.png create mode 100644 system/images/media/thumb-dbf.png create mode 100644 system/images/media/thumb-dds.png create mode 100644 system/images/media/thumb-dem.png create mode 100644 system/images/media/thumb-dll.png create mode 100644 system/images/media/thumb-dmg.png create mode 100644 system/images/media/thumb-dmp.png create mode 100644 system/images/media/thumb-doc.png create mode 100644 system/images/media/thumb-docx.png create mode 100644 system/images/media/thumb-drv.png create mode 100644 system/images/media/thumb-dtd.png create mode 100644 system/images/media/thumb-dwg.png create mode 100644 system/images/media/thumb-dxf.png create mode 100644 system/images/media/thumb-elf.png create mode 100644 system/images/media/thumb-eot.png create mode 100644 system/images/media/thumb-eps.png create mode 100644 system/images/media/thumb-exe.png create mode 100644 system/images/media/thumb-fla.png create mode 100644 system/images/media/thumb-flv.png create mode 100644 system/images/media/thumb-fnt.png create mode 100644 system/images/media/thumb-fon.png create mode 100644 system/images/media/thumb-gam.png create mode 100644 system/images/media/thumb-gbr.png create mode 100644 system/images/media/thumb-ged.png create mode 100644 system/images/media/thumb-gif.png create mode 100644 system/images/media/thumb-gpx.png create mode 100644 system/images/media/thumb-gz.png create mode 100644 system/images/media/thumb-gzip.png create mode 100644 system/images/media/thumb-hqz.png create mode 100644 system/images/media/thumb-html.png create mode 100644 system/images/media/thumb-icns.png create mode 100644 system/images/media/thumb-ico.png create mode 100644 system/images/media/thumb-ics.png create mode 100644 system/images/media/thumb-iff.png create mode 100644 system/images/media/thumb-indd.png create mode 100644 system/images/media/thumb-iso.png create mode 100644 system/images/media/thumb-jar.png create mode 100644 system/images/media/thumb-jpg.png create mode 100644 system/images/media/thumb-js.png create mode 100644 system/images/media/thumb-json.png create mode 100644 system/images/media/thumb-jsp.png create mode 100644 system/images/media/thumb-key.png create mode 100644 system/images/media/thumb-kml.png create mode 100644 system/images/media/thumb-kmz.png create mode 100644 system/images/media/thumb-lnk.png create mode 100644 system/images/media/thumb-log.png create mode 100644 system/images/media/thumb-lua.png create mode 100644 system/images/media/thumb-m3u.png create mode 100644 system/images/media/thumb-m4a.png create mode 100644 system/images/media/thumb-m4v.png create mode 100644 system/images/media/thumb-max.png create mode 100644 system/images/media/thumb-mdb.png create mode 100644 system/images/media/thumb-mdf.png create mode 100644 system/images/media/thumb-mid.png create mode 100644 system/images/media/thumb-mim.png create mode 100644 system/images/media/thumb-mov.png create mode 100644 system/images/media/thumb-mp3.png create mode 100644 system/images/media/thumb-mp4.png create mode 100644 system/images/media/thumb-mpa.png create mode 100644 system/images/media/thumb-mpe.png create mode 100644 system/images/media/thumb-mpg.png create mode 100644 system/images/media/thumb-msg.png create mode 100644 system/images/media/thumb-msi.png create mode 100644 system/images/media/thumb-nes.png create mode 100644 system/images/media/thumb-obj.png create mode 100644 system/images/media/thumb-odb.png create mode 100644 system/images/media/thumb-odc.png create mode 100644 system/images/media/thumb-odf.png create mode 100644 system/images/media/thumb-odg.png create mode 100644 system/images/media/thumb-odi.png create mode 100644 system/images/media/thumb-odp.png create mode 100644 system/images/media/thumb-ods.png create mode 100644 system/images/media/thumb-odt.png create mode 100644 system/images/media/thumb-odx.png create mode 100644 system/images/media/thumb-ogg.png create mode 100644 system/images/media/thumb-pct.png create mode 100644 system/images/media/thumb-pdb.png create mode 100644 system/images/media/thumb-pdf.png create mode 100644 system/images/media/thumb-pif.png create mode 100644 system/images/media/thumb-pkg.png create mode 100644 system/images/media/thumb-pl.png create mode 100644 system/images/media/thumb-png.png create mode 100644 system/images/media/thumb-pps.png create mode 100644 system/images/media/thumb-ppt.png create mode 100644 system/images/media/thumb-pptx.png create mode 100644 system/images/media/thumb-ps.png create mode 100644 system/images/media/thumb-psd.png create mode 100644 system/images/media/thumb-pub.png create mode 100644 system/images/media/thumb-py.png create mode 100644 system/images/media/thumb-ra.png create mode 100644 system/images/media/thumb-rar.png create mode 100644 system/images/media/thumb-raw.png create mode 100644 system/images/media/thumb-rm.png create mode 100644 system/images/media/thumb-rom.png create mode 100644 system/images/media/thumb-rpm.png create mode 100644 system/images/media/thumb-rss.png create mode 100644 system/images/media/thumb-rtf.png create mode 100644 system/images/media/thumb-sav.png create mode 100644 system/images/media/thumb-sdf.png create mode 100644 system/images/media/thumb-sql.png create mode 100644 system/images/media/thumb-srt.png create mode 100644 system/images/media/thumb-svg.png create mode 100644 system/images/media/thumb-swf.png create mode 100644 system/images/media/thumb-sys.png create mode 100644 system/images/media/thumb-tar.png create mode 100644 system/images/media/thumb-tex.png create mode 100644 system/images/media/thumb-tga.png create mode 100644 system/images/media/thumb-thm.png create mode 100644 system/images/media/thumb-tiff.png create mode 100644 system/images/media/thumb-tmp.png create mode 100644 system/images/media/thumb-ttf.png create mode 100644 system/images/media/thumb-txt.png create mode 100644 system/images/media/thumb-uue.png create mode 100644 system/images/media/thumb-vb.png create mode 100644 system/images/media/thumb-vcd.png create mode 100644 system/images/media/thumb-vcf.png create mode 100644 system/images/media/thumb-wav.png create mode 100644 system/images/media/thumb-webm.png create mode 100644 system/images/media/thumb-wma.png create mode 100644 system/images/media/thumb-wmv.png create mode 100644 system/images/media/thumb-woff.png create mode 100644 system/images/media/thumb-woff2.png create mode 100644 system/images/media/thumb-wpd.png create mode 100644 system/images/media/thumb-wps.png create mode 100644 system/images/media/thumb-wsf.png create mode 100644 system/images/media/thumb-xls.png create mode 100644 system/images/media/thumb-xlsx.png create mode 100644 system/images/media/thumb-xml.png create mode 100644 system/images/media/thumb-yuv.png create mode 100644 system/images/media/thumb-zip.png create mode 100644 system/images/media/thumb.png create mode 100644 system/images/watermark.png create mode 100644 system/install.php create mode 100644 system/languages/ar.yaml create mode 100644 system/languages/bg.yaml create mode 100644 system/languages/ca.yaml create mode 100644 system/languages/cs.yaml create mode 100644 system/languages/da.yaml create mode 100644 system/languages/de.yaml create mode 100644 system/languages/el.yaml create mode 100644 system/languages/en.yaml create mode 100644 system/languages/eo.yaml create mode 100644 system/languages/es.yaml create mode 100644 system/languages/et.yaml create mode 100644 system/languages/eu.yaml create mode 100644 system/languages/fa.yaml create mode 100644 system/languages/fi.yaml create mode 100644 system/languages/fr.yaml create mode 100644 system/languages/gl.yaml create mode 100644 system/languages/he.yaml create mode 100644 system/languages/hr.yaml create mode 100644 system/languages/hu.yaml create mode 100644 system/languages/id.yaml create mode 100644 system/languages/is.yaml create mode 100644 system/languages/it.yaml create mode 100644 system/languages/ja.yaml create mode 100644 system/languages/ko.yaml create mode 100644 system/languages/lt.yaml create mode 100644 system/languages/lv.yaml create mode 100644 system/languages/mn.yaml create mode 100644 system/languages/my.yaml create mode 100644 system/languages/nb.yaml create mode 100644 system/languages/nl.yaml create mode 100644 system/languages/no.yaml create mode 100644 system/languages/pl.yaml create mode 100644 system/languages/pt.yaml create mode 100644 system/languages/ro.yaml create mode 100644 system/languages/ru.yaml create mode 100644 system/languages/si.yaml create mode 100644 system/languages/sk.yaml create mode 100644 system/languages/sl.yaml create mode 100644 system/languages/sr.yaml create mode 100644 system/languages/sv.yaml create mode 100644 system/languages/sw.yaml create mode 100644 system/languages/th.yaml create mode 100644 system/languages/tr.yaml create mode 100644 system/languages/uk.yaml create mode 100644 system/languages/vi.yaml create mode 100644 system/languages/zh-cn.yaml create mode 100644 system/languages/zh-tw.yaml create mode 100644 system/languages/zh.yaml create mode 100644 system/pages/notfound.md create mode 100644 system/router.php create mode 100644 system/src/DOMLettersIterator.php create mode 100644 system/src/DOMWordsIterator.php create mode 100644 system/src/Grav/Common/Assets.php create mode 100644 system/src/Grav/Common/Assets/BaseAsset.php create mode 100644 system/src/Grav/Common/Assets/BlockAssets.php create mode 100644 system/src/Grav/Common/Assets/Css.php create mode 100644 system/src/Grav/Common/Assets/InlineCss.php create mode 100644 system/src/Grav/Common/Assets/InlineJs.php create mode 100644 system/src/Grav/Common/Assets/InlineJsModule.php create mode 100644 system/src/Grav/Common/Assets/Js.php create mode 100644 system/src/Grav/Common/Assets/JsModule.php create mode 100644 system/src/Grav/Common/Assets/Link.php create mode 100644 system/src/Grav/Common/Assets/Pipeline.php create mode 100644 system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php create mode 100644 system/src/Grav/Common/Assets/Traits/LegacyAssetsTrait.php create mode 100644 system/src/Grav/Common/Assets/Traits/TestingAssetsTrait.php create mode 100644 system/src/Grav/Common/Backup/Backups.php create mode 100644 system/src/Grav/Common/Browser.php create mode 100644 system/src/Grav/Common/Cache.php create mode 100644 system/src/Grav/Common/Composer.php create mode 100644 system/src/Grav/Common/Config/CompiledBase.php create mode 100644 system/src/Grav/Common/Config/CompiledBlueprints.php create mode 100644 system/src/Grav/Common/Config/CompiledConfig.php create mode 100644 system/src/Grav/Common/Config/CompiledLanguages.php create mode 100644 system/src/Grav/Common/Config/Config.php create mode 100644 system/src/Grav/Common/Config/ConfigFileFinder.php create mode 100644 system/src/Grav/Common/Config/Languages.php create mode 100644 system/src/Grav/Common/Config/Setup.php create mode 100644 system/src/Grav/Common/Data/Blueprint.php create mode 100644 system/src/Grav/Common/Data/BlueprintSchema.php create mode 100644 system/src/Grav/Common/Data/Blueprints.php create mode 100644 system/src/Grav/Common/Data/Data.php create mode 100644 system/src/Grav/Common/Data/DataInterface.php create mode 100644 system/src/Grav/Common/Data/Validation.php create mode 100644 system/src/Grav/Common/Data/ValidationException.php create mode 100644 system/src/Grav/Common/Debugger.php create mode 100644 system/src/Grav/Common/Errors/BareHandler.php create mode 100644 system/src/Grav/Common/Errors/Errors.php create mode 100644 system/src/Grav/Common/Errors/Resources/error.css create mode 100644 system/src/Grav/Common/Errors/Resources/layout.html.php create mode 100644 system/src/Grav/Common/Errors/SimplePageHandler.php create mode 100644 system/src/Grav/Common/Errors/SystemFacade.php create mode 100644 system/src/Grav/Common/File/CompiledFile.php create mode 100644 system/src/Grav/Common/File/CompiledJsonFile.php create mode 100644 system/src/Grav/Common/File/CompiledMarkdownFile.php create mode 100644 system/src/Grav/Common/File/CompiledYamlFile.php create mode 100644 system/src/Grav/Common/Filesystem/Archiver.php create mode 100644 system/src/Grav/Common/Filesystem/Folder.php create mode 100644 system/src/Grav/Common/Filesystem/RecursiveDirectoryFilterIterator.php create mode 100644 system/src/Grav/Common/Filesystem/RecursiveFolderFilterIterator.php create mode 100644 system/src/Grav/Common/Filesystem/ZipArchiver.php create mode 100644 system/src/Grav/Common/Flex/FlexCollection.php create mode 100644 system/src/Grav/Common/Flex/FlexIndex.php create mode 100644 system/src/Grav/Common/Flex/FlexObject.php create mode 100644 system/src/Grav/Common/Flex/Traits/FlexCollectionTrait.php create mode 100644 system/src/Grav/Common/Flex/Traits/FlexCommonTrait.php create mode 100644 system/src/Grav/Common/Flex/Traits/FlexGravTrait.php create mode 100644 system/src/Grav/Common/Flex/Traits/FlexIndexTrait.php create mode 100644 system/src/Grav/Common/Flex/Traits/FlexObjectTrait.php create mode 100644 system/src/Grav/Common/Flex/Types/Generic/GenericCollection.php create mode 100644 system/src/Grav/Common/Flex/Types/Generic/GenericIndex.php create mode 100644 system/src/Grav/Common/Flex/Types/Generic/GenericObject.php create mode 100644 system/src/Grav/Common/Flex/Types/Pages/PageCollection.php create mode 100644 system/src/Grav/Common/Flex/Types/Pages/PageIndex.php create mode 100644 system/src/Grav/Common/Flex/Types/Pages/PageObject.php create mode 100644 system/src/Grav/Common/Flex/Types/Pages/Storage/PageStorage.php create mode 100644 system/src/Grav/Common/Flex/Types/Pages/Traits/PageContentTrait.php create mode 100644 system/src/Grav/Common/Flex/Types/Pages/Traits/PageLegacyTrait.php create mode 100644 system/src/Grav/Common/Flex/Types/Pages/Traits/PageRoutableTrait.php create mode 100644 system/src/Grav/Common/Flex/Types/Pages/Traits/PageTranslateTrait.php create mode 100644 system/src/Grav/Common/Flex/Types/UserGroups/UserGroupCollection.php create mode 100644 system/src/Grav/Common/Flex/Types/UserGroups/UserGroupIndex.php create mode 100644 system/src/Grav/Common/Flex/Types/UserGroups/UserGroupObject.php create mode 100644 system/src/Grav/Common/Flex/Types/Users/Storage/UserFileStorage.php create mode 100644 system/src/Grav/Common/Flex/Types/Users/Storage/UserFolderStorage.php create mode 100644 system/src/Grav/Common/Flex/Types/Users/Traits/UserObjectLegacyTrait.php create mode 100644 system/src/Grav/Common/Flex/Types/Users/UserCollection.php create mode 100644 system/src/Grav/Common/Flex/Types/Users/UserIndex.php create mode 100644 system/src/Grav/Common/Flex/Types/Users/UserObject.php create mode 100644 system/src/Grav/Common/Form/FormFlash.php create mode 100644 system/src/Grav/Common/GPM/AbstractCollection.php create mode 100644 system/src/Grav/Common/GPM/Common/AbstractPackageCollection.php create mode 100644 system/src/Grav/Common/GPM/Common/CachedCollection.php create mode 100644 system/src/Grav/Common/GPM/Common/Package.php create mode 100644 system/src/Grav/Common/GPM/GPM.php create mode 100644 system/src/Grav/Common/GPM/Installer.php create mode 100644 system/src/Grav/Common/GPM/Licenses.php create mode 100644 system/src/Grav/Common/GPM/Local/AbstractPackageCollection.php create mode 100644 system/src/Grav/Common/GPM/Local/Package.php create mode 100644 system/src/Grav/Common/GPM/Local/Packages.php create mode 100644 system/src/Grav/Common/GPM/Local/Plugins.php create mode 100644 system/src/Grav/Common/GPM/Local/Themes.php create mode 100644 system/src/Grav/Common/GPM/Remote/AbstractPackageCollection.php create mode 100644 system/src/Grav/Common/GPM/Remote/GravCore.php create mode 100644 system/src/Grav/Common/GPM/Remote/Package.php create mode 100644 system/src/Grav/Common/GPM/Remote/Packages.php create mode 100644 system/src/Grav/Common/GPM/Remote/Plugins.php create mode 100644 system/src/Grav/Common/GPM/Remote/Themes.php create mode 100644 system/src/Grav/Common/GPM/Response.php create mode 100644 system/src/Grav/Common/GPM/Upgrader.php create mode 100644 system/src/Grav/Common/Getters.php create mode 100644 system/src/Grav/Common/Grav.php create mode 100644 system/src/Grav/Common/GravTrait.php create mode 100644 system/src/Grav/Common/HTTP/Client.php create mode 100644 system/src/Grav/Common/HTTP/Response.php create mode 100644 system/src/Grav/Common/Helpers/Base32.php create mode 100644 system/src/Grav/Common/Helpers/Excerpts.php create mode 100644 system/src/Grav/Common/Helpers/Exif.php create mode 100644 system/src/Grav/Common/Helpers/LogViewer.php create mode 100644 system/src/Grav/Common/Helpers/Truncator.php create mode 100644 system/src/Grav/Common/Helpers/YamlLinter.php create mode 100644 system/src/Grav/Common/Inflector.php create mode 100644 system/src/Grav/Common/Iterator.php create mode 100644 system/src/Grav/Common/Language/Language.php create mode 100644 system/src/Grav/Common/Language/LanguageCodes.php create mode 100644 system/src/Grav/Common/Markdown/Parsedown.php create mode 100644 system/src/Grav/Common/Markdown/ParsedownExtra.php create mode 100644 system/src/Grav/Common/Markdown/ParsedownGravTrait.php create mode 100644 system/src/Grav/Common/Media/Interfaces/AudioMediaInterface.php create mode 100644 system/src/Grav/Common/Media/Interfaces/ImageManipulateInterface.php create mode 100644 system/src/Grav/Common/Media/Interfaces/ImageMediaInterface.php create mode 100644 system/src/Grav/Common/Media/Interfaces/MediaCollectionInterface.php create mode 100644 system/src/Grav/Common/Media/Interfaces/MediaFileInterface.php create mode 100644 system/src/Grav/Common/Media/Interfaces/MediaInterface.php create mode 100644 system/src/Grav/Common/Media/Interfaces/MediaLinkInterface.php create mode 100644 system/src/Grav/Common/Media/Interfaces/MediaObjectInterface.php create mode 100644 system/src/Grav/Common/Media/Interfaces/MediaPlayerInterface.php create mode 100644 system/src/Grav/Common/Media/Interfaces/MediaUploadInterface.php create mode 100644 system/src/Grav/Common/Media/Interfaces/VideoMediaInterface.php create mode 100644 system/src/Grav/Common/Media/Traits/AudioMediaTrait.php create mode 100644 system/src/Grav/Common/Media/Traits/ImageDecodingTrait.php create mode 100644 system/src/Grav/Common/Media/Traits/ImageFetchPriorityTrait.php create mode 100644 system/src/Grav/Common/Media/Traits/ImageLoadingTrait.php create mode 100644 system/src/Grav/Common/Media/Traits/ImageMediaTrait.php create mode 100644 system/src/Grav/Common/Media/Traits/MediaFileTrait.php create mode 100644 system/src/Grav/Common/Media/Traits/MediaObjectTrait.php create mode 100644 system/src/Grav/Common/Media/Traits/MediaPlayerTrait.php create mode 100644 system/src/Grav/Common/Media/Traits/MediaTrait.php create mode 100644 system/src/Grav/Common/Media/Traits/MediaUploadTrait.php create mode 100644 system/src/Grav/Common/Media/Traits/StaticResizeTrait.php create mode 100644 system/src/Grav/Common/Media/Traits/ThumbnailMediaTrait.php create mode 100644 system/src/Grav/Common/Media/Traits/VideoMediaTrait.php create mode 100644 system/src/Grav/Common/Page/Collection.php create mode 100644 system/src/Grav/Common/Page/Header.php create mode 100644 system/src/Grav/Common/Page/Interfaces/PageCollectionInterface.php create mode 100644 system/src/Grav/Common/Page/Interfaces/PageContentInterface.php create mode 100644 system/src/Grav/Common/Page/Interfaces/PageFormInterface.php create mode 100644 system/src/Grav/Common/Page/Interfaces/PageInterface.php create mode 100644 system/src/Grav/Common/Page/Interfaces/PageLegacyInterface.php create mode 100644 system/src/Grav/Common/Page/Interfaces/PageRoutableInterface.php create mode 100644 system/src/Grav/Common/Page/Interfaces/PageTranslateInterface.php create mode 100644 system/src/Grav/Common/Page/Interfaces/PagesSourceInterface.php create mode 100644 system/src/Grav/Common/Page/Markdown/Excerpts.php create mode 100644 system/src/Grav/Common/Page/Media.php create mode 100644 system/src/Grav/Common/Page/Medium/AbstractMedia.php create mode 100644 system/src/Grav/Common/Page/Medium/AudioMedium.php create mode 100644 system/src/Grav/Common/Page/Medium/GlobalMedia.php create mode 100644 system/src/Grav/Common/Page/Medium/ImageFile.php create mode 100644 system/src/Grav/Common/Page/Medium/ImageMedium.php create mode 100644 system/src/Grav/Common/Page/Medium/Link.php create mode 100644 system/src/Grav/Common/Page/Medium/Medium.php create mode 100644 system/src/Grav/Common/Page/Medium/MediumFactory.php create mode 100644 system/src/Grav/Common/Page/Medium/ParsedownHtmlTrait.php create mode 100644 system/src/Grav/Common/Page/Medium/RenderableInterface.php create mode 100644 system/src/Grav/Common/Page/Medium/StaticImageMedium.php create mode 100644 system/src/Grav/Common/Page/Medium/StaticResizeTrait.php create mode 100644 system/src/Grav/Common/Page/Medium/ThumbnailImageMedium.php create mode 100644 system/src/Grav/Common/Page/Medium/VectorImageMedium.php create mode 100644 system/src/Grav/Common/Page/Medium/VideoMedium.php create mode 100644 system/src/Grav/Common/Page/Page.php create mode 100644 system/src/Grav/Common/Page/Pages.php create mode 100644 system/src/Grav/Common/Page/Traits/PageFormTrait.php create mode 100644 system/src/Grav/Common/Page/Types.php create mode 100644 system/src/Grav/Common/Plugin.php create mode 100644 system/src/Grav/Common/Plugins.php create mode 100644 system/src/Grav/Common/Processors/AssetsProcessor.php create mode 100644 system/src/Grav/Common/Processors/BackupsProcessor.php create mode 100644 system/src/Grav/Common/Processors/DebuggerAssetsProcessor.php create mode 100644 system/src/Grav/Common/Processors/Events/RequestHandlerEvent.php create mode 100644 system/src/Grav/Common/Processors/InitializeProcessor.php create mode 100644 system/src/Grav/Common/Processors/PagesProcessor.php create mode 100644 system/src/Grav/Common/Processors/PluginsProcessor.php create mode 100644 system/src/Grav/Common/Processors/ProcessorBase.php create mode 100644 system/src/Grav/Common/Processors/ProcessorInterface.php create mode 100644 system/src/Grav/Common/Processors/RenderProcessor.php create mode 100644 system/src/Grav/Common/Processors/RequestProcessor.php create mode 100644 system/src/Grav/Common/Processors/SchedulerProcessor.php create mode 100644 system/src/Grav/Common/Processors/TasksProcessor.php create mode 100644 system/src/Grav/Common/Processors/ThemesProcessor.php create mode 100644 system/src/Grav/Common/Processors/TwigProcessor.php create mode 100644 system/src/Grav/Common/Scheduler/Cron.php create mode 100644 system/src/Grav/Common/Scheduler/IntervalTrait.php create mode 100644 system/src/Grav/Common/Scheduler/Job.php create mode 100644 system/src/Grav/Common/Scheduler/Scheduler.php create mode 100644 system/src/Grav/Common/Security.php create mode 100644 system/src/Grav/Common/Service/AccountsServiceProvider.php create mode 100644 system/src/Grav/Common/Service/AssetsServiceProvider.php create mode 100644 system/src/Grav/Common/Service/BackupsServiceProvider.php create mode 100644 system/src/Grav/Common/Service/ConfigServiceProvider.php create mode 100644 system/src/Grav/Common/Service/ErrorServiceProvider.php create mode 100644 system/src/Grav/Common/Service/FilesystemServiceProvider.php create mode 100644 system/src/Grav/Common/Service/FlexServiceProvider.php create mode 100644 system/src/Grav/Common/Service/InflectorServiceProvider.php create mode 100644 system/src/Grav/Common/Service/LoggerServiceProvider.php create mode 100644 system/src/Grav/Common/Service/OutputServiceProvider.php create mode 100644 system/src/Grav/Common/Service/PagesServiceProvider.php create mode 100644 system/src/Grav/Common/Service/RequestServiceProvider.php create mode 100644 system/src/Grav/Common/Service/SchedulerServiceProvider.php create mode 100644 system/src/Grav/Common/Service/SessionServiceProvider.php create mode 100644 system/src/Grav/Common/Service/StreamsServiceProvider.php create mode 100644 system/src/Grav/Common/Service/TaskServiceProvider.php create mode 100644 system/src/Grav/Common/Session.php create mode 100644 system/src/Grav/Common/Taxonomy.php create mode 100644 system/src/Grav/Common/Theme.php create mode 100644 system/src/Grav/Common/Themes.php create mode 100644 system/src/Grav/Common/Twig/Exception/TwigException.php create mode 100644 system/src/Grav/Common/Twig/Extension/FilesystemExtension.php create mode 100644 system/src/Grav/Common/Twig/Extension/GravExtension.php create mode 100644 system/src/Grav/Common/Twig/Node/TwigNodeCache.php create mode 100644 system/src/Grav/Common/Twig/Node/TwigNodeLink.php create mode 100644 system/src/Grav/Common/Twig/Node/TwigNodeMarkdown.php create mode 100644 system/src/Grav/Common/Twig/Node/TwigNodeRender.php create mode 100644 system/src/Grav/Common/Twig/Node/TwigNodeScript.php create mode 100644 system/src/Grav/Common/Twig/Node/TwigNodeStyle.php create mode 100644 system/src/Grav/Common/Twig/Node/TwigNodeSwitch.php create mode 100644 system/src/Grav/Common/Twig/Node/TwigNodeThrow.php create mode 100644 system/src/Grav/Common/Twig/Node/TwigNodeTryCatch.php create mode 100644 system/src/Grav/Common/Twig/TokenParser/TwigTokenParserCache.php create mode 100644 system/src/Grav/Common/Twig/TokenParser/TwigTokenParserLink.php create mode 100644 system/src/Grav/Common/Twig/TokenParser/TwigTokenParserMarkdown.php create mode 100644 system/src/Grav/Common/Twig/TokenParser/TwigTokenParserRender.php create mode 100644 system/src/Grav/Common/Twig/TokenParser/TwigTokenParserScript.php create mode 100644 system/src/Grav/Common/Twig/TokenParser/TwigTokenParserStyle.php create mode 100644 system/src/Grav/Common/Twig/TokenParser/TwigTokenParserSwitch.php create mode 100644 system/src/Grav/Common/Twig/TokenParser/TwigTokenParserThrow.php create mode 100644 system/src/Grav/Common/Twig/TokenParser/TwigTokenParserTryCatch.php create mode 100644 system/src/Grav/Common/Twig/Twig.php create mode 100644 system/src/Grav/Common/Twig/TwigClockworkDataSource.php create mode 100644 system/src/Grav/Common/Twig/TwigClockworkDumper.php create mode 100644 system/src/Grav/Common/Twig/TwigEnvironment.php create mode 100644 system/src/Grav/Common/Twig/TwigExtension.php create mode 100644 system/src/Grav/Common/Twig/WriteCacheFileTrait.php create mode 100644 system/src/Grav/Common/Uri.php create mode 100644 system/src/Grav/Common/User/Access.php create mode 100644 system/src/Grav/Common/User/Authentication.php create mode 100644 system/src/Grav/Common/User/DataUser/User.php create mode 100644 system/src/Grav/Common/User/DataUser/UserCollection.php create mode 100644 system/src/Grav/Common/User/Group.php create mode 100644 system/src/Grav/Common/User/Interfaces/AuthorizeInterface.php create mode 100644 system/src/Grav/Common/User/Interfaces/UserCollectionInterface.php create mode 100644 system/src/Grav/Common/User/Interfaces/UserGroupInterface.php create mode 100644 system/src/Grav/Common/User/Interfaces/UserInterface.php create mode 100644 system/src/Grav/Common/User/Traits/UserTrait.php create mode 100644 system/src/Grav/Common/User/User.php create mode 100644 system/src/Grav/Common/Utils.php create mode 100644 system/src/Grav/Common/Yaml.php create mode 100644 system/src/Grav/Console/Application/Application.php create mode 100644 system/src/Grav/Console/Application/CommandLoader/PluginCommandLoader.php create mode 100644 system/src/Grav/Console/Application/GpmApplication.php create mode 100644 system/src/Grav/Console/Application/GravApplication.php create mode 100644 system/src/Grav/Console/Application/PluginApplication.php create mode 100644 system/src/Grav/Console/Cli/BackupCommand.php create mode 100644 system/src/Grav/Console/Cli/CleanCommand.php create mode 100644 system/src/Grav/Console/Cli/ClearCacheCommand.php create mode 100644 system/src/Grav/Console/Cli/ComposerCommand.php create mode 100644 system/src/Grav/Console/Cli/InstallCommand.php create mode 100644 system/src/Grav/Console/Cli/LogViewerCommand.php create mode 100644 system/src/Grav/Console/Cli/NewProjectCommand.php create mode 100644 system/src/Grav/Console/Cli/PageSystemValidatorCommand.php create mode 100644 system/src/Grav/Console/Cli/SandboxCommand.php create mode 100644 system/src/Grav/Console/Cli/SchedulerCommand.php create mode 100644 system/src/Grav/Console/Cli/SecurityCommand.php create mode 100644 system/src/Grav/Console/Cli/ServerCommand.php create mode 100644 system/src/Grav/Console/Cli/YamlLinterCommand.php create mode 100644 system/src/Grav/Console/ConsoleCommand.php create mode 100644 system/src/Grav/Console/ConsoleTrait.php create mode 100644 system/src/Grav/Console/Gpm/DirectInstallCommand.php create mode 100644 system/src/Grav/Console/Gpm/IndexCommand.php create mode 100644 system/src/Grav/Console/Gpm/InfoCommand.php create mode 100644 system/src/Grav/Console/Gpm/InstallCommand.php create mode 100644 system/src/Grav/Console/Gpm/SelfupgradeCommand.php create mode 100644 system/src/Grav/Console/Gpm/UninstallCommand.php create mode 100644 system/src/Grav/Console/Gpm/UpdateCommand.php create mode 100644 system/src/Grav/Console/Gpm/VersionCommand.php create mode 100644 system/src/Grav/Console/GpmCommand.php create mode 100644 system/src/Grav/Console/GravCommand.php create mode 100644 system/src/Grav/Console/Plugin/PluginListCommand.php create mode 100644 system/src/Grav/Console/TerminalObjects/Table.php create mode 100644 system/src/Grav/Events/BeforeSessionStartEvent.php create mode 100644 system/src/Grav/Events/FlexRegisterEvent.php create mode 100644 system/src/Grav/Events/PageEvent.php create mode 100644 system/src/Grav/Events/PermissionsRegisterEvent.php create mode 100644 system/src/Grav/Events/PluginsLoadedEvent.php create mode 100644 system/src/Grav/Events/SessionStartEvent.php create mode 100644 system/src/Grav/Events/TypesEvent.php create mode 100644 system/src/Grav/Framework/Acl/Access.php create mode 100644 system/src/Grav/Framework/Acl/Action.php create mode 100644 system/src/Grav/Framework/Acl/Permissions.php create mode 100644 system/src/Grav/Framework/Acl/PermissionsReader.php create mode 100644 system/src/Grav/Framework/Acl/RecursiveActionIterator.php create mode 100644 system/src/Grav/Framework/Cache/AbstractCache.php create mode 100644 system/src/Grav/Framework/Cache/Adapter/ChainCache.php create mode 100644 system/src/Grav/Framework/Cache/Adapter/DoctrineCache.php create mode 100644 system/src/Grav/Framework/Cache/Adapter/FileCache.php create mode 100644 system/src/Grav/Framework/Cache/Adapter/MemoryCache.php create mode 100644 system/src/Grav/Framework/Cache/Adapter/SessionCache.php create mode 100644 system/src/Grav/Framework/Cache/CacheInterface.php create mode 100644 system/src/Grav/Framework/Cache/CacheTrait.php create mode 100644 system/src/Grav/Framework/Cache/Exception/CacheException.php create mode 100644 system/src/Grav/Framework/Cache/Exception/InvalidArgumentException.php create mode 100644 system/src/Grav/Framework/Collection/AbstractFileCollection.php create mode 100644 system/src/Grav/Framework/Collection/AbstractIndexCollection.php create mode 100644 system/src/Grav/Framework/Collection/AbstractLazyCollection.php create mode 100644 system/src/Grav/Framework/Collection/ArrayCollection.php create mode 100644 system/src/Grav/Framework/Collection/CollectionInterface.php create mode 100644 system/src/Grav/Framework/Collection/FileCollection.php create mode 100644 system/src/Grav/Framework/Collection/FileCollectionInterface.php create mode 100644 system/src/Grav/Framework/Compat/Serializable.php create mode 100644 system/src/Grav/Framework/ContentBlock/ContentBlock.php create mode 100644 system/src/Grav/Framework/ContentBlock/ContentBlockInterface.php create mode 100644 system/src/Grav/Framework/ContentBlock/HtmlBlock.php create mode 100644 system/src/Grav/Framework/ContentBlock/HtmlBlockInterface.php create mode 100644 system/src/Grav/Framework/Contracts/Media/MediaObjectInterface.php create mode 100644 system/src/Grav/Framework/Contracts/Object/IdentifierInterface.php create mode 100644 system/src/Grav/Framework/Contracts/Relationships/RelationshipIdentifierInterface.php create mode 100644 system/src/Grav/Framework/Contracts/Relationships/RelationshipInterface.php create mode 100644 system/src/Grav/Framework/Contracts/Relationships/RelationshipsInterface.php create mode 100644 system/src/Grav/Framework/Contracts/Relationships/ToManyRelationshipInterface.php create mode 100644 system/src/Grav/Framework/Contracts/Relationships/ToOneRelationshipInterface.php create mode 100644 system/src/Grav/Framework/Controller/Traits/ControllerResponseTrait.php create mode 100644 system/src/Grav/Framework/DI/Container.php create mode 100644 system/src/Grav/Framework/File/AbstractFile.php create mode 100644 system/src/Grav/Framework/File/CsvFile.php create mode 100644 system/src/Grav/Framework/File/DataFile.php create mode 100644 system/src/Grav/Framework/File/File.php create mode 100644 system/src/Grav/Framework/File/Formatter/AbstractFormatter.php create mode 100644 system/src/Grav/Framework/File/Formatter/CsvFormatter.php create mode 100644 system/src/Grav/Framework/File/Formatter/FormatterInterface.php create mode 100644 system/src/Grav/Framework/File/Formatter/IniFormatter.php create mode 100644 system/src/Grav/Framework/File/Formatter/JsonFormatter.php create mode 100644 system/src/Grav/Framework/File/Formatter/MarkdownFormatter.php create mode 100644 system/src/Grav/Framework/File/Formatter/SerializeFormatter.php create mode 100644 system/src/Grav/Framework/File/Formatter/YamlFormatter.php create mode 100644 system/src/Grav/Framework/File/IniFile.php create mode 100644 system/src/Grav/Framework/File/Interfaces/FileFormatterInterface.php create mode 100644 system/src/Grav/Framework/File/Interfaces/FileInterface.php create mode 100644 system/src/Grav/Framework/File/JsonFile.php create mode 100644 system/src/Grav/Framework/File/MarkdownFile.php create mode 100644 system/src/Grav/Framework/File/YamlFile.php create mode 100644 system/src/Grav/Framework/Filesystem/Filesystem.php create mode 100644 system/src/Grav/Framework/Filesystem/Interfaces/FilesystemInterface.php create mode 100644 system/src/Grav/Framework/Flex/Flex.php create mode 100644 system/src/Grav/Framework/Flex/FlexCollection.php create mode 100644 system/src/Grav/Framework/Flex/FlexDirectory.php create mode 100644 system/src/Grav/Framework/Flex/FlexDirectoryForm.php create mode 100644 system/src/Grav/Framework/Flex/FlexForm.php create mode 100644 system/src/Grav/Framework/Flex/FlexFormFlash.php create mode 100644 system/src/Grav/Framework/Flex/FlexIdentifier.php create mode 100644 system/src/Grav/Framework/Flex/FlexIndex.php create mode 100644 system/src/Grav/Framework/Flex/FlexObject.php create mode 100644 system/src/Grav/Framework/Flex/Interfaces/FlexAuthorizeInterface.php create mode 100644 system/src/Grav/Framework/Flex/Interfaces/FlexCollectionInterface.php create mode 100644 system/src/Grav/Framework/Flex/Interfaces/FlexCommonInterface.php create mode 100644 system/src/Grav/Framework/Flex/Interfaces/FlexDirectoryFormInterface.php create mode 100644 system/src/Grav/Framework/Flex/Interfaces/FlexDirectoryInterface.php create mode 100644 system/src/Grav/Framework/Flex/Interfaces/FlexFormInterface.php create mode 100644 system/src/Grav/Framework/Flex/Interfaces/FlexIndexInterface.php create mode 100644 system/src/Grav/Framework/Flex/Interfaces/FlexInterface.php create mode 100644 system/src/Grav/Framework/Flex/Interfaces/FlexObjectFormInterface.php create mode 100644 system/src/Grav/Framework/Flex/Interfaces/FlexObjectInterface.php create mode 100644 system/src/Grav/Framework/Flex/Interfaces/FlexStorageInterface.php create mode 100644 system/src/Grav/Framework/Flex/Interfaces/FlexTranslateInterface.php create mode 100644 system/src/Grav/Framework/Flex/Pages/FlexPageCollection.php create mode 100644 system/src/Grav/Framework/Flex/Pages/FlexPageIndex.php create mode 100644 system/src/Grav/Framework/Flex/Pages/FlexPageObject.php create mode 100644 system/src/Grav/Framework/Flex/Pages/Traits/PageAuthorsTrait.php create mode 100644 system/src/Grav/Framework/Flex/Pages/Traits/PageContentTrait.php create mode 100644 system/src/Grav/Framework/Flex/Pages/Traits/PageLegacyTrait.php create mode 100644 system/src/Grav/Framework/Flex/Pages/Traits/PageRoutableTrait.php create mode 100644 system/src/Grav/Framework/Flex/Pages/Traits/PageTranslateTrait.php create mode 100644 system/src/Grav/Framework/Flex/Storage/AbstractFilesystemStorage.php create mode 100644 system/src/Grav/Framework/Flex/Storage/FileStorage.php create mode 100644 system/src/Grav/Framework/Flex/Storage/FolderStorage.php create mode 100644 system/src/Grav/Framework/Flex/Storage/SimpleStorage.php create mode 100644 system/src/Grav/Framework/Flex/Traits/FlexAuthorizeTrait.php create mode 100644 system/src/Grav/Framework/Flex/Traits/FlexMediaTrait.php create mode 100644 system/src/Grav/Framework/Flex/Traits/FlexRelatedDirectoryTrait.php create mode 100644 system/src/Grav/Framework/Flex/Traits/FlexRelationshipsTrait.php create mode 100644 system/src/Grav/Framework/Form/FormFlash.php create mode 100644 system/src/Grav/Framework/Form/FormFlashFile.php create mode 100644 system/src/Grav/Framework/Form/Interfaces/FormFactoryInterface.php create mode 100644 system/src/Grav/Framework/Form/Interfaces/FormFlashInterface.php create mode 100644 system/src/Grav/Framework/Form/Interfaces/FormInterface.php create mode 100644 system/src/Grav/Framework/Form/Traits/FormTrait.php create mode 100644 system/src/Grav/Framework/Interfaces/RenderInterface.php create mode 100644 system/src/Grav/Framework/Logger/Processors/UserProcessor.php create mode 100644 system/src/Grav/Framework/Media/Interfaces/MediaCollectionInterface.php create mode 100644 system/src/Grav/Framework/Media/Interfaces/MediaInterface.php create mode 100644 system/src/Grav/Framework/Media/Interfaces/MediaManipulationInterface.php create mode 100644 system/src/Grav/Framework/Media/Interfaces/MediaObjectInterface.php create mode 100644 system/src/Grav/Framework/Media/MediaIdentifier.php create mode 100644 system/src/Grav/Framework/Media/MediaObject.php create mode 100644 system/src/Grav/Framework/Media/UploadedMediaObject.php create mode 100644 system/src/Grav/Framework/Mime/MimeTypes.php create mode 100644 system/src/Grav/Framework/Object/Access/ArrayAccessTrait.php create mode 100644 system/src/Grav/Framework/Object/Access/NestedArrayAccessTrait.php create mode 100644 system/src/Grav/Framework/Object/Access/NestedPropertyCollectionTrait.php create mode 100644 system/src/Grav/Framework/Object/Access/NestedPropertyTrait.php create mode 100644 system/src/Grav/Framework/Object/Access/OverloadedPropertyTrait.php create mode 100644 system/src/Grav/Framework/Object/ArrayObject.php create mode 100644 system/src/Grav/Framework/Object/Base/ObjectCollectionTrait.php create mode 100644 system/src/Grav/Framework/Object/Base/ObjectTrait.php create mode 100644 system/src/Grav/Framework/Object/Collection/ObjectExpressionVisitor.php create mode 100644 system/src/Grav/Framework/Object/Identifiers/Identifier.php create mode 100644 system/src/Grav/Framework/Object/Interfaces/NestedObjectCollectionInterface.php create mode 100644 system/src/Grav/Framework/Object/Interfaces/NestedObjectInterface.php create mode 100644 system/src/Grav/Framework/Object/Interfaces/ObjectCollectionInterface.php create mode 100644 system/src/Grav/Framework/Object/Interfaces/ObjectInterface.php create mode 100644 system/src/Grav/Framework/Object/LazyObject.php create mode 100644 system/src/Grav/Framework/Object/ObjectCollection.php create mode 100644 system/src/Grav/Framework/Object/ObjectIndex.php create mode 100644 system/src/Grav/Framework/Object/Property/ArrayPropertyTrait.php create mode 100644 system/src/Grav/Framework/Object/Property/LazyPropertyTrait.php create mode 100644 system/src/Grav/Framework/Object/Property/MixedPropertyTrait.php create mode 100644 system/src/Grav/Framework/Object/Property/ObjectPropertyTrait.php create mode 100644 system/src/Grav/Framework/Object/PropertyObject.php create mode 100644 system/src/Grav/Framework/Pagination/AbstractPagination.php create mode 100644 system/src/Grav/Framework/Pagination/AbstractPaginationPage.php create mode 100644 system/src/Grav/Framework/Pagination/Interfaces/PaginationInterface.php create mode 100644 system/src/Grav/Framework/Pagination/Interfaces/PaginationPageInterface.php create mode 100644 system/src/Grav/Framework/Pagination/Pagination.php create mode 100644 system/src/Grav/Framework/Pagination/PaginationPage.php create mode 100644 system/src/Grav/Framework/Psr7/AbstractUri.php create mode 100644 system/src/Grav/Framework/Psr7/Request.php create mode 100644 system/src/Grav/Framework/Psr7/Response.php create mode 100644 system/src/Grav/Framework/Psr7/ServerRequest.php create mode 100644 system/src/Grav/Framework/Psr7/Stream.php create mode 100644 system/src/Grav/Framework/Psr7/Traits/MessageDecoratorTrait.php create mode 100644 system/src/Grav/Framework/Psr7/Traits/RequestDecoratorTrait.php create mode 100644 system/src/Grav/Framework/Psr7/Traits/ResponseDecoratorTrait.php create mode 100644 system/src/Grav/Framework/Psr7/Traits/ServerRequestDecoratorTrait.php create mode 100644 system/src/Grav/Framework/Psr7/Traits/StreamDecoratorTrait.php create mode 100644 system/src/Grav/Framework/Psr7/Traits/UploadedFileDecoratorTrait.php create mode 100644 system/src/Grav/Framework/Psr7/Traits/UriDecorationTrait.php create mode 100644 system/src/Grav/Framework/Psr7/UploadedFile.php create mode 100644 system/src/Grav/Framework/Psr7/Uri.php create mode 100644 system/src/Grav/Framework/Relationships/Relationships.php create mode 100644 system/src/Grav/Framework/Relationships/ToManyRelationship.php create mode 100644 system/src/Grav/Framework/Relationships/ToOneRelationship.php create mode 100644 system/src/Grav/Framework/Relationships/Traits/RelationshipTrait.php create mode 100644 system/src/Grav/Framework/RequestHandler/Exception/InvalidArgumentException.php create mode 100644 system/src/Grav/Framework/RequestHandler/Exception/NotFoundException.php create mode 100644 system/src/Grav/Framework/RequestHandler/Exception/NotHandledException.php create mode 100644 system/src/Grav/Framework/RequestHandler/Exception/PageExpiredException.php create mode 100644 system/src/Grav/Framework/RequestHandler/Exception/RequestException.php create mode 100644 system/src/Grav/Framework/RequestHandler/Middlewares/Exceptions.php create mode 100644 system/src/Grav/Framework/RequestHandler/Middlewares/MultipartRequestSupport.php create mode 100644 system/src/Grav/Framework/RequestHandler/RequestHandler.php create mode 100644 system/src/Grav/Framework/RequestHandler/Traits/RequestHandlerTrait.php create mode 100644 system/src/Grav/Framework/Route/Route.php create mode 100644 system/src/Grav/Framework/Route/RouteFactory.php create mode 100644 system/src/Grav/Framework/Session/Exceptions/SessionException.php create mode 100644 system/src/Grav/Framework/Session/Messages.php create mode 100644 system/src/Grav/Framework/Session/Session.php create mode 100644 system/src/Grav/Framework/Session/SessionInterface.php create mode 100644 system/src/Grav/Framework/Uri/Uri.php create mode 100644 system/src/Grav/Framework/Uri/UriFactory.php create mode 100644 system/src/Grav/Framework/Uri/UriPartsFilter.php create mode 100644 system/src/Grav/Installer/Install.php create mode 100644 system/src/Grav/Installer/InstallException.php create mode 100644 system/src/Grav/Installer/VersionUpdate.php create mode 100644 system/src/Grav/Installer/VersionUpdater.php create mode 100644 system/src/Grav/Installer/Versions.php create mode 100644 system/src/Grav/Installer/YamlUpdater.php create mode 100644 system/src/Grav/Installer/updates/1.7.0_2020-11-20_1.php create mode 100644 system/src/Twig/DeferredExtension/DeferredBlockNode.php create mode 100644 system/src/Twig/DeferredExtension/DeferredDeclareNode.php create mode 100644 system/src/Twig/DeferredExtension/DeferredExtension.php create mode 100644 system/src/Twig/DeferredExtension/DeferredInitializeNode.php create mode 100644 system/src/Twig/DeferredExtension/DeferredNode.php create mode 100644 system/src/Twig/DeferredExtension/DeferredNodeVisitor.php create mode 100644 system/src/Twig/DeferredExtension/DeferredNodeVisitorCompat.php create mode 100644 system/src/Twig/DeferredExtension/DeferredResolveNode.php create mode 100644 system/src/Twig/DeferredExtension/DeferredTokenParser.php create mode 100644 system/templates/default.html.twig create mode 100644 system/templates/external.html.twig create mode 100644 system/templates/flex/404.html.twig create mode 100644 system/templates/flex/_default/collection/debug.html.twig create mode 100644 system/templates/flex/_default/object/debug.html.twig create mode 100644 system/templates/modular/default.html.twig create mode 100644 system/templates/partials/messages.html.twig create mode 100644 system/templates/partials/metadata.html.twig create mode 100644 tests/_bootstrap.php create mode 100644 tests/_support/AcceptanceTester.php create mode 100644 tests/_support/FunctionalTester.php create mode 100644 tests/_support/Helper/Acceptance.php create mode 100644 tests/_support/Helper/Functional.php create mode 100644 tests/_support/Helper/Unit.php create mode 100644 tests/_support/UnitTester.php create mode 100644 tests/acceptance.suite.yml create mode 100644 tests/acceptance/_bootstrap.php create mode 100644 tests/fake/nested-site/user/pages/01.item1/01.item1-1/01.item1-1-1/default.md create mode 100644 tests/fake/nested-site/user/pages/01.item1/01.item1-1/02.item1-1-2/default.md create mode 100644 tests/fake/nested-site/user/pages/01.item1/01.item1-1/03.item1-1-3/default.md create mode 100644 tests/fake/nested-site/user/pages/01.item1/01.item1-1/default.md create mode 100644 tests/fake/nested-site/user/pages/01.item1/02.item1-2/01.item1-2-1/default.md create mode 100644 tests/fake/nested-site/user/pages/01.item1/02.item1-2/02.item1-2-2/default.md create mode 100644 tests/fake/nested-site/user/pages/01.item1/02.item1-2/03.item1-2-3/default.md create mode 100644 tests/fake/nested-site/user/pages/01.item1/02.item1-2/default.md create mode 100644 tests/fake/nested-site/user/pages/01.item1/03.item1-3/01.item1-3-1/default.md create mode 100644 tests/fake/nested-site/user/pages/01.item1/03.item1-3/02.item1-3-2/default.md create mode 100644 tests/fake/nested-site/user/pages/01.item1/03.item1-3/03.item1-3-3/default.md create mode 100644 tests/fake/nested-site/user/pages/01.item1/03.item1-3/default.md create mode 100644 tests/fake/nested-site/user/pages/01.item1/default.md create mode 100644 tests/fake/nested-site/user/pages/01.item1/existing-file.zip create mode 100644 tests/fake/nested-site/user/pages/01.item1/home-cache-image.jpg create mode 100644 tests/fake/nested-site/user/pages/01.item1/home-sample-image.jpg create mode 100644 tests/fake/nested-site/user/pages/02.item2/01.item2-1/01.item2-1-1/default.md create mode 100644 tests/fake/nested-site/user/pages/02.item2/01.item2-1/02.item2-1-2/default.md create mode 100644 tests/fake/nested-site/user/pages/02.item2/01.item2-1/03.item2-1-3/default.md create mode 100644 tests/fake/nested-site/user/pages/02.item2/01.item2-1/default.md create mode 100644 tests/fake/nested-site/user/pages/02.item2/02.item2-2/01.item2-2-1/default.md create mode 100644 tests/fake/nested-site/user/pages/02.item2/02.item2-2/02.item2-2-2/default.md create mode 100644 tests/fake/nested-site/user/pages/02.item2/02.item2-2/03.item2-2-3/default.md create mode 100644 tests/fake/nested-site/user/pages/02.item2/02.item2-2/cache-image.jpg create mode 100644 tests/fake/nested-site/user/pages/02.item2/02.item2-2/default.md create mode 100644 tests/fake/nested-site/user/pages/02.item2/02.item2-2/existing-file.zip create mode 100644 tests/fake/nested-site/user/pages/02.item2/02.item2-2/sample-image.jpg create mode 100644 tests/fake/nested-site/user/pages/02.item2/03.item2-3/01.item2-3-1/default.md create mode 100644 tests/fake/nested-site/user/pages/02.item2/03.item2-3/02.item2-3-2/default.md create mode 100644 tests/fake/nested-site/user/pages/02.item2/03.item2-3/03.item2-3-3/default.md create mode 100644 tests/fake/nested-site/user/pages/02.item2/03.item2-3/default.md create mode 100644 tests/fake/nested-site/user/pages/02.item2/default.md create mode 100644 tests/fake/nested-site/user/pages/03.item3/01.item3-1/01.item3-1-1/default.md create mode 100644 tests/fake/nested-site/user/pages/03.item3/01.item3-1/02.item3-1-2/default.md create mode 100644 tests/fake/nested-site/user/pages/03.item3/01.item3-1/03.item3-1-3/default.md create mode 100644 tests/fake/nested-site/user/pages/03.item3/01.item3-1/default.md create mode 100644 tests/fake/nested-site/user/pages/03.item3/02.item3-2/01.item3-2-1/default.md create mode 100644 tests/fake/nested-site/user/pages/03.item3/02.item3-2/02.item3-2-2/default.md create mode 100644 tests/fake/nested-site/user/pages/03.item3/02.item3-2/03.item3-2-3/default.md create mode 100644 tests/fake/nested-site/user/pages/03.item3/02.item3-2/default.md create mode 100644 tests/fake/nested-site/user/pages/03.item3/03.item3-3/01.item3-3-1/default.md create mode 100644 tests/fake/nested-site/user/pages/03.item3/03.item3-3/02.item3-3-2/default.md create mode 100644 tests/fake/nested-site/user/pages/03.item3/03.item3-3/03.item3-3-3/default.md create mode 100644 tests/fake/nested-site/user/pages/03.item3/03.item3-3/default.md create mode 100644 tests/fake/nested-site/user/pages/03.item3/default.md create mode 100644 tests/fake/simple-site/user/pages/01.home/default.md create mode 100644 tests/fake/simple-site/user/pages/02.blog/blog.md create mode 100644 tests/fake/simple-site/user/pages/02.blog/post-one/item.md create mode 100644 tests/fake/simple-site/user/pages/02.blog/post-two/item.md create mode 100644 tests/fake/simple-site/user/pages/03.about/default.md create mode 100644 tests/fake/single-pages/01.simple-page/default.md create mode 100644 tests/functional.suite.yml create mode 100644 tests/functional/Grav/Console/DirectInstallCommandTest.php create mode 100644 tests/functional/_bootstrap.php create mode 100644 tests/unit.suite.yml create mode 100644 tests/unit/Grav/Common/AssetsTest.php create mode 100644 tests/unit/Grav/Common/BrowserTest.php create mode 100644 tests/unit/Grav/Common/ComposerTest.php create mode 100644 tests/unit/Grav/Common/GPM/GPMTest.php create mode 100644 tests/unit/Grav/Common/Helpers/ExcerptsTest.php create mode 100644 tests/unit/Grav/Common/InflectorTest.php create mode 100644 tests/unit/Grav/Common/Language/LanguageCodesTest.php create mode 100644 tests/unit/Grav/Common/Markdown/ParsedownTest.php create mode 100644 tests/unit/Grav/Common/Page/PagesTest.php create mode 100644 tests/unit/Grav/Common/Twig/TwigExtensionTest.php create mode 100644 tests/unit/Grav/Common/UriTest.php create mode 100644 tests/unit/Grav/Common/UtilsTest.php create mode 100644 tests/unit/Grav/Console/Gpm/InstallCommandTest.php create mode 100644 tests/unit/_bootstrap.php create mode 100644 tmp/.gitkeep create mode 100644 tmp/forms/2b5he3159ovn9belhv6c341ghj/04c43184876809253b97f0a5a5864a3d/index.yaml create mode 100644 user/accounts/.gitkeep create mode 100644 user/config/media.yaml create mode 100644 user/config/plugins/youtube.yaml create mode 100644 user/config/site.yaml create mode 100644 user/config/streams.yaml create mode 100644 user/config/system.yaml create mode 100644 user/config/versions.yaml create mode 100644 user/data/.gitkeep create mode 100644 user/pages/01.home/RectoHD.jpg create mode 100644 user/pages/01.home/_pourquoi-le-style-de-lours/text.md create mode 100644 user/pages/01.home/modular.md create mode 100644 user/pages/02.correction/blog.md create mode 100644 user/pages/03.creation-mise-en-page-impression/blog.md create mode 100644 user/pages/04.nouvelle-section-1/01.secretaire-dedition-et-de-redaction/items.md create mode 100644 user/pages/04.nouvelle-section-1/02.chef-de-projet-print/items.md create mode 100644 user/pages/04.nouvelle-section-1/03.etape-1/etape1.png create mode 100644 user/pages/04.nouvelle-section-1/03.etape-1/item-etapes.md create mode 100644 user/pages/04.nouvelle-section-1/04.etape-2/etape2.png create mode 100644 user/pages/04.nouvelle-section-1/04.etape-2/item-etapes.md create mode 100644 user/pages/04.nouvelle-section-1/05.etape-3/etape3.png create mode 100644 user/pages/04.nouvelle-section-1/05.etape-3/item-etapes.md create mode 100644 user/pages/04.nouvelle-section-1/06.etape-4/etape4.png create mode 100644 user/pages/04.nouvelle-section-1/06.etape-4/item-etapes.md create mode 100644 user/pages/04.nouvelle-section-1/07.fiabilite/blog.md create mode 100644 user/pages/04.nouvelle-section-1/blog.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/01.kakemonos/Kakemonos_Solifap.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/01.kakemonos/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/02.4-depliants-de-mobilisation-3-volets-99-x-210-mm/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/02.4-depliants-de-mobilisation-3-volets-99-x-210-mm/montage_depliants_SC.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/03.affiche-danimation-reseau-40-x-60-cm/Affiche_APF_DEF.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/03.affiche-danimation-reseau-40-x-60-cm/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/04.affiche-de-spectacle-40-x-60-cm-tickets-dentree/Affiche_danceline.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/04.affiche-de-spectacle-40-x-60-cm-tickets-dentree/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/05.affiche-destinations-40-x-60-cm/Affiche_AFS.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/05.affiche-destinations-40-x-60-cm/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/06.brochure-taxe-dapprentissage-20-pages-a4/Plaquette CRP 2021_C3.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/06.brochure-taxe-dapprentissage-20-pages-a4/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/07.collection-de-guides-metier-a5-16-24-pages/GuideAlliancy_DefisNouveauMonde_RelationITMetier_Atlassian_Valiantys-1.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/07.collection-de-guides-metier-a5-16-24-pages/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/08.depliants-dechantillons-a4-2-3-ou-4-volets-quadri/IMG_2368_CTN.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/08.depliants-dechantillons-a4-2-3-ou-4-volets-quadri/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/09.dossier-numerique-de-presentation-strategie-de-marque/Wild_Bed_Presentation.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/09.dossier-numerique-de-presentation-strategie-de-marque/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/10.enveloppe-a-fenetre-229-x-324-mm-mecanisable/UAE_enveloppe_2019.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/10.enveloppe-a-fenetre-229-x-324-mm-mecanisable/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/11.etude-sociologique-a4-52-pages-quadri/RAAction_Enfance.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/11.etude-sociologique-a4-52-pages-quadri/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/12.exposition-11-panneaux-rigides-60-x-160-cm/Expo_jamboree_site.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/12.exposition-11-panneaux-rigides-60-x-160-cm/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/13.flyer-de-presentation-a5/flyerA5_FEDEEH.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/13.flyer-de-presentation-a5/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/14.identite-visuelle-wild-bed/Wild_Bed_Presentation.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/14.identite-visuelle-wild-bed/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/15.journaux-trimestriels-4-pages-a4/HD_PARTAGE1_V3-1.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/15.journaux-trimestriels-4-pages-a4/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/16.kakemono-80-x-200-cm/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/16.kakemono-80-x-200-cm/kakemono_FEDEEH.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/17.kakemono-800-x-2000-mm/Kakemono_Poissy.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/17.kakemono-800-x-2000-mm/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/18.livre-88-pages/SOPRA_STERIA_Cahier_couv_siteLSO.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/18.livre-88-pages/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/19.livre-de-memoires-148-x-210-mm-280-pages-n-and-b-feuillet-quadri/couv_Cactusdelame.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/19.livre-de-memoires-148-x-210-mm-280-pages-n-and-b-feuillet-quadri/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/20.livre-de-memoires-220-x-180-mm-100-pages-quadri/HD_CouvertureOK_LIVRE DELFOUR.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/20.livre-de-memoires-220-x-180-mm-100-pages-quadri/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/21.livre-de-memoires-680-pages-15-x-22-cm/COUV_Livre_BARDET_V4.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/21.livre-de-memoires-680-pages-15-x-22-cm/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/22.collection-de-livrets-a5-16-24-pages/Oracle_Alliancy.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/22.collection-de-livrets-a5-16-24-pages/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/23.livret-daccompagnement-pour-les-salaries-36-pages-15-x-21-cm/Livret_Colibri_PDF.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/23.livret-daccompagnement-pour-les-salaries-36-pages-15-x-21-cm/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/24.livret-danimation-pour-les-jeunes-56-pages-21-x-15-cm/Livret_Jeune_siteLSO.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/24.livret-danimation-pour-les-jeunes-56-pages-21-x-15-cm/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/25.livret-danimation-reseau-12-pages-15-x-21-cm/VQ_AJT_AFP_siteLSO.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/25.livret-danimation-reseau-12-pages-15-x-21-cm/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/26.livret-danimation-reseau-12-pages-a5/Affiche_APF_DEF.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/26.livret-danimation-reseau-12-pages-a5/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/27.livret-de-presentation-institutionnelle-12-pages-a5/HD_Livret_Benedictines_V8.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/27.livret-de-presentation-institutionnelle-12-pages-a5/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/28.plaquette-dappel-aux-dons-3-volets-a4/Plaquette Massillon v5BD-1.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/28.plaquette-dappel-aux-dons-3-volets-a4/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/29.plaquette-de-presentation-camping-4-pages-a5/Plaquette_camping_WildBed.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/29.plaquette-de-presentation-camping-4-pages-a5/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/30.plaquette-institutionnelle-8-pages-a4/Plaquette_CRP_siteLSO.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/30.plaquette-institutionnelle-8-pages-a4/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/31.livret-pedagogique-32-pages-a5/LivretA5_ouvgroupe_EXE_HD3-1.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/31.livret-pedagogique-32-pages-a5/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/32.affiche-60-x-80-cm/affiche_AFS_cartedumonde_v13.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/32.affiche-60-x-80-cm/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/33.livret-de-formation-36-pages-a5/Secours_catholique.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/33.livret-de-formation-36-pages-a5/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/34.rapport-dactivite-52-pages-a4/RA SC Paris 2017_V6-1.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/34.rapport-dactivite-52-pages-a4/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/35.plaquette-institutionnelle-4-pages-a4/SIGNAL_HD-1.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/35.plaquette-institutionnelle-4-pages-a4/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/36.rapports-dactivite-60-pages-a4/RA_Solifap2018.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/36.rapports-dactivite-60-pages-a4/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/37.depliant-institutionnel-3-volets-99-x-210-mm/depliant-v12_IMP_HD-1.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/37.depliant-institutionnel-3-volets-99-x-210-mm/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/38.rapport-annuel-2021-32-pages-a4/RA_Colibri_siteLSO.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/38.rapport-annuel-2021-32-pages-a4/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/39.rapport-annuel-2021-64-pages-a4/COUV_RA_CSUD_siteLSO.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/39.rapport-annuel-2021-64-pages-a4/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/40.rapport-sociologique-a4-54-pages-quadri/Rapport_ASE_LEPPI_V3_TBD.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/40.rapport-sociologique-a4-54-pages-quadri/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/41.plan-strategique-20-pages-a4/Plan_strategique_SOLIFAP.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/41.plan-strategique-20-pages-a4/item.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/blog.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/projet-n-2/LivretA5_ouvgroupe_EXE_HD3-1.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/projet-n-2/items.md create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/projet-n-3/affiche_AFS_cartedumonde_v13.jpg create mode 100644 user/pages/05.nouvelle-section-2/01.sous-section-2-1/projet-n-3/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/02.aude-cliente-sociologue/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/02.aude-cliente-sociologue/linkedin-red.svg create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/03.caroline-cliente-resp-communication/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/03.caroline-cliente-resp-communication/linkedin-red.svg create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/04.catherine-graphiste/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/04.catherine-graphiste/linkedin-red.svg create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/05.eric-photographe/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/05.eric-photographe/linkedin-red.svg create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/06.francoise-cliente-particuliere/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/06.francoise-cliente-particuliere/oral-red.svg create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/07.isabelle-graphiste/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/07.isabelle-graphiste/linkedin-red.svg create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/08.jean-francois-client-particulier/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/08.jean-francois-client-particulier/oral-red.svg create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/09.jean-luc-imprimeur/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/09.jean-luc-imprimeur/linkedin-red.svg create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/10.lionel-imprimeur/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/10.lionel-imprimeur/linkedin-red.svg create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/11.ludovic-client/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/11.ludovic-client/malt-red.svg create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/12.antoine-client/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/12.antoine-client/malt-red.svg create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/13.antoine-ex-responsable-hierarchique/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/13.antoine-ex-responsable-hierarchique/linkedin-red.svg create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/14.philippe-ex-collegue-commanditaire/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/14.philippe-ex-collegue-commanditaire/linkedin-red.svg create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/15.philippe-ex-responsable-hierarchique/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/15.philippe-ex-responsable-hierarchique/linkedin-red.svg create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/16.virginie-cliente-biographe/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/16.virginie-cliente-biographe/linkedin-red.svg create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/anne-sophie-ex-collegue-commanditaire/item.md create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/anne-sophie-ex-collegue-commanditaire/linkedin-red.svg create mode 100644 user/pages/05.nouvelle-section-2/02.recommandations/blog.md create mode 100644 user/pages/05.nouvelle-section-2/03.clients/Alliancy.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/Colas.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/Csud.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/Danceline_2.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/Diocese_du_Mans.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/EetD.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/FSEF.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/Forus_OK.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/FroidNews_2.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/Kaolin.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/LOGO_Action_enfance.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/LOGO_LEPPI.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/Logo Groupe CTN.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/LogoINIRR.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/Logo_Benedictines_Vanves.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/Logo_Colibri.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/SGDF_OK.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/Wild_Bed.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/blog.md create mode 100644 user/pages/05.nouvelle-section-2/03.clients/extreme_OK.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/logo-carre_5Painset2poissons.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/logo-carre_ACI.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/logo-carre_AFS.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/logo-carre_APF.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/logo-carre_Caritas-France.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/logo-carre_Massillon.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/logo-carre_Signal-Expertise.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/logo-carre_laFedeeh.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/logo-carre_solifap.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/logo_CMCPM_site_LSO.jpg create mode 100644 user/pages/05.nouvelle-section-2/03.clients/particuliersOK2.jpg create mode 100644 user/pages/05.nouvelle-section-2/blog.md create mode 100644 user/pages/06.contact/01.profil/EC_BD_modif.png create mode 100644 user/pages/06.contact/01.profil/facebook-red.svg create mode 100644 user/pages/06.contact/01.profil/items.md create mode 100644 user/pages/06.contact/01.profil/linkedin-red.svg create mode 100644 user/pages/06.contact/02.profil-2/items.md create mode 100644 user/pages/06.contact/EC_BD_modif.png create mode 100644 user/pages/06.contact/blog.md create mode 100644 user/pages/07.pied-de-page/conditions-generales-des-services/blog.md create mode 100644 user/pages/07.pied-de-page/mentions-legales/blog.md create mode 100644 user/pages/07.pied-de-page/modular.md create mode 100644 user/plugins/.gitkeep create mode 100644 user/themes/.gitkeep create mode 100644 user/themes/le_style_de_lours_modif/.gitignore create mode 100644 user/themes/le_style_de_lours_modif/CHANGELOG.md create mode 100644 user/themes/le_style_de_lours_modif/LICENSE create mode 100644 user/themes/le_style_de_lours_modif/README.md create mode 100644 user/themes/le_style_de_lours_modif/assets/quark-screenshots.jpg create mode 100644 user/themes/le_style_de_lours_modif/blueprints.yaml create mode 100644 user/themes/le_style_de_lours_modif/blueprints/blog.yaml create mode 100644 user/themes/le_style_de_lours_modif/blueprints/default.yaml create mode 100644 user/themes/le_style_de_lours_modif/blueprints/item.yaml create mode 100644 user/themes/le_style_de_lours_modif/blueprints/modular/features.yaml create mode 100644 user/themes/le_style_de_lours_modif/blueprints/modular/hero.yaml create mode 100644 user/themes/le_style_de_lours_modif/blueprints/modular/text.yaml create mode 100644 user/themes/le_style_de_lours_modif/blueprints/partials/blog-bits.yaml create mode 100644 user/themes/le_style_de_lours_modif/css-compiled/spectre-exp.css create mode 100644 user/themes/le_style_de_lours_modif/css-compiled/spectre-exp.min.css create mode 100644 user/themes/le_style_de_lours_modif/css-compiled/spectre-icons.css create mode 100644 user/themes/le_style_de_lours_modif/css-compiled/spectre-icons.min.css create mode 100644 user/themes/le_style_de_lours_modif/css-compiled/spectre.css create mode 100644 user/themes/le_style_de_lours_modif/css-compiled/spectre.min.css create mode 100644 user/themes/le_style_de_lours_modif/css-compiled/theme.css create mode 100644 user/themes/le_style_de_lours_modif/css-compiled/theme.css.map create mode 100644 user/themes/le_style_de_lours_modif/css-compiled/theme.min.css create mode 100644 user/themes/le_style_de_lours_modif/css-compiled/theme.min.css.map create mode 100644 user/themes/le_style_de_lours_modif/css/bricklayer.css create mode 100644 user/themes/le_style_de_lours_modif/css/custom.css create mode 100644 user/themes/le_style_de_lours_modif/css/jquery.mCustomScrollbar.css create mode 100644 user/themes/le_style_de_lours_modif/css/line-awesome.min.css create mode 100644 user/themes/le_style_de_lours_modif/css/owl.carousel.min.css create mode 100644 user/themes/le_style_de_lours_modif/css/owl.theme.default.min.css create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/leaguegothic-condensed-italic-webfont.eot create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/leaguegothic-condensed-italic-webfont.svg create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/leaguegothic-condensed-italic-webfont.ttf create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/leaguegothic-condensed-italic-webfont.woff create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/leaguegothic-condensed-regular-webfont.eot create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/leaguegothic-condensed-regular-webfont.svg create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/leaguegothic-condensed-regular-webfont.ttf create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/leaguegothic-condensed-regular-webfont.woff create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/leaguegothic-italic-webfont.eot create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/leaguegothic-italic-webfont.svg create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/leaguegothic-italic-webfont.ttf create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/leaguegothic-italic-webfont.woff create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/leaguegothic-regular-webfont.eot create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/leaguegothic-regular-webfont.svg create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/leaguegothic-regular-webfont.ttf create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/leaguegothic-regular-webfont.woff create mode 100644 user/themes/le_style_de_lours_modif/fonts/League_gothic/stylesheet.css create mode 100644 user/themes/le_style_de_lours_modif/fonts/line-awesome.eot create mode 100644 user/themes/le_style_de_lours_modif/fonts/line-awesome.svg create mode 100644 user/themes/le_style_de_lours_modif/fonts/line-awesome.ttf create mode 100644 user/themes/le_style_de_lours_modif/fonts/line-awesome.woff create mode 100644 user/themes/le_style_de_lours_modif/fonts/line-awesome.woff2 create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Bold-webfont.eot create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Bold-webfont.svg create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Bold-webfont.ttf create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Bold-webfont.woff create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-BoldItalic-webfont.eot create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-BoldItalic-webfont.svg create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-BoldItalic-webfont.ttf create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-BoldItalic-webfont.woff create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Italic-webfont.eot create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Italic-webfont.svg create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Italic-webfont.ttf create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Italic-webfont.woff create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Light-webfont.eot create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Light-webfont.svg create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Light-webfont.ttf create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Light-webfont.woff create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Medium-webfont.eot create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Medium-webfont.svg create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Medium-webfont.ttf create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Medium-webfont.woff create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-MediumItalic-webfont.eot create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-MediumItalic-webfont.svg create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-MediumItalic-webfont.ttf create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-MediumItalic-webfont.woff create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Regular-webfont.eot create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Regular-webfont.svg create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Regular-webfont.ttf create mode 100644 user/themes/le_style_de_lours_modif/fonts/roboto/Roboto-Regular-webfont.woff create mode 100644 user/themes/le_style_de_lours_modif/gulpfile.js create mode 100644 user/themes/le_style_de_lours_modif/images/favicon.png create mode 100644 user/themes/le_style_de_lours_modif/images/grav-logo.svg create mode 100644 user/themes/le_style_de_lours_modif/js/bricklayer.min.js create mode 100644 user/themes/le_style_de_lours_modif/js/jquery-1.10.2.js create mode 100644 user/themes/le_style_de_lours_modif/js/jquery.mCustomScrollbar.js create mode 100644 user/themes/le_style_de_lours_modif/js/jquery.treemenu.js create mode 100644 user/themes/le_style_de_lours_modif/js/owl.carousel.min.js create mode 100644 user/themes/le_style_de_lours_modif/js/scopedQuerySelectorShim.min.js create mode 100644 user/themes/le_style_de_lours_modif/js/scritps.js create mode 100644 user/themes/le_style_de_lours_modif/js/singlepagenav.min.js create mode 100644 user/themes/le_style_de_lours_modif/js/site.js create mode 100644 user/themes/le_style_de_lours_modif/js/smooth-scroll.min.js create mode 100644 user/themes/le_style_de_lours_modif/languages.yaml create mode 100644 user/themes/le_style_de_lours_modif/le_style_de_lours_modif.php create mode 100644 user/themes/le_style_de_lours_modif/le_style_de_lours_modif.yaml create mode 100644 user/themes/le_style_de_lours_modif/package-lock.json create mode 100644 user/themes/le_style_de_lours_modif/package.json create mode 100644 user/themes/le_style_de_lours_modif/screenshot.jpg create mode 100644 user/themes/le_style_de_lours_modif/scss/theme.scss create mode 100644 user/themes/le_style_de_lours_modif/scss/theme/_animation.scss create mode 100644 user/themes/le_style_de_lours_modif/scss/theme/_carousel.scss create mode 100644 user/themes/le_style_de_lours_modif/scss/theme/_fonts.scss create mode 100644 user/themes/le_style_de_lours_modif/scss/theme/_footer.scss create mode 100644 user/themes/le_style_de_lours_modif/scss/theme/_header.scss create mode 100644 user/themes/le_style_de_lours_modif/scss/theme/_media-quieries.scss create mode 100644 user/themes/le_style_de_lours_modif/scss/theme/_menu.scss create mode 100644 user/themes/le_style_de_lours_modif/scss/theme/_mixins.scss create mode 100644 user/themes/le_style_de_lours_modif/scss/theme/_mobile.scss create mode 100644 user/themes/le_style_de_lours_modif/scss/theme/_reset.scss create mode 100644 user/themes/le_style_de_lours_modif/scss/theme/_start.scss create mode 100644 user/themes/le_style_de_lours_modif/scss/theme/_typography.scss create mode 100644 user/themes/le_style_de_lours_modif/scss/theme/_variables.scss create mode 100644 user/themes/le_style_de_lours_modif/templates/blog.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/default.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/error.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/forms/fields/checkbox/checkbox.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/forms/fields/checkboxes/checkboxes.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/forms/fields/radio/radio.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/forms/fields/switch/switch.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/item-etapes.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/item.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/items.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/macros/macros.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/modular.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/modular/features.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/modular/hero.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/modular/text.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/archives.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/base.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/blog-item.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/blog-list-item.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/blog/date.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/blog/page-summary.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/blog/taxonomy.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/blog/title.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/footer.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/form-messages.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/hero.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/layout.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/login-status.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/logo.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/messages.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/navigation.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/no-gal.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/relatedpages.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/sidebar.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/sous-gal.html.twig create mode 100644 user/themes/le_style_de_lours_modif/templates/partials/taxonomylist.html.twig create mode 100644 user/themes/le_style_de_lours_modif/thumbnail.jpg create mode 100644 user/themes/le_style_de_lours_modif/yarn.lock create mode 100644 webserver-configs/Caddyfile create mode 100644 webserver-configs/Caddyfile-0.8.x create mode 100644 webserver-configs/htaccess.txt create mode 100644 webserver-configs/lighttpd.conf create mode 100644 webserver-configs/nginx.conf create mode 100644 webserver-configs/web.config diff --git a/.dependencies b/.dependencies new file mode 100644 index 0000000..86f4a79 --- /dev/null +++ b/.dependencies @@ -0,0 +1,34 @@ +git: + problems: + url: https://github.com/getgrav/grav-plugin-problems + path: user/plugins/problems + branch: master + error: + url: https://github.com/getgrav/grav-plugin-error + path: user/plugins/error + branch: master + markdown-notices: + url: https://github.com/getgrav/grav-plugin-markdown-notices + path: user/plugins/markdown-notices + branch: master + quark: + url: https://github.com/getgrav/grav-theme-quark + path: user/themes/quark + branch: master +links: + problems: + src: grav-plugin-problems + path: user/plugins/problems + scm: github + error: + src: grav-plugin-error + path: user/plugins/error + scm: github + markdown-notices: + src: grav-plugin-markdown-notices + path: user/plugins/markdown-notices + scm: github + quark: + src: grav-theme-quark + path: user/themes/quark + scm: github diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..685c063 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +charset = utf-8 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 4 + +# 2 space indentation +[*.yaml, *.yml] +indent_style = space +indent_size = 2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..366e1fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,43 @@ +# Composer +.composer +vendor/* +!*/vendor/* + +# Sass +.sass-cache + +# Grav Specific +backup/* +!backup/.* +cache/* +!cache/.* +assets/* +!assets/.* +logs/* +!logs/.* +images/* +!images/.* +user/accounts/* +!user/accounts/.* +user/data/* +!user/data/.* +user/plugins/* +!user/plugins/.* +user/localhost/config/security.yaml +user/config/security.yaml + +# OS Generated +.DS_Store* +ehthumbs.db +Icon? +Thumbs.db +*.swp + +# phpstorm +.idea/* + +tests/_output/* +tests/_support/_generated/* +tests/cache/* +tests/error.log +/system/templates/testing diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..9b61c48 --- /dev/null +++ b/.htaccess @@ -0,0 +1,75 @@ + + +RewriteEngine On + +## Begin RewriteBase +# If you are getting 500 or 404 errors on subpages, you may have to uncomment the RewriteBase entry +# You should change the '/' to your appropriate subfolder. For example if you have +# your Grav install at the root of your site '/' should work, else it might be something +# along the lines of: RewriteBase / +## + +RewriteBase / + +## End - RewriteBase + +## Begin - X-Forwarded-Proto +# In some hosted or load balanced environments, SSL negotiation happens upstream. +# In order for Grav to recognize the connection as secure, you need to uncomment +# the following lines. +# +# RewriteCond %{HTTP:X-Forwarded-Proto} https +# RewriteRule .* - [E=HTTPS:on] +# +## End - X-Forwarded-Proto + +## Begin - Exploits +# If you experience problems on your site block out the operations listed below +# This attempts to block the most common type of exploit `attempts` to Grav +# +# Block out any script trying to base64_encode data within the URL. +RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR] +# Block out any script that includes a \n"; + } +} diff --git a/system/src/Grav/Common/Assets/InlineJsModule.php b/system/src/Grav/Common/Assets/InlineJsModule.php new file mode 100644 index 0000000..17aada4 --- /dev/null +++ b/system/src/Grav/Common/Assets/InlineJsModule.php @@ -0,0 +1,46 @@ + 'js_module', + 'attributes' => ['type' => 'module'], + 'position' => 'after' + ]; + + $merged_attributes = Utils::arrayMergeRecursiveUnique($base_options, $elements); + + parent::__construct($merged_attributes, $key); + } + + /** + * @return string + */ + public function render() + { + return 'renderAttributes(). ">\n" . trim($this->asset) . "\n\n"; + } + +} diff --git a/system/src/Grav/Common/Assets/Js.php b/system/src/Grav/Common/Assets/Js.php new file mode 100644 index 0000000..a66b059 --- /dev/null +++ b/system/src/Grav/Common/Assets/Js.php @@ -0,0 +1,48 @@ + 'js', + ]; + + $merged_attributes = Utils::arrayMergeRecursiveUnique($base_options, $elements); + + parent::__construct($merged_attributes, $key); + } + + /** + * @return string + */ + public function render() + { + if (isset($this->attributes['loading']) && $this->attributes['loading'] === 'inline') { + $buffer = $this->gatherLinks([$this], self::JS_ASSET); + return 'renderAttributes() . ">\n" . trim($buffer) . "\n\n"; + } + + return '\n"; + } +} diff --git a/system/src/Grav/Common/Assets/JsModule.php b/system/src/Grav/Common/Assets/JsModule.php new file mode 100644 index 0000000..55523b0 --- /dev/null +++ b/system/src/Grav/Common/Assets/JsModule.php @@ -0,0 +1,49 @@ + 'js_module', + 'attributes' => ['type' => 'module'] + ]; + + $merged_attributes = Utils::arrayMergeRecursiveUnique($base_options, $elements); + + parent::__construct($merged_attributes, $key); + } + + /** + * @return string + */ + public function render() + { + if (isset($this->attributes['loading']) && $this->attributes['loading'] === 'inline') { + $buffer = $this->gatherLinks([$this], self::JS_MODULE_ASSET); + return 'renderAttributes() . ">\n" . trim($buffer) . "\n\n"; + } + + return '\n"; + } +} diff --git a/system/src/Grav/Common/Assets/Link.php b/system/src/Grav/Common/Assets/Link.php new file mode 100644 index 0000000..f60ee64 --- /dev/null +++ b/system/src/Grav/Common/Assets/Link.php @@ -0,0 +1,43 @@ + 'link', + ]; + + $merged_attributes = Utils::arrayMergeRecursiveUnique($base_options, $elements); + + parent::__construct($merged_attributes, $key); + } + + /** + * @return string + */ + public function render() + { + return 'renderAttributes() . $this->integrityHash($this->asset) . ">\n"; + } +} diff --git a/system/src/Grav/Common/Assets/Pipeline.php b/system/src/Grav/Common/Assets/Pipeline.php new file mode 100644 index 0000000..3fd542e --- /dev/null +++ b/system/src/Grav/Common/Assets/Pipeline.php @@ -0,0 +1,347 @@ +base_url = rtrim($uri->rootUrl($config->get('system.absolute_urls')), '/') . '/'; + $this->assets_dir = $locator->findResource('asset://'); + if (!$this->assets_dir) { + // Attempt to create assets folder if it doesn't exist yet. + $this->assets_dir = $locator->findResource('asset://', true, true); + Folder::mkdir($this->assets_dir); + $locator->clearCache(); + } + + $this->assets_url = $locator->findResource('asset://', false); + } + + /** + * Minify and concatenate CSS + * + * @param array $assets + * @param string $group + * @param array $attributes + * @return bool|string URL or generated content if available, else false + */ + public function renderCss($assets, $group, $attributes = []) + { + // temporary list of assets to pipeline + $inline_group = false; + + if (array_key_exists('loading', $attributes) && $attributes['loading'] === 'inline') { + $inline_group = true; + unset($attributes['loading']); + } + + // Store Attributes + $this->attributes = array_merge(['type' => 'text/css', 'rel' => 'stylesheet'], $attributes); + + // Compute uid based on assets and timestamp + $json_assets = json_encode($assets); + $uid = md5($json_assets . (int)$this->css_minify . (int)$this->css_rewrite . $group); + $file = $uid . '.css'; + $relative_path = "{$this->base_url}{$this->assets_url}/{$file}"; + + $filepath = "{$this->assets_dir}/{$file}"; + if (file_exists($filepath)) { + $buffer = file_get_contents($filepath) . "\n"; + } else { + //if nothing found get out of here! + if (empty($assets)) { + return false; + } + + // Concatenate files + $buffer = $this->gatherLinks($assets, self::CSS_ASSET); + + // Minify if required + if ($this->shouldMinify('css')) { + $minifier = new CSS(); + $minifier->add($buffer); + $buffer = $minifier->minify(); + } + + // Write file + if (trim($buffer) !== '') { + file_put_contents($filepath, $buffer); + } + } + + if ($inline_group) { + $output = "\n"; + } else { + $this->asset = $relative_path; + $output = 'renderAttributes() . BaseAsset::integrityHash($this->asset) . ">\n"; + } + + return $output; + } + + /** + * Minify and concatenate JS files. + * + * @param array $assets + * @param string $group + * @param array $attributes + * @return bool|string URL or generated content if available, else false + */ + public function renderJs($assets, $group, $attributes = [], $type = self::JS_ASSET) + { + // temporary list of assets to pipeline + $inline_group = false; + + if (array_key_exists('loading', $attributes) && $attributes['loading'] === 'inline') { + $inline_group = true; + unset($attributes['loading']); + } + + // Store Attributes + $this->attributes = $attributes; + + // Compute uid based on assets and timestamp + $json_assets = json_encode($assets); + $uid = md5($json_assets . $this->js_minify . $group); + $file = $uid . '.js'; + $relative_path = "{$this->base_url}{$this->assets_url}/{$file}"; + + $filepath = "{$this->assets_dir}/{$file}"; + if (file_exists($filepath)) { + $buffer = file_get_contents($filepath) . "\n"; + } else { + //if nothing found get out of here! + if (empty($assets)) { + return false; + } + + // Concatenate files + $buffer = $this->gatherLinks($assets, $type); + + // Minify if required + if ($this->shouldMinify('js')) { + $minifier = new JS(); + $minifier->add($buffer); + $buffer = $minifier->minify(); + } + + // Write file + if (trim($buffer) !== '') { + file_put_contents($filepath, $buffer); + } + } + + if ($inline_group) { + $output = 'renderAttributes(). ">\n" . $buffer . "\n\n"; + } else { + $this->asset = $relative_path; + $output = '\n"; + } + + return $output; + } + + /** + * Minify and concatenate JS files. + * + * @param array $assets + * @param string $group + * @param array $attributes + * @return bool|string URL or generated content if available, else false + */ + public function renderJs_Module($assets, $group, $attributes = []) + { + $attributes['type'] = 'module'; + return $this->renderJs($assets, $group, $attributes, self::JS_MODULE_ASSET); + } + + /** + * Finds relative CSS urls() and rewrites the URL with an absolute one + * + * @param string $file the css source file + * @param string $dir , $local relative path to the css file + * @param bool $local is this a local or remote asset + * @return string + */ + protected function cssRewrite($file, $dir, $local) + { + // Strip any sourcemap comments + $file = preg_replace(self::CSS_SOURCEMAP_REGEX, '', $file); + + // Find any css url() elements, grab the URLs and calculate an absolute path + // Then replace the old url with the new one + $file = (string)preg_replace_callback(self::CSS_URL_REGEX, function ($matches) use ($dir, $local) { + $isImport = count($matches) > 3 && $matches[3] === '@import'; + + if ($isImport) { + $old_url = $matches[5]; + } else { + $old_url = $matches[2]; + } + + // Ensure link is not rooted to web server, a data URL, or to a remote host + if (preg_match(self::FIRST_FORWARDSLASH_REGEX, $old_url) || Utils::startsWith($old_url, 'data:') || $this->isRemoteLink($old_url)) { + return $matches[0]; + } + + // clean leading / + $old_url = Utils::normalizePath($dir . '/' . $old_url); + if (preg_match(self::FIRST_FORWARDSLASH_REGEX, $old_url)) { + $old_url = ltrim($old_url, '/'); + } + + $new_url = ($local ? $this->base_url : '') . $old_url; + + if ($isImport) { + return str_replace($matches[5], $new_url, $matches[0]); + } else { + return str_replace($matches[2], $new_url, $matches[0]); + } + }, $file); + + return $file; + } + + /** + * Finds relative JS urls() and rewrites the URL with an absolute one + * + * @param string $file the css source file + * @param string $dir local relative path to the css file + * @param bool $local is this a local or remote asset + * @return string + */ + protected function jsRewrite($file, $dir, $local) + { + // Find any js import elements, grab the URLs and calculate an absolute path + // Then replace the old url with the new one + $file = (string)preg_replace_callback(self::JS_IMPORT_REGEX, function ($matches) use ($dir, $local) { + + $old_url = $matches[1]; + + // Ensure link is not rooted to web server, a data URL, or to a remote host + if (preg_match(self::FIRST_FORWARDSLASH_REGEX, $old_url) || $this->isRemoteLink($old_url)) { + return $matches[0]; + } + + // clean leading / + $old_url = Utils::normalizePath($dir . '/' . $old_url); + $old_url = str_replace('/./', '/', $old_url); + if (preg_match(self::FIRST_FORWARDSLASH_REGEX, $old_url)) { + $old_url = ltrim($old_url, '/'); + } + + $new_url = ($local ? $this->base_url : '') . $old_url; + + return str_replace($matches[1], $new_url, $matches[0]); + }, $file); + + return $file; + } + + /** + * @param string $type + * @return bool + */ + private function shouldMinify($type = 'css') + { + $check = $type . '_minify'; + $win_check = $type . '_minify_windows'; + + $minify = (bool) $this->$check; + + // If this is a Windows server, and minify_windows is false (default value) skip the + // minification process because it will cause Apache to die/crash due to insufficient + // ThreadStackSize in httpd.conf - See: https://bugs.php.net/bug.php?id=47689 + if (stripos(php_uname('s'), 'WIN') === 0 && !$this->{$win_check}) { + $minify = false; + } + + return $minify; + } +} diff --git a/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php b/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php new file mode 100644 index 0000000..874633f --- /dev/null +++ b/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php @@ -0,0 +1,215 @@ +rootUrl(true); + + // Sanity check for local URLs with absolute URL's enabled + if (Utils::startsWith($link, $base)) { + return false; + } + + return (0 === strpos($link, 'http://') || 0 === strpos($link, 'https://') || 0 === strpos($link, '//')); + } + + /** + * Download and concatenate the content of several links. + * + * @param array $assets + * @param int $type + * @return string + */ + protected function gatherLinks(array $assets, int $type = self::CSS_ASSET): string + { + $buffer = ''; + foreach ($assets as $asset) { + $local = true; + + $link = $asset->getAsset(); + $relative_path = $link; + + if (static::isRemoteLink($link)) { + $local = false; + if (0 === strpos($link, '//')) { + $link = 'http:' . $link; + } + $relative_dir = dirname($relative_path); + } else { + // Fix to remove relative dir if grav is in one + if (($this->base_url !== '/') && Utils::startsWith($relative_path, $this->base_url)) { + $base_url = '#' . preg_quote($this->base_url, '#') . '#'; + $relative_path = ltrim(preg_replace($base_url, '/', $link, 1), '/'); + } + + $relative_dir = dirname($relative_path); + $link = GRAV_ROOT . '/' . $relative_path; + } + + // TODO: looks like this is not being used. + $file = $this->fetch_command instanceof Closure ? @$this->fetch_command->__invoke($link) : @file_get_contents($link); + + // No file found, skip it... + if ($file === false) { + continue; + } + + // Double check last character being + if ($type === self::JS_ASSET || $type === self::JS_MODULE_ASSET) { + $file = rtrim($file, ' ;') . ';'; + } + + // If this is CSS + the file is local + rewrite enabled + if ($type === self::CSS_ASSET && $this->css_rewrite) { + $file = $this->cssRewrite($file, $relative_dir, $local); + } + + if ($type === self::JS_MODULE_ASSET) { + $file = $this->jsRewrite($file, $relative_dir, $local); + } + + $file = rtrim($file) . PHP_EOL; + $buffer .= $file; + } + + // Pull out @imports and move to top + if ($type === self::CSS_ASSET) { + $buffer = $this->moveImports($buffer); + } + + return $buffer; + } + + /** + * Moves @import statements to the top of the file per the CSS specification + * + * @param string $file the file containing the combined CSS files + * @return string the modified file with any @imports at the top of the file + */ + protected function moveImports($file) + { + $regex = '{@import.*?["\']([^"\']+)["\'].*?;}'; + + $imports = []; + + $file = (string)preg_replace_callback($regex, static function ($matches) use (&$imports) { + $imports[] = $matches[0]; + + return ''; + }, $file); + + return implode("\n", $imports) . "\n\n" . $file; + } + + /** + * + * Build an HTML attribute string from an array. + * + * @return string + */ + protected function renderAttributes() + { + $html = ''; + $no_key = ['loading']; + + foreach ($this->attributes as $key => $value) { + if ($value === null) { + continue; + } + + if (is_numeric($key)) { + $key = $value; + } + if (is_array($value)) { + $value = implode(' ', $value); + } + + if (in_array($key, $no_key, true)) { + $element = htmlentities($value, ENT_QUOTES, 'UTF-8', false); + } else { + $element = $key . '="' . htmlentities($value, ENT_QUOTES, 'UTF-8', false) . '"'; + } + + $html .= ' ' . $element; + } + + return $html; + } + + /** + * Render Querystring + * + * @param string|null $asset + * @return string + */ + protected function renderQueryString($asset = null) + { + $querystring = ''; + + $asset = $asset ?? $this->asset; + $attributes = $this->attributes; + + if (!empty($this->query)) { + if (Utils::contains($asset, '?')) { + $querystring .= '&' . $this->query; + } else { + $querystring .= '?' . $this->query; + } + } + + if ($this->timestamp) { + if ($querystring || Utils::contains($asset, '?')) { + $querystring .= '&' . $this->timestamp; + } else { + $querystring .= '?' . $this->timestamp; + } + } + + return $querystring; + } +} diff --git a/system/src/Grav/Common/Assets/Traits/LegacyAssetsTrait.php b/system/src/Grav/Common/Assets/Traits/LegacyAssetsTrait.php new file mode 100644 index 0000000..08a59e2 --- /dev/null +++ b/system/src/Grav/Common/Assets/Traits/LegacyAssetsTrait.php @@ -0,0 +1,137 @@ + null, 'pipeline' => true, 'loading' => null, 'group' => null]; + $arguments = $this->createArgumentsFromLegacy($args, $defaults); + break; + + case (Assets::INLINE_JS_TYPE): + $defaults = ['priority' => null, 'group' => null, 'attributes' => null]; + $arguments = $this->createArgumentsFromLegacy($args, $defaults); + + // special case to handle old attributes being passed in + if (isset($arguments['attributes'])) { + $old_attributes = $arguments['attributes']; + if (is_array($old_attributes)) { + $arguments = array_merge($arguments, $old_attributes); + } else { + $arguments['type'] = $old_attributes; + } + } + unset($arguments['attributes']); + + break; + + case (Assets::INLINE_CSS_TYPE): + $defaults = ['priority' => null, 'group' => null]; + $arguments = $this->createArgumentsFromLegacy($args, $defaults); + break; + + default: + case (Assets::CSS_TYPE): + $defaults = ['priority' => null, 'pipeline' => true, 'group' => null, 'loading' => null]; + $arguments = $this->createArgumentsFromLegacy($args, $defaults); + } + + return $arguments; + } + + /** + * @param array $args + * @param array $defaults + * @return array + */ + protected function createArgumentsFromLegacy(array $args, array $defaults) + { + // Remove arguments with old default values. + $arguments = []; + foreach ($args as $arg) { + $default = current($defaults); + if ($arg !== $default) { + $arguments[key($defaults)] = $arg; + } + next($defaults); + } + + return $arguments; + } + + /** + * Convenience wrapper for async loading of JavaScript + * + * @param string|array $asset + * @param int $priority + * @param bool $pipeline + * @param string $group name of the group + * @return Assets + * @deprecated Please use dynamic method with ['loading' => 'async']. + */ + public function addAsyncJs($asset, $priority = 10, $pipeline = true, $group = 'head') + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use dynamic method with [\'loading\' => \'async\']', E_USER_DEPRECATED); + + return $this->addJs($asset, $priority, $pipeline, 'async', $group); + } + + /** + * Convenience wrapper for deferred loading of JavaScript + * + * @param string|array $asset + * @param int $priority + * @param bool $pipeline + * @param string $group name of the group + * @return Assets + * @deprecated Please use dynamic method with ['loading' => 'defer']. + */ + public function addDeferJs($asset, $priority = 10, $pipeline = true, $group = 'head') + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use dynamic method with [\'loading\' => \'defer\']', E_USER_DEPRECATED); + + return $this->addJs($asset, $priority, $pipeline, 'defer', $group); + } +} diff --git a/system/src/Grav/Common/Assets/Traits/TestingAssetsTrait.php b/system/src/Grav/Common/Assets/Traits/TestingAssetsTrait.php new file mode 100644 index 0000000..c264868 --- /dev/null +++ b/system/src/Grav/Common/Assets/Traits/TestingAssetsTrait.php @@ -0,0 +1,350 @@ +collections[$asset]) || isset($this->assets_css[$asset]) || isset($this->assets_js[$asset]); + } + + /** + * Return the array of all the registered collections + * + * @return array + */ + public function getCollections() + { + return $this->collections; + } + + /** + * Set the array of collections explicitly + * + * @param array $collections + * @return $this + */ + public function setCollection($collections) + { + $this->collections = $collections; + + return $this; + } + + /** + * Return the array of all the registered CSS assets + * If a $key is provided, it will try to return only that asset + * else it will return null + * + * @param string|null $key the asset key + * @return array + */ + public function getCss($key = null) + { + if (null !== $key) { + $asset_key = md5($key); + + return $this->assets_css[$asset_key] ?? null; + } + + return $this->assets_css; + } + + /** + * Return the array of all the registered JS assets + * If a $key is provided, it will try to return only that asset + * else it will return null + * + * @param string|null $key the asset key + * @return array + */ + public function getJs($key = null) + { + if (null !== $key) { + $asset_key = md5($key); + + return $this->assets_js[$asset_key] ?? null; + } + + return $this->assets_js; + } + + /** + * Set the whole array of CSS assets + * + * @param array $css + * @return $this + */ + public function setCss($css) + { + $this->assets_css = $css; + + return $this; + } + + /** + * Set the whole array of JS assets + * + * @param array $js + * @return $this + */ + public function setJs($js) + { + $this->assets_js = $js; + + return $this; + } + + /** + * Removes an item from the CSS array if set + * + * @param string $key The asset key + * @return $this + */ + public function removeCss($key) + { + $asset_key = md5($key); + if (isset($this->assets_css[$asset_key])) { + unset($this->assets_css[$asset_key]); + } + + return $this; + } + + /** + * Removes an item from the JS array if set + * + * @param string $key The asset key + * @return $this + */ + public function removeJs($key) + { + $asset_key = md5($key); + if (isset($this->assets_js[$asset_key])) { + unset($this->assets_js[$asset_key]); + } + + return $this; + } + + /** + * Sets the state of CSS Pipeline + * + * @param bool $value + * @return $this + */ + public function setCssPipeline($value) + { + $this->css_pipeline = (bool)$value; + + return $this; + } + + /** + * Sets the state of JS Pipeline + * + * @param bool $value + * @return $this + */ + public function setJsPipeline($value) + { + $this->js_pipeline = (bool)$value; + + return $this; + } + + /** + * Reset all assets. + * + * @return $this + */ + public function reset() + { + $this->resetCss(); + $this->resetJs(); + $this->setCssPipeline(false); + $this->setJsPipeline(false); + $this->order = []; + + return $this; + } + + /** + * Reset JavaScript assets. + * + * @return $this + */ + public function resetJs() + { + $this->assets_js = []; + + return $this; + } + + /** + * Reset CSS assets. + * + * @return $this + */ + public function resetCss() + { + $this->assets_css = []; + + return $this; + } + + /** + * Explicitly set's a timestamp for assets + * + * @param string|int $value + */ + public function setTimestamp($value) + { + $this->timestamp = $value; + } + + /** + * Get the timestamp for assets + * + * @param bool $include_join + * @return string|null + */ + public function getTimestamp($include_join = true) + { + if ($this->timestamp) { + return $include_join ? '?' . $this->timestamp : $this->timestamp; + } + + return null; + } + + /** + * Add all assets matching $pattern within $directory. + * + * @param string $directory Relative to the Grav root path, or a stream identifier + * @param string $pattern (regex) + * @return $this + */ + public function addDir($directory, $pattern = self::DEFAULT_REGEX) + { + $root_dir = GRAV_ROOT; + + // Check if $directory is a stream. + if (strpos($directory, '://')) { + $directory = Grav::instance()['locator']->findResource($directory, null); + } + + // Get files + $files = $this->rglob($root_dir . DIRECTORY_SEPARATOR . $directory, $pattern, $root_dir . '/'); + + // No luck? Nothing to do + if (!$files) { + return $this; + } + + // Add CSS files + if ($pattern === self::CSS_REGEX) { + foreach ($files as $file) { + $this->addCss($file); + } + + return $this; + } + + // Add JavaScript files + if ($pattern === self::JS_REGEX) { + foreach ($files as $file) { + $this->addJs($file); + } + + return $this; + } + + // Add JavaScript Module files + if ($pattern === self::JS_MODULE_REGEX) { + foreach ($files as $file) { + $this->addJsModule($file); + } + + return $this; + } + + // Unknown pattern. + foreach ($files as $asset) { + $this->add($asset); + } + + return $this; + } + + /** + * Add all JavaScript assets within $directory + * + * @param string $directory Relative to the Grav root path, or a stream identifier + * @return $this + */ + public function addDirJs($directory) + { + return $this->addDir($directory, self::JS_REGEX); + } + + /** + * Add all CSS assets within $directory + * + * @param string $directory Relative to the Grav root path, or a stream identifier + * @return $this + */ + public function addDirCss($directory) + { + return $this->addDir($directory, self::CSS_REGEX); + } + + /** + * Recursively get files matching $pattern within $directory. + * + * @param string $directory + * @param string $pattern (regex) + * @param string|null $ltrim Will be trimmed from the left of the file path + * @return array + */ + protected function rglob($directory, $pattern, $ltrim = null) + { + $iterator = new RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator( + $directory, + FilesystemIterator::SKIP_DOTS + )), $pattern); + $offset = strlen($ltrim); + $files = []; + + foreach ($iterator as $file) { + $files[] = substr($file->getPathname(), $offset); + } + + return $files; + } +} diff --git a/system/src/Grav/Common/Backup/Backups.php b/system/src/Grav/Common/Backup/Backups.php new file mode 100644 index 0000000..dd2cf37 --- /dev/null +++ b/system/src/Grav/Common/Backup/Backups.php @@ -0,0 +1,322 @@ +addListener('onSchedulerInitialized', [$this, 'onSchedulerInitialized']); + + $grav->fireEvent('onBackupsInitialized', new Event(['backups' => $this])); + } + + /** + * @return void + */ + public function setup() + { + if (null === static::$backup_dir) { + $grav = Grav::instance(); + static::$backup_dir = $grav['locator']->findResource('backup://', true, true); + Folder::create(static::$backup_dir); + } + } + + /** + * @param Event $event + * @return void + */ + public function onSchedulerInitialized(Event $event) + { + $grav = Grav::instance(); + + /** @var Scheduler $scheduler */ + $scheduler = $event['scheduler']; + + /** @var Inflector $inflector */ + $inflector = $grav['inflector']; + + foreach (static::getBackupProfiles() as $id => $profile) { + $at = $profile['schedule_at']; + $name = $inflector::hyphenize($profile['name']); + $logs = 'logs/backup-' . $name . '.out'; + /** @var Job $job */ + $job = $scheduler->addFunction('Grav\Common\Backup\Backups::backup', [$id], $name); + $job->at($at); + $job->output($logs); + $job->backlink('/tools/backups'); + } + } + + /** + * @param string $backup + * @param string $base_url + * @return string + */ + public function getBackupDownloadUrl($backup, $base_url) + { + $param_sep = Grav::instance()['config']->get('system.param_sep', ':'); + $download = urlencode(base64_encode(Utils::basename($backup))); + $url = rtrim(Grav::instance()['uri']->rootUrl(true), '/') . '/' . trim( + $base_url, + '/' + ) . '/task' . $param_sep . 'backup/download' . $param_sep . $download . '/admin-nonce' . $param_sep . Utils::getNonce('admin-form'); + + return $url; + } + + /** + * @return array + */ + public static function getBackupProfiles() + { + return Grav::instance()['config']->get('backups.profiles'); + } + + /** + * @return array + */ + public static function getPurgeConfig() + { + return Grav::instance()['config']->get('backups.purge'); + } + + /** + * @return array + */ + public function getBackupNames() + { + return array_column(static::getBackupProfiles(), 'name'); + } + + /** + * @return float|int + */ + public static function getTotalBackupsSize() + { + $backups = static::getAvailableBackups(); + + return $backups ? array_sum(array_column($backups, 'size')) : 0; + } + + /** + * @param bool $force + * @return array + */ + public static function getAvailableBackups($force = false) + { + if ($force || null === static::$backups) { + static::$backups = []; + + $grav = Grav::instance(); + $backups_itr = new GlobIterator(static::$backup_dir . '/*.zip', FilesystemIterator::KEY_AS_FILENAME); + $inflector = $grav['inflector']; + $long_date_format = DATE_RFC2822; + + /** + * @var string $name + * @var SplFileInfo $file + */ + foreach ($backups_itr as $name => $file) { + if (preg_match(static::BACKUP_FILENAME_REGEXZ, $name, $matches)) { + $date = DateTime::createFromFormat(static::BACKUP_DATE_FORMAT, $matches[2]); + $timestamp = $date->getTimestamp(); + $backup = new stdClass(); + $backup->title = $inflector->titleize($matches[1]); + $backup->time = $date; + $backup->date = $date->format($long_date_format); + $backup->filename = $name; + $backup->path = $file->getPathname(); + $backup->size = $file->getSize(); + static::$backups[$timestamp] = $backup; + } + } + // Reverse Key Sort to get in reverse date order + krsort(static::$backups); + } + + return static::$backups; + } + + /** + * Backup + * + * @param int $id + * @param callable|null $status + * @return string|null + */ + public static function backup($id = 0, callable $status = null) + { + $grav = Grav::instance(); + + $profiles = static::getBackupProfiles(); + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + + if (isset($profiles[$id])) { + $backup = (object) $profiles[$id]; + } else { + throw new RuntimeException('No backups defined...'); + } + + $name = $grav['inflector']->underscorize($backup->name); + $date = date(static::BACKUP_DATE_FORMAT, time()); + $filename = trim($name, '_') . '--' . $date . '.zip'; + $destination = static::$backup_dir . DS . $filename; + $max_execution_time = ini_set('max_execution_time', '600'); + $backup_root = $backup->root; + + if ($locator->isStream($backup_root)) { + $backup_root = $locator->findResource($backup_root); + } else { + $backup_root = rtrim(GRAV_ROOT . $backup_root, DS) ?: DS; + } + + if (!$backup_root || !file_exists($backup_root)) { + throw new RuntimeException("Backup location: {$backup_root} does not exist..."); + } + + $options = [ + 'exclude_files' => static::convertExclude($backup->exclude_files ?? ''), + 'exclude_paths' => static::convertExclude($backup->exclude_paths ?? ''), + ]; + + $archiver = Archiver::create('zip'); + $archiver->setArchive($destination)->setOptions($options)->compress($backup_root, $status)->addEmptyFolders($options['exclude_paths'], $status); + + $status && $status([ + 'type' => 'message', + 'message' => 'Done...', + ]); + + $status && $status([ + 'type' => 'progress', + 'complete' => true + ]); + + if ($max_execution_time !== false) { + ini_set('max_execution_time', $max_execution_time); + } + + // Log the backup + $grav['log']->notice('Backup Created: ' . $destination); + + // Fire Finished event + $grav->fireEvent('onBackupFinished', new Event(['backup' => $destination])); + + // Purge anything required + static::purge(); + + // Log + $log = JsonFile::instance($locator->findResource("log://backup.log", true, true)); + $log->content([ + 'time' => time(), + 'location' => $destination + ]); + $log->save(); + + return $destination; + } + + /** + * @return void + * @throws Exception + */ + public static function purge() + { + $purge_config = static::getPurgeConfig(); + $trigger = $purge_config['trigger']; + $backups = static::getAvailableBackups(true); + + switch ($trigger) { + case 'number': + $backups_count = count($backups); + if ($backups_count > $purge_config['max_backups_count']) { + $last = end($backups); + unlink($last->path); + static::purge(); + } + break; + + case 'time': + $last = end($backups); + $now = new DateTime(); + $interval = $now->diff($last->time); + if ($interval->days > $purge_config['max_backups_time']) { + unlink($last->path); + static::purge(); + } + break; + + default: + $used_space = static::getTotalBackupsSize(); + $max_space = $purge_config['max_backups_space'] * 1024 * 1024 * 1024; + if ($used_space > $max_space) { + $last = end($backups); + unlink($last->path); + static::purge(); + } + break; + } + } + + /** + * @param string $exclude + * @return array + */ + protected static function convertExclude($exclude) + { + $lines = preg_split("/[\s,]+/", $exclude); + + return array_map('trim', $lines, array_fill(0, count($lines), '/')); + } +} diff --git a/system/src/Grav/Common/Browser.php b/system/src/Grav/Common/Browser.php new file mode 100644 index 0000000..6a92eee --- /dev/null +++ b/system/src/Grav/Common/Browser.php @@ -0,0 +1,153 @@ +useragent = parse_user_agent(); + } catch (InvalidArgumentException $e) { + $this->useragent = parse_user_agent("Mozilla/5.0 (compatible; Unknown;)"); + } + } + + /** + * Get the current browser identifier + * + * Currently detected browsers: + * + * Android Browser + * BlackBerry Browser + * Camino + * Kindle / Silk + * Firefox / Iceweasel + * Safari + * Internet Explorer + * IEMobile + * Chrome + * Opera + * Midori + * Vivaldi + * TizenBrowser + * Lynx + * Wget + * Curl + * + * @return string the lowercase browser name + */ + public function getBrowser() + { + return strtolower($this->useragent['browser']); + } + + /** + * Get the current platform identifier + * + * Currently detected platforms: + * + * Desktop + * -> Windows + * -> Linux + * -> Macintosh + * -> Chrome OS + * Mobile + * -> Android + * -> iPhone + * -> iPad / iPod Touch + * -> Windows Phone OS + * -> Kindle + * -> Kindle Fire + * -> BlackBerry + * -> Playbook + * -> Tizen + * Console + * -> Nintendo 3DS + * -> New Nintendo 3DS + * -> Nintendo Wii + * -> Nintendo WiiU + * -> PlayStation 3 + * -> PlayStation 4 + * -> PlayStation Vita + * -> Xbox 360 + * -> Xbox One + * + * @return string the lowercase platform name + */ + public function getPlatform() + { + return strtolower($this->useragent['platform']); + } + + /** + * Get the current full version identifier + * + * @return string the browser full version identifier + */ + public function getLongVersion() + { + return $this->useragent['version']; + } + + /** + * Get the current major version identifier + * + * @return int the browser major version identifier + */ + public function getVersion() + { + $version = explode('.', $this->getLongVersion()); + + return (int)$version[0]; + } + + /** + * Determine if the request comes from a human, or from a bot/crawler + * + * @return bool + */ + public function isHuman() + { + $browser = $this->getBrowser(); + if (empty($browser)) { + return false; + } + + if (preg_match('~(bot|crawl)~i', $browser)) { + return false; + } + + return true; + } + + /** + * Determine if “Do Not Track” is set by browser + * @see https://www.w3.org/TR/tracking-dnt/ + * + * @return bool + */ + public function isTrackable(): bool + { + return !(isset($_SERVER['HTTP_DNT']) && $_SERVER['HTTP_DNT'] === '1'); + } +} diff --git a/system/src/Grav/Common/Cache.php b/system/src/Grav/Common/Cache.php new file mode 100644 index 0000000..acb68e0 --- /dev/null +++ b/system/src/Grav/Common/Cache.php @@ -0,0 +1,690 @@ +init($grav); + } + + /** + * Initialization that sets a base key and the driver based on configuration settings + * + * @param Grav $grav + * @return void + */ + public function init(Grav $grav) + { + $this->config = $grav['config']; + $this->now = time(); + + if (null === $this->enabled) { + $this->enabled = (bool)$this->config->get('system.cache.enabled'); + } + + /** @var Uri $uri */ + $uri = $grav['uri']; + + $prefix = $this->config->get('system.cache.prefix'); + $uniqueness = substr(md5($uri->rootUrl(true) . $this->config->key() . GRAV_VERSION), 2, 8); + + // Cache key allows us to invalidate all cache on configuration changes. + $this->key = ($prefix ?: 'g') . '-' . $uniqueness; + $this->cache_dir = $grav['locator']->findResource('cache://doctrine/' . $uniqueness, true, true); + $this->driver_setting = $this->config->get('system.cache.driver'); + $this->driver = $this->getCacheDriver(); + $this->driver->setNamespace($this->key); + + /** @var EventDispatcher $dispatcher */ + $dispatcher = Grav::instance()['events']; + $dispatcher->addListener('onSchedulerInitialized', [$this, 'onSchedulerInitialized']); + } + + /** + * @return CacheInterface + */ + public function getSimpleCache() + { + if (null === $this->simpleCache) { + $cache = new \Grav\Framework\Cache\Adapter\DoctrineCache($this->driver, '', $this->getLifetime()); + + // Disable cache key validation. + $cache->setValidation(false); + + $this->simpleCache = $cache; + } + + return $this->simpleCache; + } + + /** + * Deletes the old out of date file-based caches + * + * @return int + */ + public function purgeOldCache() + { + $cache_dir = dirname($this->cache_dir); + $current = Utils::basename($this->cache_dir); + $count = 0; + + foreach (new DirectoryIterator($cache_dir) as $file) { + $dir = $file->getBasename(); + if ($dir === $current || $file->isDot() || $file->isFile()) { + continue; + } + + Folder::delete($file->getPathname()); + $count++; + } + + return $count; + } + + /** + * Public accessor to set the enabled state of the cache + * + * @param bool|int $enabled + * @return void + */ + public function setEnabled($enabled) + { + $this->enabled = (bool)$enabled; + } + + /** + * Returns the current enabled state + * + * @return bool + */ + public function getEnabled() + { + return $this->enabled; + } + + /** + * Get cache state + * + * @return string + */ + public function getCacheStatus() + { + return 'Cache: [' . ($this->enabled ? 'true' : 'false') . '] Setting: [' . $this->driver_setting . '] Driver: [' . $this->driver_name . ']'; + } + + /** + * Automatically picks the cache mechanism to use. If you pick one manually it will use that + * If there is no config option for $driver in the config, or it's set to 'auto', it will + * pick the best option based on which cache extensions are installed. + * + * @return DoctrineCache\CacheProvider The cache driver to use + */ + public function getCacheDriver() + { + $setting = $this->driver_setting; + $driver_name = 'file'; + + // CLI compatibility requires a non-volatile cache driver + if ($this->config->get('system.cache.cli_compatibility') && ( + $setting === 'auto' || $this->isVolatileDriver($setting))) { + $setting = $driver_name; + } + + if (!$setting || $setting === 'auto') { + if (extension_loaded('apcu')) { + $driver_name = 'apcu'; + } elseif (extension_loaded('wincache')) { + $driver_name = 'wincache'; + } + } else { + $driver_name = $setting; + } + + $this->driver_name = $driver_name; + + switch ($driver_name) { + case 'apc': + case 'apcu': + $driver = new DoctrineCache\ApcuCache(); + break; + + case 'wincache': + $driver = new DoctrineCache\WinCacheCache(); + break; + + case 'memcache': + if (extension_loaded('memcache')) { + $memcache = new \Memcache(); + $memcache->connect( + $this->config->get('system.cache.memcache.server', 'localhost'), + $this->config->get('system.cache.memcache.port', 11211) + ); + $driver = new DoctrineCache\MemcacheCache(); + $driver->setMemcache($memcache); + } else { + throw new LogicException('Memcache PHP extension has not been installed'); + } + break; + + case 'memcached': + if (extension_loaded('memcached')) { + $memcached = new \Memcached(); + $memcached->addServer( + $this->config->get('system.cache.memcached.server', 'localhost'), + $this->config->get('system.cache.memcached.port', 11211) + ); + $driver = new DoctrineCache\MemcachedCache(); + $driver->setMemcached($memcached); + } else { + throw new LogicException('Memcached PHP extension has not been installed'); + } + break; + + case 'redis': + if (extension_loaded('redis')) { + $redis = new \Redis(); + $socket = $this->config->get('system.cache.redis.socket', false); + $password = $this->config->get('system.cache.redis.password', false); + $databaseId = $this->config->get('system.cache.redis.database', 0); + + if ($socket) { + $redis->connect($socket); + } else { + $redis->connect( + $this->config->get('system.cache.redis.server', 'localhost'), + $this->config->get('system.cache.redis.port', 6379) + ); + } + + // Authenticate with password if set + if ($password && !$redis->auth($password)) { + throw new \RedisException('Redis authentication failed'); + } + + // Select alternate ( !=0 ) database ID if set + if ($databaseId && !$redis->select($databaseId)) { + throw new \RedisException('Could not select alternate Redis database ID'); + } + + $driver = new DoctrineCache\RedisCache(); + $driver->setRedis($redis); + } else { + throw new LogicException('Redis PHP extension has not been installed'); + } + break; + + default: + $driver = new DoctrineCache\FilesystemCache($this->cache_dir); + break; + } + + return $driver; + } + + /** + * Gets a cached entry if it exists based on an id. If it does not exist, it returns false + * + * @param string $id the id of the cached entry + * @return mixed|bool returns the cached entry, can be any type, or false if doesn't exist + */ + public function fetch($id) + { + if ($this->enabled) { + return $this->driver->fetch($id); + } + + return false; + } + + /** + * Stores a new cached entry. + * + * @param string $id the id of the cached entry + * @param array|object|int $data the data for the cached entry to store + * @param int|null $lifetime the lifetime to store the entry in seconds + */ + public function save($id, $data, $lifetime = null) + { + if ($this->enabled) { + if ($lifetime === null) { + $lifetime = $this->getLifetime(); + } + $this->driver->save($id, $data, $lifetime); + } + } + + /** + * Deletes an item in the cache based on the id + * + * @param string $id the id of the cached data entry + * @return bool true if the item was deleted successfully + */ + public function delete($id) + { + if ($this->enabled) { + return $this->driver->delete($id); + } + + return false; + } + + /** + * Deletes all cache + * + * @return bool + */ + public function deleteAll() + { + if ($this->enabled) { + return $this->driver->deleteAll(); + } + + return false; + } + + /** + * Returns a boolean state of whether or not the item exists in the cache based on id key + * + * @param string $id the id of the cached data entry + * @return bool true if the cached items exists + */ + public function contains($id) + { + if ($this->enabled) { + return $this->driver->contains(($id)); + } + + return false; + } + + /** + * Getter method to get the cache key + * + * @return string + */ + public function getKey() + { + return $this->key; + } + + /** + * Setter method to set key (Advanced) + * + * @param string $key + * @return void + */ + public function setKey($key) + { + $this->key = $key; + $this->driver->setNamespace($this->key); + } + + /** + * Helper method to clear all Grav caches + * + * @param string $remove standard|all|assets-only|images-only|cache-only + * @return array + */ + public static function clearCache($remove = 'standard') + { + $locator = Grav::instance()['locator']; + $output = []; + $user_config = USER_DIR . 'config/system.yaml'; + + switch ($remove) { + case 'all': + $remove_paths = self::$all_remove; + break; + case 'assets-only': + $remove_paths = self::$assets_remove; + break; + case 'images-only': + $remove_paths = self::$images_remove; + break; + case 'cache-only': + $remove_paths = self::$cache_remove; + break; + case 'tmp-only': + $remove_paths = self::$tmp_remove; + break; + case 'invalidate': + $remove_paths = []; + break; + default: + if (Grav::instance()['config']->get('system.cache.clear_images_by_default')) { + $remove_paths = self::$standard_remove; + } else { + $remove_paths = self::$standard_remove_no_images; + } + } + + // Delete entries in the doctrine cache if required + if (in_array($remove, ['all', 'standard'])) { + $cache = Grav::instance()['cache']; + $cache->driver->deleteAll(); + } + + // Clearing cache event to add paths to clear + Grav::instance()->fireEvent('onBeforeCacheClear', new Event(['remove' => $remove, 'paths' => &$remove_paths])); + + foreach ($remove_paths as $stream) { + // Convert stream to a real path + try { + $path = $locator->findResource($stream, true, true); + if ($path === false) { + continue; + } + + $anything = false; + $files = glob($path . '/*'); + + if (is_array($files)) { + foreach ($files as $file) { + if (is_link($file)) { + $output[] = 'Skipping symlink: ' . $file; + } elseif (is_file($file)) { + if (@unlink($file)) { + $anything = true; + } + } elseif (is_dir($file)) { + if (Folder::delete($file, false)) { + $anything = true; + } + } + } + } + + if ($anything) { + $output[] = 'Cleared: ' . $path . '/*'; + } + } catch (Exception $e) { + // stream not found or another error while deleting files. + $output[] = 'ERROR: ' . $e->getMessage(); + } + } + + $output[] = ''; + + if (($remove === 'all' || $remove === 'standard') && file_exists($user_config)) { + touch($user_config); + + $output[] = 'Touched: ' . $user_config; + $output[] = ''; + } + + // Clear stat cache + @clearstatcache(); + + // Clear opcache + if (function_exists('opcache_reset')) { + @opcache_reset(); + } + + Grav::instance()->fireEvent('onAfterCacheClear', new Event(['remove' => $remove, 'output' => &$output])); + + return $output; + } + + /** + * @return void + */ + public static function invalidateCache() + { + $user_config = USER_DIR . 'config/system.yaml'; + + if (file_exists($user_config)) { + touch($user_config); + } + + // Clear stat cache + @clearstatcache(); + + // Clear opcache + if (function_exists('opcache_reset')) { + @opcache_reset(); + } + } + + /** + * Set the cache lifetime programmatically + * + * @param int $future timestamp + * @return void + */ + public function setLifetime($future) + { + if (!$future) { + return; + } + + $interval = (int)($future - $this->now); + if ($interval > 0 && $interval < $this->getLifetime()) { + $this->lifetime = $interval; + } + } + + + /** + * Retrieve the cache lifetime (in seconds) + * + * @return int + */ + public function getLifetime() + { + if ($this->lifetime === null) { + $this->lifetime = (int)($this->config->get('system.cache.lifetime') ?: 604800); // 1 week default + } + + return $this->lifetime; + } + + /** + * Returns the current driver name + * + * @return string + */ + public function getDriverName() + { + return $this->driver_name; + } + + /** + * Returns the current driver setting + * + * @return string + */ + public function getDriverSetting() + { + return $this->driver_setting; + } + + /** + * is this driver a volatile driver in that it resides in PHP process memory + * + * @param string $setting + * @return bool + */ + public function isVolatileDriver($setting) + { + return in_array($setting, ['apc', 'apcu', 'xcache', 'wincache'], true); + } + + /** + * Static function to call as a scheduled Job to purge old Doctrine files + * + * @param bool $echo + * + * @return string|void + */ + public static function purgeJob($echo = false) + { + /** @var Cache $cache */ + $cache = Grav::instance()['cache']; + $deleted_folders = $cache->purgeOldCache(); + $msg = 'Purged ' . $deleted_folders . ' old cache folders...'; + + if ($echo) { + echo $msg; + } else { + return $msg; + } + } + + /** + * Static function to call as a scheduled Job to clear Grav cache + * + * @param string $type + * @return void + */ + public static function clearJob($type) + { + $result = static::clearCache($type); + static::invalidateCache(); + + echo strip_tags(implode("\n", $result)); + } + + /** + * @param Event $event + * @return void + */ + public function onSchedulerInitialized(Event $event) + { + /** @var Scheduler $scheduler */ + $scheduler = $event['scheduler']; + $config = Grav::instance()['config']; + + // File Cache Purge + $at = $config->get('system.cache.purge_at'); + $name = 'cache-purge'; + $logs = 'logs/' . $name . '.out'; + + $job = $scheduler->addFunction('Grav\Common\Cache::purgeJob', [true], $name); + $job->at($at); + $job->output($logs); + $job->backlink('/config/system#caching'); + + // Cache Clear + $at = $config->get('system.cache.clear_at'); + $clear_type = $config->get('system.cache.clear_job_type'); + $name = 'cache-clear'; + $logs = 'logs/' . $name . '.out'; + + $job = $scheduler->addFunction('Grav\Common\Cache::clearJob', [$clear_type], $name); + $job->at($at); + $job->output($logs); + $job->backlink('/config/system#caching'); + } +} diff --git a/system/src/Grav/Common/Composer.php b/system/src/Grav/Common/Composer.php new file mode 100644 index 0000000..65ba505 --- /dev/null +++ b/system/src/Grav/Common/Composer.php @@ -0,0 +1,67 @@ +path = $path ? rtrim($path, '\\/') . '/' : ''; + $this->cacheFolder = $cacheFolder; + $this->files = $files; + } + + /** + * Get filename for the compiled PHP file. + * + * @param string|null $name + * @return $this + */ + public function name($name = null) + { + if (!$this->name) { + $this->name = $name ?: md5(json_encode(array_keys($this->files))); + } + + return $this; + } + + /** + * Function gets called when cached configuration is saved. + * + * @return void + */ + public function modified() + { + } + + /** + * Get timestamp of compiled configuration + * + * @return int Timestamp of compiled configuration + */ + public function timestamp() + { + return $this->timestamp ?: time(); + } + + /** + * Load the configuration. + * + * @return mixed + */ + public function load() + { + if ($this->object) { + return $this->object; + } + + $filename = $this->createFilename(); + if (!$this->loadCompiledFile($filename) && $this->loadFiles()) { + $this->saveCompiledFile($filename); + } + + return $this->object; + } + + /** + * Returns checksum from the configuration files. + * + * You can set $this->checksum = false to disable this check. + * + * @return bool|string + */ + public function checksum() + { + if (null === $this->checksum) { + $this->checksum = md5(json_encode($this->files) . $this->version); + } + + return $this->checksum; + } + + /** + * @return string + */ + protected function createFilename() + { + return "{$this->cacheFolder}/{$this->name()->name}.php"; + } + + /** + * Create configuration object. + * + * @param array $data + * @return void + */ + abstract protected function createObject(array $data = []); + + /** + * Finalize configuration object. + * + * @return void + */ + abstract protected function finalizeObject(); + + /** + * Load single configuration file and append it to the correct position. + * + * @param string $name Name of the position. + * @param string|string[] $filename File(s) to be loaded. + * @return void + */ + abstract protected function loadFile($name, $filename); + + /** + * Load and join all configuration files. + * + * @return bool + * @internal + */ + protected function loadFiles() + { + $this->createObject(); + + $list = array_reverse($this->files); + foreach ($list as $files) { + foreach ($files as $name => $item) { + $this->loadFile($name, $this->path . $item['file']); + } + } + + $this->finalizeObject(); + + return true; + } + + /** + * Load compiled file. + * + * @param string $filename + * @return bool + * @internal + */ + protected function loadCompiledFile($filename) + { + if (!file_exists($filename)) { + return false; + } + + $cache = include $filename; + if (!is_array($cache) + || !isset($cache['checksum'], $cache['data'], $cache['@class']) + || $cache['@class'] !== get_class($this) + ) { + return false; + } + + // Load real file if cache isn't up to date (or is invalid). + if ($cache['checksum'] !== $this->checksum()) { + return false; + } + + $this->createObject($cache['data']); + $this->timestamp = $cache['timestamp'] ?? 0; + + $this->finalizeObject(); + + return true; + } + + /** + * Save compiled file. + * + * @param string $filename + * @return void + * @throws RuntimeException + * @internal + */ + protected function saveCompiledFile($filename) + { + $file = PhpFile::instance($filename); + + // Attempt to lock the file for writing. + try { + $file->lock(false); + } catch (Exception $e) { + // Another process has locked the file; we will check this in a bit. + } + + if ($file->locked() === false) { + // File was already locked by another process. + return; + } + + $cache = [ + '@class' => get_class($this), + 'timestamp' => time(), + 'checksum' => $this->checksum(), + 'files' => $this->files, + 'data' => $this->getState() + ]; + + $file->save($cache); + $file->unlock(); + $file->free(); + + $this->modified(); + } + + /** + * @return array + */ + protected function getState() + { + return $this->object->toArray(); + } +} diff --git a/system/src/Grav/Common/Config/CompiledBlueprints.php b/system/src/Grav/Common/Config/CompiledBlueprints.php new file mode 100644 index 0000000..ca7173c --- /dev/null +++ b/system/src/Grav/Common/Config/CompiledBlueprints.php @@ -0,0 +1,131 @@ +version = 2; + } + + /** + * Returns checksum from the configuration files. + * + * You can set $this->checksum = false to disable this check. + * + * @return bool|string + */ + public function checksum() + { + if (null === $this->checksum) { + $this->checksum = md5(json_encode($this->files) . json_encode($this->getTypes()) . $this->version); + } + + return $this->checksum; + } + + /** + * Create configuration object. + * + * @param array $data + */ + protected function createObject(array $data = []) + { + $this->object = (new BlueprintSchema($data))->setTypes($this->getTypes()); + } + + /** + * Get list of form field types. + * + * @return array + */ + protected function getTypes() + { + return Grav::instance()['plugins']->formFieldTypes ?: []; + } + + /** + * Finalize configuration object. + * + * @return void + */ + protected function finalizeObject() + { + } + + /** + * Load single configuration file and append it to the correct position. + * + * @param string $name Name of the position. + * @param array $files Files to be loaded. + * @return void + */ + protected function loadFile($name, $files) + { + // Load blueprint file. + $blueprint = new Blueprint($files); + + $this->object->embed($name, $blueprint->load()->toArray(), '/', true); + } + + /** + * Load and join all configuration files. + * + * @return bool + * @internal + */ + protected function loadFiles() + { + $this->createObject(); + + // Convert file list into parent list. + $list = []; + /** @var array $files */ + foreach ($this->files as $files) { + foreach ($files as $name => $item) { + $list[$name][] = $this->path . $item['file']; + } + } + + // Load files. + foreach ($list as $name => $files) { + $this->loadFile($name, $files); + } + + $this->finalizeObject(); + + return true; + } + + /** + * @return array + */ + protected function getState() + { + return $this->object->getState(); + } +} diff --git a/system/src/Grav/Common/Config/CompiledConfig.php b/system/src/Grav/Common/Config/CompiledConfig.php new file mode 100644 index 0000000..85bb5e3 --- /dev/null +++ b/system/src/Grav/Common/Config/CompiledConfig.php @@ -0,0 +1,114 @@ +version = 1; + } + + /** + * Set blueprints for the configuration. + * + * @param callable $blueprints + * @return $this + */ + public function setBlueprints(callable $blueprints) + { + $this->callable = $blueprints; + + return $this; + } + + /** + * @param bool $withDefaults + * @return mixed + */ + public function load($withDefaults = false) + { + $this->withDefaults = $withDefaults; + + return parent::load(); + } + + /** + * Create configuration object. + * + * @param array $data + * @return void + */ + protected function createObject(array $data = []) + { + if ($this->withDefaults && empty($data) && is_callable($this->callable)) { + $blueprints = $this->callable; + $data = $blueprints()->getDefaults(); + } + + $this->object = new Config($data, $this->callable); + } + + /** + * Finalize configuration object. + * + * @return void + */ + protected function finalizeObject() + { + $this->object->checksum($this->checksum()); + $this->object->timestamp($this->timestamp()); + } + + /** + * Function gets called when cached configuration is saved. + * + * @return void + */ + public function modified() + { + $this->object->modified(true); + } + + /** + * Load single configuration file and append it to the correct position. + * + * @param string $name Name of the position. + * @param string $filename File to be loaded. + * @return void + */ + protected function loadFile($name, $filename) + { + $file = CompiledYamlFile::instance($filename); + $this->object->join($name, $file->content(), '/'); + $file->free(); + } +} diff --git a/system/src/Grav/Common/Config/CompiledLanguages.php b/system/src/Grav/Common/Config/CompiledLanguages.php new file mode 100644 index 0000000..7e6692c --- /dev/null +++ b/system/src/Grav/Common/Config/CompiledLanguages.php @@ -0,0 +1,83 @@ +version = 1; + } + + /** + * Create configuration object. + * + * @param array $data + * @return void + */ + protected function createObject(array $data = []) + { + $this->object = new Languages($data); + } + + /** + * Finalize configuration object. + * + * @return void + */ + protected function finalizeObject() + { + $this->object->checksum($this->checksum()); + $this->object->timestamp($this->timestamp()); + } + + + /** + * Function gets called when cached configuration is saved. + * + * @return void + */ + public function modified() + { + $this->object->modified(true); + } + + /** + * Load single configuration file and append it to the correct position. + * + * @param string $name Name of the position. + * @param string $filename File to be loaded. + * @return void + */ + protected function loadFile($name, $filename) + { + $file = CompiledYamlFile::instance($filename); + if (preg_match('|languages\.yaml$|', $filename)) { + $this->object->mergeRecursive((array) $file->content()); + } else { + $this->object->mergeRecursive([$name => $file->content()]); + } + $file->free(); + } +} diff --git a/system/src/Grav/Common/Config/Config.php b/system/src/Grav/Common/Config/Config.php new file mode 100644 index 0000000..17eb117 --- /dev/null +++ b/system/src/Grav/Common/Config/Config.php @@ -0,0 +1,156 @@ +key) { + $this->key = md5($this->checksum . $this->timestamp); + } + + return $this->key; + } + + /** + * @param string|null $checksum + * @return string|null + */ + public function checksum($checksum = null) + { + if ($checksum !== null) { + $this->checksum = $checksum; + } + + return $this->checksum; + } + + /** + * @param bool|null $modified + * @return bool + */ + public function modified($modified = null) + { + if ($modified !== null) { + $this->modified = $modified; + } + + return $this->modified; + } + + /** + * @param int|null $timestamp + * @return int + */ + public function timestamp($timestamp = null) + { + if ($timestamp !== null) { + $this->timestamp = $timestamp; + } + + return $this->timestamp; + } + + /** + * @return $this + */ + public function reload() + { + $grav = Grav::instance(); + + // Load new configuration. + $config = ConfigServiceProvider::load($grav); + + /** @var Debugger $debugger */ + $debugger = $grav['debugger']; + + if ($config->modified()) { + // Update current configuration. + $this->items = $config->toArray(); + $this->checksum($config->checksum()); + $this->modified(true); + + $debugger->addMessage('Configuration was changed and saved.'); + } + + return $this; + } + + /** + * @return void + */ + public function debug() + { + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + + $debugger->addMessage('Environment Name: ' . $this->environment); + if ($this->modified()) { + $debugger->addMessage('Configuration reloaded and cached.'); + } + } + + /** + * @return void + */ + public function init() + { + $setup = Grav::instance()['setup']->toArray(); + foreach ($setup as $key => $value) { + if ($key === 'streams' || !is_array($value)) { + // Optimized as streams and simple values are fully defined in setup. + $this->items[$key] = $value; + } else { + $this->joinDefaults($key, $value); + } + } + + // Legacy value - Override the media.upload_limit based on PHP values + $this->items['system']['media']['upload_limit'] = Utils::getUploadLimit(); + } + + /** + * @return mixed + * @deprecated 1.5 Use Grav::instance()['languages'] instead. + */ + public function getLanguages() + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use Grav::instance()[\'languages\'] instead', E_USER_DEPRECATED); + + return Grav::instance()['languages']; + } +} diff --git a/system/src/Grav/Common/Config/ConfigFileFinder.php b/system/src/Grav/Common/Config/ConfigFileFinder.php new file mode 100644 index 0000000..6381e48 --- /dev/null +++ b/system/src/Grav/Common/Config/ConfigFileFinder.php @@ -0,0 +1,273 @@ +base = $base ? "{$base}/" : ''; + + return $this; + } + + /** + * Return all locations for all the files with a timestamp. + * + * @param array $paths List of folders to look from. + * @param string $pattern Pattern to match the file. Pattern will also be removed from the key. + * @param int $levels Maximum number of recursive directories. + * @return array + */ + public function locateFiles(array $paths, $pattern = '|\.yaml$|', $levels = -1) + { + $list = []; + foreach ($paths as $folder) { + $list += $this->detectRecursive($folder, $pattern, $levels); + } + + return $list; + } + + /** + * Return all locations for all the files with a timestamp. + * + * @param array $paths List of folders to look from. + * @param string $pattern Pattern to match the file. Pattern will also be removed from the key. + * @param int $levels Maximum number of recursive directories. + * @return array + */ + public function getFiles(array $paths, $pattern = '|\.yaml$|', $levels = -1) + { + $list = []; + foreach ($paths as $folder) { + $path = trim(Folder::getRelativePath($folder), '/'); + + $files = $this->detectRecursive($folder, $pattern, $levels); + + $list += $files[trim($path, '/')]; + } + + return $list; + } + + /** + * Return all paths for all the files with a timestamp. + * + * @param array $paths List of folders to look from. + * @param string $pattern Pattern to match the file. Pattern will also be removed from the key. + * @param int $levels Maximum number of recursive directories. + * @return array + */ + public function listFiles(array $paths, $pattern = '|\.yaml$|', $levels = -1) + { + $list = []; + foreach ($paths as $folder) { + $list = array_merge_recursive($list, $this->detectAll($folder, $pattern, $levels)); + } + + return $list; + } + + /** + * Find filename from a list of folders. + * + * Note: Only finds the last override. + * + * @param string $filename + * @param array $folders + * @return array + */ + public function locateFileInFolder($filename, array $folders) + { + $list = []; + foreach ($folders as $folder) { + $list += $this->detectInFolder($folder, $filename); + } + + return $list; + } + + /** + * Find filename from a list of folders. + * + * @param array $folders + * @param string|null $filename + * @return array + */ + public function locateInFolders(array $folders, $filename = null) + { + $list = []; + foreach ($folders as $folder) { + $path = trim(Folder::getRelativePath($folder), '/'); + $list[$path] = $this->detectInFolder($folder, $filename); + } + + return $list; + } + + /** + * Return all existing locations for a single file with a timestamp. + * + * @param array $paths Filesystem paths to look up from. + * @param string $name Configuration file to be located. + * @param string $ext File extension (optional, defaults to .yaml). + * @return array + */ + public function locateFile(array $paths, $name, $ext = '.yaml') + { + $filename = preg_replace('|[.\/]+|', '/', $name) . $ext; + + $list = []; + foreach ($paths as $folder) { + $path = trim(Folder::getRelativePath($folder), '/'); + + if (is_file("{$folder}/{$filename}")) { + $modified = filemtime("{$folder}/{$filename}"); + } else { + $modified = 0; + } + $basename = $this->base . $name; + $list[$path] = [$basename => ['file' => "{$path}/{$filename}", 'modified' => $modified]]; + } + + return $list; + } + + /** + * Detects all directories with a configuration file and returns them with last modification time. + * + * @param string $folder Location to look up from. + * @param string $pattern Pattern to match the file. Pattern will also be removed from the key. + * @param int $levels Maximum number of recursive directories. + * @return array + * @internal + */ + protected function detectRecursive($folder, $pattern, $levels) + { + $path = trim(Folder::getRelativePath($folder), '/'); + + if (is_dir($folder)) { + // Find all system and user configuration files. + $options = [ + 'levels' => $levels, + 'compare' => 'Filename', + 'pattern' => $pattern, + 'filters' => [ + 'pre-key' => $this->base, + 'key' => $pattern, + 'value' => function (RecursiveDirectoryIterator $file) use ($path) { + return ['file' => "{$path}/{$file->getSubPathname()}", 'modified' => $file->getMTime()]; + } + ], + 'key' => 'SubPathname' + ]; + + $list = Folder::all($folder, $options); + + ksort($list); + } else { + $list = []; + } + + return [$path => $list]; + } + + /** + * Detects all directories with the lookup file and returns them with last modification time. + * + * @param string $folder Location to look up from. + * @param string|null $lookup Filename to be located (defaults to directory name). + * @return array + * @internal + */ + protected function detectInFolder($folder, $lookup = null) + { + $folder = rtrim($folder, '/'); + $path = trim(Folder::getRelativePath($folder), '/'); + $base = $path === $folder ? '' : ($path ? substr($folder, 0, -strlen($path)) : $folder . '/'); + + $list = []; + + if (is_dir($folder)) { + $iterator = new DirectoryIterator($folder); + foreach ($iterator as $directory) { + if (!$directory->isDir() || $directory->isDot()) { + continue; + } + + $name = $directory->getFilename(); + $find = ($lookup ?: $name) . '.yaml'; + $filename = "{$path}/{$name}/{$find}"; + + if (file_exists($base . $filename)) { + $basename = $this->base . $name; + $list[$basename] = ['file' => $filename, 'modified' => filemtime($base . $filename)]; + } + } + } + + return $list; + } + + /** + * Detects all plugins with a configuration file and returns them with last modification time. + * + * @param string $folder Location to look up from. + * @param string $pattern Pattern to match the file. Pattern will also be removed from the key. + * @param int $levels Maximum number of recursive directories. + * @return array + * @internal + */ + protected function detectAll($folder, $pattern, $levels) + { + $path = trim(Folder::getRelativePath($folder), '/'); + + if (is_dir($folder)) { + // Find all system and user configuration files. + $options = [ + 'levels' => $levels, + 'compare' => 'Filename', + 'pattern' => $pattern, + 'filters' => [ + 'pre-key' => $this->base, + 'key' => $pattern, + 'value' => function (RecursiveDirectoryIterator $file) use ($path) { + return ["{$path}/{$file->getSubPathname()}" => $file->getMTime()]; + } + ], + 'key' => 'SubPathname' + ]; + + $list = Folder::all($folder, $options); + + ksort($list); + } else { + $list = []; + } + + return $list; + } +} diff --git a/system/src/Grav/Common/Config/Languages.php b/system/src/Grav/Common/Config/Languages.php new file mode 100644 index 0000000..6152a6a --- /dev/null +++ b/system/src/Grav/Common/Config/Languages.php @@ -0,0 +1,107 @@ +checksum = $checksum; + } + + return $this->checksum; + } + + /** + * @param bool|null $modified + * @return bool + */ + public function modified($modified = null) + { + if ($modified !== null) { + $this->modified = $modified; + } + + return $this->modified; + } + + /** + * @param int|null $timestamp + * @return int + */ + public function timestamp($timestamp = null) + { + if ($timestamp !== null) { + $this->timestamp = $timestamp; + } + + return $this->timestamp; + } + + /** + * @return void + */ + public function reformat() + { + if (isset($this->items['plugins'])) { + $this->items = array_merge_recursive($this->items, $this->items['plugins']); + unset($this->items['plugins']); + } + } + + /** + * @param array $data + * @return void + */ + public function mergeRecursive(array $data) + { + $this->items = Utils::arrayMergeRecursiveUnique($this->items, $data); + } + + /** + * @param string $lang + * @return array + */ + public function flattenByLang($lang) + { + $language = $this->items[$lang]; + return Utils::arrayFlattenDotNotation($language); + } + + /** + * @param array $array + * @return array + */ + public function unflatten($array) + { + return Utils::arrayUnflattenDotNotation($array); + } +} diff --git a/system/src/Grav/Common/Config/Setup.php b/system/src/Grav/Common/Config/Setup.php new file mode 100644 index 0000000..ba9b52f --- /dev/null +++ b/system/src/Grav/Common/Config/Setup.php @@ -0,0 +1,423 @@ + 'unknown', + '127.0.0.1' => 'localhost', + '::1' => 'localhost' + ]; + + /** + * @var string|null Current environment normalized to lower case. + */ + public static $environment; + + /** @var string */ + public static $securityFile = 'config://security.yaml'; + + /** @var array */ + protected $streams = [ + 'user' => [ + 'type' => 'ReadOnlyStream', + 'force' => true, + 'prefixes' => [ + '' => [] // Set in constructor + ] + ], + 'cache' => [ + 'type' => 'Stream', + 'force' => true, + 'prefixes' => [ + '' => [], // Set in constructor + 'images' => ['images'] + ] + ], + 'log' => [ + 'type' => 'Stream', + 'force' => true, + 'prefixes' => [ + '' => [] // Set in constructor + ] + ], + 'tmp' => [ + 'type' => 'Stream', + 'force' => true, + 'prefixes' => [ + '' => [] // Set in constructor + ] + ], + 'backup' => [ + 'type' => 'Stream', + 'force' => true, + 'prefixes' => [ + '' => [] // Set in constructor + ] + ], + 'environment' => [ + 'type' => 'ReadOnlyStream' + // If not defined, environment will be set up in the constructor. + ], + 'system' => [ + 'type' => 'ReadOnlyStream', + 'prefixes' => [ + '' => ['system'], + ] + ], + 'asset' => [ + 'type' => 'Stream', + 'prefixes' => [ + '' => ['assets'], + ] + ], + 'blueprints' => [ + 'type' => 'ReadOnlyStream', + 'prefixes' => [ + '' => ['environment://blueprints', 'user://blueprints', 'system://blueprints'], + ] + ], + 'config' => [ + 'type' => 'ReadOnlyStream', + 'prefixes' => [ + '' => ['environment://config', 'user://config', 'system://config'], + ] + ], + 'plugins' => [ + 'type' => 'ReadOnlyStream', + 'prefixes' => [ + '' => ['user://plugins'], + ] + ], + 'plugin' => [ + 'type' => 'ReadOnlyStream', + 'prefixes' => [ + '' => ['user://plugins'], + ] + ], + 'themes' => [ + 'type' => 'ReadOnlyStream', + 'prefixes' => [ + '' => ['user://themes'], + ] + ], + 'languages' => [ + 'type' => 'ReadOnlyStream', + 'prefixes' => [ + '' => ['environment://languages', 'user://languages', 'system://languages'], + ] + ], + 'image' => [ + 'type' => 'Stream', + 'prefixes' => [ + '' => ['user://images', 'system://images'] + ] + ], + 'page' => [ + 'type' => 'ReadOnlyStream', + 'prefixes' => [ + '' => ['user://pages'] + ] + ], + 'user-data' => [ + 'type' => 'Stream', + 'force' => true, + 'prefixes' => [ + '' => ['user://data'] + ] + ], + 'account' => [ + 'type' => 'ReadOnlyStream', + 'prefixes' => [ + '' => ['user://accounts'] + ] + ], + ]; + + /** + * @param Container|array $container + */ + public function __construct($container) + { + // Configure main streams. + $abs = str_starts_with(GRAV_SYSTEM_PATH, '/'); + $this->streams['system']['prefixes'][''] = $abs ? ['system', GRAV_SYSTEM_PATH] : ['system']; + $this->streams['user']['prefixes'][''] = [GRAV_USER_PATH]; + $this->streams['cache']['prefixes'][''] = [GRAV_CACHE_PATH]; + $this->streams['log']['prefixes'][''] = [GRAV_LOG_PATH]; + $this->streams['tmp']['prefixes'][''] = [GRAV_TMP_PATH]; + $this->streams['backup']['prefixes'][''] = [GRAV_BACKUP_PATH]; + + // If environment is not set, look for the environment variable and then the constant. + $environment = static::$environment ?? + (defined('GRAV_ENVIRONMENT') ? GRAV_ENVIRONMENT : (getenv('GRAV_ENVIRONMENT') ?: null)); + + // If no environment is set, make sure we get one (CLI or hostname). + if (null === $environment) { + if (defined('GRAV_CLI')) { + $request = null; + $uri = null; + $environment = 'cli'; + } else { + /** @var ServerRequestInterface $request */ + $request = $container['request']; + $uri = $request->getUri(); + $environment = $uri->getHost(); + } + } + + // Resolve server aliases to the proper environment. + static::$environment = static::$environments[$environment] ?? $environment; + + // Pre-load setup.php which contains our initial configuration. + // Configuration may contain dynamic parts, which is why we need to always load it. + // If GRAV_SETUP_PATH has been defined, use it, otherwise use defaults. + $setupFile = defined('GRAV_SETUP_PATH') ? GRAV_SETUP_PATH : (getenv('GRAV_SETUP_PATH') ?: null); + if (null !== $setupFile) { + // Make sure that the custom setup file exists. Terminates the script if not. + if (!str_starts_with($setupFile, '/')) { + $setupFile = GRAV_WEBROOT . '/' . $setupFile; + } + if (!is_file($setupFile)) { + echo 'GRAV_SETUP_PATH is defined but does not point to existing setup file.'; + exit(1); + } + } else { + $setupFile = GRAV_WEBROOT . '/setup.php'; + if (!is_file($setupFile)) { + $setupFile = GRAV_WEBROOT . '/' . GRAV_USER_PATH . '/setup.php'; + } + if (!is_file($setupFile)) { + $setupFile = null; + } + } + $setup = $setupFile ? (array) include $setupFile : []; + + // Add default streams defined in beginning of the class. + if (!isset($setup['streams']['schemes'])) { + $setup['streams']['schemes'] = []; + } + $setup['streams']['schemes'] += $this->streams; + + // Initialize class. + parent::__construct($setup); + + $this->def('environment', static::$environment); + + // Figure out path for the current environment. + $envPath = defined('GRAV_ENVIRONMENT_PATH') ? GRAV_ENVIRONMENT_PATH : (getenv('GRAV_ENVIRONMENT_PATH') ?: null); + if (null === $envPath) { + // Find common path for all environments and append current environment into it. + $envPath = defined('GRAV_ENVIRONMENTS_PATH') ? GRAV_ENVIRONMENTS_PATH : (getenv('GRAV_ENVIRONMENTS_PATH') ?: null); + if (null !== $envPath) { + $envPath .= '/'; + } else { + // Use default location. Start with Grav 1.7 default. + $envPath = GRAV_WEBROOT. '/' . GRAV_USER_PATH . '/env'; + if (is_dir($envPath)) { + $envPath = 'user://env/'; + } else { + // Fallback to Grav 1.6 default. + $envPath = 'user://'; + } + } + $envPath .= $this->get('environment'); + } + + // Set up environment. + $this->def('environment', static::$environment); + $this->def('streams.schemes.environment.prefixes', ['' => [$envPath]]); + } + + /** + * @return $this + * @throws RuntimeException + * @throws InvalidArgumentException + */ + public function init() + { + $locator = new UniformResourceLocator(GRAV_WEBROOT); + $files = []; + + $guard = 5; + do { + $check = $files; + $this->initializeLocator($locator); + $files = $locator->findResources('config://streams.yaml'); + + if ($check === $files) { + break; + } + + // Update streams. + foreach (array_reverse($files) as $path) { + $file = CompiledYamlFile::instance($path); + $content = (array)$file->content(); + if (!empty($content['schemes'])) { + $this->items['streams']['schemes'] = $content['schemes'] + $this->items['streams']['schemes']; + } + } + } while (--$guard); + + if (!$guard) { + throw new RuntimeException('Setup: Configuration reload loop detected!'); + } + + // Make sure we have valid setup. + $this->check($locator); + + return $this; + } + + /** + * Initialize resource locator by using the configuration. + * + * @param UniformResourceLocator $locator + * @return void + * @throws BadMethodCallException + */ + public function initializeLocator(UniformResourceLocator $locator) + { + $locator->reset(); + + $schemes = (array) $this->get('streams.schemes', []); + + foreach ($schemes as $scheme => $config) { + if (isset($config['paths'])) { + $locator->addPath($scheme, '', $config['paths']); + } + + $override = $config['override'] ?? false; + $force = $config['force'] ?? false; + + if (isset($config['prefixes'])) { + foreach ((array)$config['prefixes'] as $prefix => $paths) { + $locator->addPath($scheme, $prefix, $paths, $override, $force); + } + } + } + } + + /** + * Get available streams and their types from the configuration. + * + * @return array + */ + public function getStreams() + { + $schemes = []; + foreach ((array) $this->get('streams.schemes') as $scheme => $config) { + $type = $config['type'] ?? 'ReadOnlyStream'; + if ($type[0] !== '\\') { + $type = '\\RocketTheme\\Toolbox\\StreamWrapper\\' . $type; + } + + $schemes[$scheme] = $type; + } + + return $schemes; + } + + /** + * @param UniformResourceLocator $locator + * @return void + * @throws InvalidArgumentException + * @throws BadMethodCallException + * @throws RuntimeException + */ + protected function check(UniformResourceLocator $locator) + { + $streams = $this->items['streams']['schemes'] ?? null; + if (!is_array($streams)) { + throw new InvalidArgumentException('Configuration is missing streams.schemes!'); + } + $diff = array_keys(array_diff_key($this->streams, $streams)); + if ($diff) { + throw new InvalidArgumentException( + sprintf('Configuration is missing keys %s from streams.schemes!', implode(', ', $diff)) + ); + } + + try { + // If environment is found, remove all missing override locations (B/C compatibility). + if ($locator->findResource('environment://', true)) { + $force = $this->get('streams.schemes.environment.force', false); + if (!$force) { + $prefixes = $this->get('streams.schemes.environment.prefixes.'); + $update = false; + foreach ($prefixes as $i => $prefix) { + if ($locator->isStream($prefix)) { + if ($locator->findResource($prefix, true)) { + break; + } + } elseif (file_exists($prefix)) { + break; + } + + unset($prefixes[$i]); + $update = true; + } + + if ($update) { + $this->set('streams.schemes.environment.prefixes', ['' => array_values($prefixes)]); + $this->initializeLocator($locator); + } + } + } + + if (!$locator->findResource('environment://config', true)) { + // If environment does not have its own directory, remove it from the lookup. + $prefixes = $this->get('streams.schemes.environment.prefixes'); + $prefixes['config'] = []; + + $this->set('streams.schemes.environment.prefixes', $prefixes); + $this->initializeLocator($locator); + } + + // Create security.yaml salt if it doesn't exist into existing configuration environment if possible. + $securityFile = Utils::basename(static::$securityFile); + $securityFolder = substr(static::$securityFile, 0, -\strlen($securityFile)); + $securityFolder = $locator->findResource($securityFolder, true) ?: $locator->findResource($securityFolder, true, true); + $filename = "{$securityFolder}/{$securityFile}"; + + $security_file = CompiledYamlFile::instance($filename); + $security_content = (array)$security_file->content(); + + if (!isset($security_content['salt'])) { + $security_content = array_merge($security_content, ['salt' => Utils::generateRandomString(14)]); + $security_file->content($security_content); + $security_file->save(); + $security_file->free(); + } + } catch (RuntimeException $e) { + throw new RuntimeException(sprintf('Grav failed to initialize: %s', $e->getMessage()), 500, $e); + } + } +} diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php new file mode 100644 index 0000000..3e84dce --- /dev/null +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -0,0 +1,594 @@ +blueprintSchema) { + $this->blueprintSchema = clone $this->blueprintSchema; + } + } + + /** + * @param string $scope + * @return void + */ + public function setScope($scope) + { + $this->scope = $scope; + } + + /** + * @param object $object + * @return void + */ + public function setObject($object) + { + $this->object = $object; + } + + /** + * Set default values for field types. + * + * @param array $types + * @return $this + */ + public function setTypes(array $types) + { + $this->initInternals(); + + $this->blueprintSchema->setTypes($types); + + return $this; + } + + /** + * @param string $name + * @return array|mixed|null + * @since 1.7 + */ + public function getDefaultValue(string $name) + { + $path = explode('.', $name); + $current = $this->getDefaults(); + + foreach ($path as $field) { + if (is_object($current) && isset($current->{$field})) { + $current = $current->{$field}; + } elseif (is_array($current) && isset($current[$field])) { + $current = $current[$field]; + } else { + return null; + } + } + + return $current; + } + + /** + * Get nested structure containing default values defined in the blueprints. + * + * Fields without default value are ignored in the list. + * + * @return array + */ + public function getDefaults() + { + $this->initInternals(); + + if (null === $this->defaults) { + $this->defaults = $this->blueprintSchema->getDefaults(); + } + + return $this->defaults; + } + + /** + * Initialize blueprints with its dynamic fields. + * + * @return $this + */ + public function init() + { + foreach ($this->dynamic as $key => $data) { + // Locate field. + $path = explode('/', $key); + $current = &$this->items; + + foreach ($path as $field) { + if (is_object($current)) { + // Handle objects. + if (!isset($current->{$field})) { + $current->{$field} = []; + } + + $current = &$current->{$field}; + } else { + // Handle arrays and scalars. + if (!is_array($current)) { + $current = [$field => []]; + } elseif (!isset($current[$field])) { + $current[$field] = []; + } + + $current = &$current[$field]; + } + } + + // Set dynamic property. + foreach ($data as $property => $call) { + $action = $call['action']; + $method = 'dynamic' . ucfirst($action); + $call['object'] = $this->object; + + if (isset($this->handlers[$action])) { + $callable = $this->handlers[$action]; + $callable($current, $property, $call); + } elseif (method_exists($this, $method)) { + $this->{$method}($current, $property, $call); + } + } + } + + return $this; + } + + /** + * Extend blueprint with another blueprint. + * + * @param BlueprintForm|array $extends + * @param bool $append + * @return $this + */ + public function extend($extends, $append = false) + { + parent::extend($extends, $append); + + $this->deepInit($this->items); + + return $this; + } + + /** + * @param string $name + * @param mixed $value + * @param string $separator + * @param bool $append + * @return $this + */ + public function embed($name, $value, $separator = '/', $append = false) + { + parent::embed($name, $value, $separator, $append); + + $this->deepInit($this->items); + + return $this; + } + + /** + * Merge two arrays by using blueprints. + * + * @param array $data1 + * @param array $data2 + * @param string|null $name Optional + * @param string $separator Optional + * @return array + */ + public function mergeData(array $data1, array $data2, $name = null, $separator = '.') + { + $this->initInternals(); + + return $this->blueprintSchema->mergeData($data1, $data2, $name, $separator); + } + + /** + * Process data coming from a form. + * + * @param array $data + * @param array $toggles + * @return array + */ + public function processForm(array $data, array $toggles = []) + { + $this->initInternals(); + + return $this->blueprintSchema->processForm($data, $toggles); + } + + /** + * Return data fields that do not exist in blueprints. + * + * @param array $data + * @param string $prefix + * @return array + */ + public function extra(array $data, $prefix = '') + { + $this->initInternals(); + + return $this->blueprintSchema->extra($data, $prefix); + } + + /** + * Validate data against blueprints. + * + * @param array $data + * @param array $options + * @return void + * @throws RuntimeException + */ + public function validate(array $data, array $options = []) + { + $this->initInternals(); + + $this->blueprintSchema->validate($data, $options); + } + + /** + * Filter data by using blueprints. + * + * @param array $data + * @param bool $missingValuesAsNull + * @param bool $keepEmptyValues + * @return array + */ + public function filter(array $data, bool $missingValuesAsNull = false, bool $keepEmptyValues = false) + { + $this->initInternals(); + + return $this->blueprintSchema->filter($data, $missingValuesAsNull, $keepEmptyValues) ?? []; + } + + + /** + * Flatten data by using blueprints. + * + * @param array $data Data to be flattened. + * @param bool $includeAll True if undefined properties should also be included. + * @param string $name Property which will be flattened, useful for flattening repeating data. + * @return array + */ + public function flattenData(array $data, bool $includeAll = false, string $name = '') + { + $this->initInternals(); + + return $this->blueprintSchema->flattenData($data, $includeAll, $name); + } + + + /** + * Return blueprint data schema. + * + * @return BlueprintSchema + */ + public function schema() + { + $this->initInternals(); + + return $this->blueprintSchema; + } + + /** + * @param string $name + * @param callable $callable + * @return void + */ + public function addDynamicHandler(string $name, callable $callable): void + { + $this->handlers[$name] = $callable; + } + + /** + * Initialize validator. + * + * @return void + */ + protected function initInternals() + { + if (null === $this->blueprintSchema) { + $types = Grav::instance()['plugins']->formFieldTypes; + + $this->blueprintSchema = new BlueprintSchema; + + if ($types) { + $this->blueprintSchema->setTypes($types); + } + + $this->blueprintSchema->embed('', $this->items); + $this->blueprintSchema->init(); + $this->defaults = null; + } + } + + /** + * @param string $filename + * @return array + */ + protected function loadFile($filename) + { + $file = CompiledYamlFile::instance($filename); + $content = (array)$file->content(); + $file->free(); + + return $content; + } + + /** + * @param string|array $path + * @param string|null $context + * @return array + */ + protected function getFiles($path, $context = null) + { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + + if (is_string($path) && !$locator->isStream($path)) { + if (is_file($path)) { + return [$path]; + } + + // Find path overrides. + if (null === $context) { + $paths = (array) ($this->overrides[$path] ?? null); + } else { + $paths = []; + } + + // Add path pointing to default context. + if ($context === null) { + $context = $this->context; + } + + if ($context && $context[strlen($context)-1] !== '/') { + $context .= '/'; + } + + $path = $context . $path; + + if (!preg_match('/\.yaml$/', $path)) { + $path .= '.yaml'; + } + + $paths[] = $path; + } else { + $paths = (array) $path; + } + + $files = []; + foreach ($paths as $lookup) { + if (is_string($lookup) && strpos($lookup, '://')) { + $files = array_merge($files, $locator->findResources($lookup)); + } else { + $files[] = $lookup; + } + } + + return array_values(array_unique($files)); + } + + /** + * @param array $field + * @param string $property + * @param array $call + * @return void + */ + protected function dynamicData(array &$field, $property, array &$call) + { + $params = $call['params']; + + if (is_array($params)) { + $function = array_shift($params); + } else { + $function = $params; + $params = []; + } + + [$o, $f] = explode('::', $function, 2); + + $data = null; + if (!$f) { + if (function_exists($o)) { + $data = call_user_func_array($o, $params); + } + } else { + if (method_exists($o, $f)) { + $data = call_user_func_array([$o, $f], $params); + } + } + + // If function returns a value, + if (null !== $data) { + if (is_array($data) && isset($field[$property]) && is_array($field[$property])) { + // Combine field and @data-field together. + $field[$property] += $data; + } else { + // Or create/replace field with @data-field. + $field[$property] = $data; + } + } + } + + /** + * @param array $field + * @param string $property + * @param array $call + * @return void + */ + protected function dynamicConfig(array &$field, $property, array &$call) + { + $params = $call['params']; + if (is_array($params)) { + $value = array_shift($params); + $params = array_shift($params); + } else { + $value = $params; + $params = []; + } + + $default = $field[$property] ?? null; + $config = Grav::instance()['config']->get($value, $default); + if (!empty($field['value_only'])) { + $config = array_combine($config, $config); + } + + if (null !== $config) { + if (!empty($params['append']) && is_array($config) && isset($field[$property]) && is_array($field[$property])) { + // Combine field and @config-field together. + $field[$property] += $config; + } else { + // Or create/replace field with @config-field. + $field[$property] = $config; + } + } + } + + /** + * @param array $field + * @param string $property + * @param array $call + * @return void + */ + protected function dynamicSecurity(array &$field, $property, array &$call) + { + if ($property || !empty($field['validate']['ignore'])) { + return; + } + + $grav = Grav::instance(); + $actions = (array)$call['params']; + + /** @var UserInterface|null $user */ + $user = $grav['user'] ?? null; + $success = null !== $user; + if ($success) { + $success = $this->resolveActions($user, $actions); + } + if (!$success) { + static::addPropertyRecursive($field, 'validate', ['ignore' => true]); + } + } + + /** + * @param UserInterface|null $user + * @param array $actions + * @param string $op + * @return bool + */ + protected function resolveActions(?UserInterface $user, array $actions, string $op = 'and') + { + if (null === $user) { + return false; + } + + $c = $i = count($actions); + foreach ($actions as $key => $action) { + if (!is_int($key) && is_array($actions)) { + $i -= $this->resolveActions($user, $action, $key); + } elseif ($user->authorize($action)) { + $i--; + } + } + + if ($op === 'and') { + return $i === 0; + } + + return $c !== $i; + } + + /** + * @param array $field + * @param string $property + * @param array $call + * @return void + */ + protected function dynamicScope(array &$field, $property, array &$call) + { + if ($property && $property !== 'ignore') { + return; + } + + $scopes = (array)$call['params']; + $matches = in_array($this->scope, $scopes, true); + if ($this->scope && $property !== 'ignore') { + $matches = !$matches; + } + + if ($matches) { + static::addPropertyRecursive($field, 'validate', ['ignore' => true]); + return; + } + } + + /** + * @param array $field + * @param string $property + * @param mixed $value + * @return void + */ + public static function addPropertyRecursive(array &$field, $property, $value) + { + if (is_array($value) && isset($field[$property]) && is_array($field[$property])) { + $field[$property] = array_merge_recursive($field[$property], $value); + } else { + $field[$property] = $value; + } + + if (!empty($field['fields'])) { + foreach ($field['fields'] as $key => &$child) { + static::addPropertyRecursive($child, $property, $value); + } + } + } +} diff --git a/system/src/Grav/Common/Data/BlueprintSchema.php b/system/src/Grav/Common/Data/BlueprintSchema.php new file mode 100644 index 0000000..1408cb6 --- /dev/null +++ b/system/src/Grav/Common/Data/BlueprintSchema.php @@ -0,0 +1,429 @@ + true, 'xss_check' => true]; + + /** @var array */ + protected $ignoreFormKeys = [ + 'title' => true, + 'help' => true, + 'placeholder' => true, + 'placeholder_key' => true, + 'placeholder_value' => true, + 'fields' => true + ]; + + /** + * @return array + */ + public function getTypes() + { + return $this->types; + } + + /** + * @param string $name + * @return array + */ + public function getType($name) + { + return $this->types[$name] ?? []; + } + + /** + * @param string $name + * @return array|null + */ + public function getNestedRules(string $name) + { + return $this->getNested($name); + } + + /** + * Validate data against blueprints. + * + * @param array $data + * @param array $options + * @return void + * @throws RuntimeException + */ + public function validate(array $data, array $options = []) + { + try { + $validation = $this->items['']['form']['validation'] ?? 'loose'; + $messages = $this->validateArray($data, $this->nested, $validation === 'strict', $options['xss_check'] ?? true); + } catch (RuntimeException $e) { + throw (new ValidationException($e->getMessage(), $e->getCode(), $e))->setMessages(); + } + + if (!empty($messages)) { + throw (new ValidationException('', 400))->setMessages($messages); + } + } + + /** + * @param array $data + * @param array $toggles + * @return array + */ + public function processForm(array $data, array $toggles = []) + { + return $this->processFormRecursive($data, $toggles, $this->nested) ?? []; + } + + /** + * Filter data by using blueprints. + * + * @param array $data Incoming data, for example from a form. + * @param bool $missingValuesAsNull Include missing values as nulls. + * @param bool $keepEmptyValues Include empty values. + * @return array + */ + public function filter(array $data, $missingValuesAsNull = false, $keepEmptyValues = false) + { + $this->buildIgnoreNested($this->nested); + + return $this->filterArray($data, $this->nested, '', $missingValuesAsNull, $keepEmptyValues) ?? []; + } + + /** + * Flatten data by using blueprints. + * + * @param array $data Data to be flattened. + * @param bool $includeAll True if undefined properties should also be included. + * @param string $name Property which will be flattened, useful for flattening repeating data. + * @return array + */ + public function flattenData(array $data, bool $includeAll = false, string $name = '') + { + $prefix = $name !== '' ? $name . '.' : ''; + + $list = []; + if ($includeAll) { + $items = $name !== '' ? $this->getProperty($name)['fields'] ?? [] : $this->items; + foreach ($items as $key => $rules) { + $type = $rules['type'] ?? ''; + $ignore = (bool) array_filter((array)($rules['validate']['ignore'] ?? [])) ?? false; + if (!str_starts_with($type, '_') && !str_contains($key, '*') && $ignore !== true) { + $list[$prefix . $key] = null; + } + } + } + + $nested = $this->getNestedRules($name); + + return array_replace($list, $this->flattenArray($data, $nested, $prefix)); + } + + /** + * @param array $data + * @param array $rules + * @param string $prefix + * @return array + */ + protected function flattenArray(array $data, array $rules, string $prefix) + { + $array = []; + + foreach ($data as $key => $field) { + $val = $rules[$key] ?? $rules['*'] ?? null; + $rule = is_string($val) ? $this->items[$val] : null; + + if ($rule || isset($val['*'])) { + // Item has been defined in blueprints. + $array[$prefix.$key] = $field; + } elseif (is_array($field) && is_array($val)) { + // Array has been defined in blueprints. + $array += $this->flattenArray($field, $val, $prefix . $key . '.'); + } else { + // Undefined/extra item. + $array[$prefix.$key] = $field; + } + } + + return $array; + } + + /** + * @param array $data + * @param array $rules + * @param bool $strict + * @param bool $xss + * @return array + * @throws RuntimeException + */ + protected function validateArray(array $data, array $rules, bool $strict, bool $xss = true) + { + $messages = $this->checkRequired($data, $rules); + + foreach ($data as $key => $child) { + $val = $rules[$key] ?? $rules['*'] ?? null; + $rule = is_string($val) ? $this->items[$val] : null; + $checkXss = $xss; + + if ($rule) { + // Item has been defined in blueprints. + if (!empty($rule['disabled']) || !empty($rule['validate']['ignore'])) { + // Skip validation in the ignored field. + continue; + } + + $messages += Validation::validate($child, $rule); + + } elseif (is_array($child) && is_array($val)) { + // Array has been defined in blueprints. + $messages += $this->validateArray($child, $val, $strict); + $checkXss = false; + + } elseif ($strict) { + // Undefined/extra item in strict mode. + /** @var Config $config */ + $config = Grav::instance()['config']; + if (!$config->get('system.strict_mode.blueprint_strict_compat', true)) { + throw new RuntimeException(sprintf('%s is not defined in blueprints', $key), 400); + } + + user_error(sprintf('Having extra key %s in your data is deprecated with blueprint having \'validation: strict\'', $key), E_USER_DEPRECATED); + } + + if ($checkXss) { + $messages += Validation::checkSafety($child, $rule ?: ['name' => $key]); + } + } + + return $messages; + } + + /** + * @param array $data + * @param array $rules + * @param string $parent + * @param bool $missingValuesAsNull + * @param bool $keepEmptyValues + * @return array|null + */ + protected function filterArray(array $data, array $rules, string $parent, bool $missingValuesAsNull, bool $keepEmptyValues) + { + $results = []; + + foreach ($data as $key => $field) { + $val = $rules[$key] ?? $rules['*'] ?? null; + $rule = is_string($val) ? $this->items[$val] : $this->items[$parent . $key] ?? null; + + if (!empty($rule['disabled']) || !empty($rule['validate']['ignore'])) { + // Skip any data in the ignored field. + unset($results[$key]); + continue; + } + + if (null === $field) { + if ($missingValuesAsNull) { + $results[$key] = null; + } else { + unset($results[$key]); + } + continue; + } + + $isParent = isset($val['*']); + $type = $rule['type'] ?? null; + + if (!$isParent && $type && $type !== '_parent') { + $field = Validation::filter($field, $rule); + } elseif (is_array($field) && is_array($val)) { + // Array has been defined in blueprints. + $k = $isParent ? '*' : $key; + $field = $this->filterArray($field, $val, $parent . $k . '.', $missingValuesAsNull, $keepEmptyValues); + + if (null === $field) { + // Nested parent has no values. + unset($results[$key]); + continue; + } + } elseif (isset($rules['validation']) && $rules['validation'] === 'strict') { + // Skip any extra data. + continue; + } + + if ($keepEmptyValues || (null !== $field && (!is_array($field) || !empty($field)))) { + $results[$key] = $field; + } + } + + return $results ?: null; + } + + /** + * @param array $nested + * @param string $parent + * @return bool + */ + protected function buildIgnoreNested(array $nested, $parent = '') + { + $ignore = true; + foreach ($nested as $key => $val) { + $key = $parent . $key; + if (is_array($val)) { + $ignore = $this->buildIgnoreNested($val, $key . '.') && $ignore; // Keep the order! + } else { + $child = $this->items[$key] ?? null; + $ignore = $ignore && (!$child || !empty($child['disabled']) || !empty($child['validate']['ignore'])); + } + } + if ($ignore) { + $key = trim($parent, '.'); + $this->items[$key]['validate']['ignore'] = true; + } + + return $ignore; + } + + /** + * @param array|null $data + * @param array $toggles + * @param array $nested + * @return array|null + */ + protected function processFormRecursive(?array $data, array $toggles, array $nested) + { + foreach ($nested as $key => $value) { + if ($key === '') { + continue; + } + if ($key === '*') { + // TODO: Add support to collections. + continue; + } + if (is_array($value)) { + // Special toggle handling for all the nested data. + $toggle = $toggles[$key] ?? []; + if (!is_array($toggle)) { + if (!$toggle) { + $data[$key] = null; + + continue; + } + + $toggle = []; + } + // Recursively fetch the items. + $childData = $data[$key] ?? null; + if (null !== $childData && !is_array($childData)) { + throw new \RuntimeException(sprintf("Bad form data for field collection '%s': %s used instead of an array", $key, gettype($childData))); + } + $data[$key] = $this->processFormRecursive($data[$key] ?? null, $toggle, $value); + } else { + $field = $this->get($value); + // Do not add the field if: + if ( + // Not an input field + !$field + // Field has been disabled + || !empty($field['disabled']) + // Field validation is set to be ignored + || !empty($field['validate']['ignore']) + // Field is overridable and the toggle is turned off + || (!empty($field['overridable']) && empty($toggles[$key])) + ) { + continue; + } + if (!isset($data[$key])) { + $data[$key] = null; + } + } + } + + return $data; + } + + /** + * @param array $data + * @param array $fields + * @return array + */ + protected function checkRequired(array $data, array $fields) + { + $messages = []; + + foreach ($fields as $name => $field) { + if (!is_string($field)) { + continue; + } + + $field = $this->items[$field]; + + // Skip ignored field, it will not be required. + if (!empty($field['disabled']) || !empty($field['validate']['ignore'])) { + continue; + } + + // Skip overridable fields without value. + // TODO: We need better overridable support, which is not just ignoring required values but also looking if defaults are good. + if (!empty($field['overridable']) && !isset($data[$name])) { + continue; + } + + // Check if required. + if (isset($field['validate']['required']) + && $field['validate']['required'] === true) { + if (isset($data[$name])) { + continue; + } + if ($field['type'] === 'file' && isset($data['data']['name'][$name])) { //handle case of file input fields required + continue; + } + + $value = $field['label'] ?? $field['name']; + $language = Grav::instance()['language']; + $message = sprintf($language->translate('GRAV.FORM.MISSING_REQUIRED_FIELD', null, true) . ' %s', $language->translate($value)); + $messages[$field['name']][] = $message; + } + } + + return $messages; + } + + /** + * @param array $field + * @param string $property + * @param array $call + * @return void + */ + protected function dynamicConfig(array &$field, $property, array &$call) + { + $value = $call['params']; + + $default = $field[$property] ?? null; + $config = Grav::instance()['config']->get($value, $default); + + if (null !== $config) { + $field[$property] = $config; + } + } +} diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php new file mode 100644 index 0000000..5534a19 --- /dev/null +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -0,0 +1,121 @@ +search = $search; + } + + /** + * Get blueprint. + * + * @param string $type Blueprint type. + * @return Blueprint + * @throws RuntimeException + */ + public function get($type) + { + if (!isset($this->instances[$type])) { + $blueprint = $this->loadFile($type); + $this->instances[$type] = $blueprint; + } + + return $this->instances[$type]; + } + + /** + * Get all available blueprint types. + * + * @return array List of type=>name + */ + public function types() + { + if ($this->types === null) { + $this->types = []; + + $grav = Grav::instance(); + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + + // Get stream / directory iterator. + if ($locator->isStream($this->search)) { + $iterator = $locator->getIterator($this->search); + } else { + $iterator = new DirectoryIterator($this->search); + } + + foreach ($iterator as $file) { + if (!$file->isFile() || '.' . $file->getExtension() !== YAML_EXT) { + continue; + } + $name = $file->getBasename(YAML_EXT); + $this->types[$name] = ucfirst(str_replace('_', ' ', $name)); + } + } + + return $this->types; + } + + + /** + * Load blueprint file. + * + * @param string $name Name of the blueprint. + * @return Blueprint + */ + protected function loadFile($name) + { + $blueprint = new Blueprint($name); + + if (is_array($this->search) || is_object($this->search)) { + // Page types. + $blueprint->setOverrides($this->search); + $blueprint->setContext('blueprints://pages'); + } else { + $blueprint->setContext($this->search); + } + + try { + $blueprint->load()->init(); + } catch (RuntimeException $e) { + $log = Grav::instance()['log']; + $log->error(sprintf('Blueprint %s cannot be loaded: %s', $name, $e->getMessage())); + + throw $e; + } + + return $blueprint; + } +} diff --git a/system/src/Grav/Common/Data/Data.php b/system/src/Grav/Common/Data/Data.php new file mode 100644 index 0000000..95944b2 --- /dev/null +++ b/system/src/Grav/Common/Data/Data.php @@ -0,0 +1,343 @@ +items = $items; + if (null !== $blueprints) { + $this->blueprints = $blueprints; + } + } + + /** + * @param bool $value + * @return $this + */ + public function setKeepEmptyValues(bool $value) + { + $this->keepEmptyValues = $value; + + return $this; + } + + /** + * @param bool $value + * @return $this + */ + public function setMissingValuesAsNull(bool $value) + { + $this->missingValuesAsNull = $value; + + return $this; + } + + /** + * Get value by using dot notation for nested arrays/objects. + * + * @example $value = $data->value('this.is.my.nested.variable'); + * + * @param string $name Dot separated path to the requested value. + * @param mixed $default Default value (or null). + * @param string $separator Separator, defaults to '.' + * @return mixed Value. + */ + public function value($name, $default = null, $separator = '.') + { + return $this->get($name, $default, $separator); + } + + /** + * Join nested values together by using blueprints. + * + * @param string $name Dot separated path to the requested value. + * @param mixed $value Value to be joined. + * @param string $separator Separator, defaults to '.' + * @return $this + * @throws RuntimeException + */ + public function join($name, $value, $separator = '.') + { + $old = $this->get($name, null, $separator); + if ($old !== null) { + if (!is_array($old)) { + throw new RuntimeException('Value ' . $old); + } + + if (is_object($value)) { + $value = (array) $value; + } elseif (!is_array($value)) { + throw new RuntimeException('Value ' . $value); + } + + $value = $this->blueprints()->mergeData($old, $value, $name, $separator); + } + + $this->set($name, $value, $separator); + + return $this; + } + + /** + * Get nested structure containing default values defined in the blueprints. + * + * Fields without default value are ignored in the list. + + * @return array + */ + public function getDefaults() + { + return $this->blueprints()->getDefaults(); + } + + /** + * Set default values by using blueprints. + * + * @param string $name Dot separated path to the requested value. + * @param mixed $value Value to be joined. + * @param string $separator Separator, defaults to '.' + * @return $this + */ + public function joinDefaults($name, $value, $separator = '.') + { + if (is_object($value)) { + $value = (array) $value; + } + + $old = $this->get($name, null, $separator); + if ($old !== null) { + $value = $this->blueprints()->mergeData($value, $old, $name, $separator); + } + + $this->set($name, $value, $separator); + + return $this; + } + + /** + * Get value from the configuration and join it with given data. + * + * @param string $name Dot separated path to the requested value. + * @param array|object $value Value to be joined. + * @param string $separator Separator, defaults to '.' + * @return array + * @throws RuntimeException + */ + public function getJoined($name, $value, $separator = '.') + { + if (is_object($value)) { + $value = (array) $value; + } elseif (!is_array($value)) { + throw new RuntimeException('Value ' . $value); + } + + $old = $this->get($name, null, $separator); + + if ($old === null) { + // No value set; no need to join data. + return $value; + } + + if (!is_array($old)) { + throw new RuntimeException('Value ' . $old); + } + + // Return joined data. + return $this->blueprints()->mergeData($old, $value, $name, $separator); + } + + + /** + * Merge two configurations together. + * + * @param array $data + * @return $this + */ + public function merge(array $data) + { + $this->items = $this->blueprints()->mergeData($this->items, $data); + + return $this; + } + + /** + * Set default values to the configuration if variables were not set. + * + * @param array $data + * @return $this + */ + public function setDefaults(array $data) + { + $this->items = $this->blueprints()->mergeData($data, $this->items); + + return $this; + } + + /** + * Validate by blueprints. + * + * @return $this + * @throws Exception + */ + public function validate() + { + $this->blueprints()->validate($this->items); + + return $this; + } + + /** + * @return $this + */ + public function filter() + { + $args = func_get_args(); + $missingValuesAsNull = (bool)(array_shift($args) ?? $this->missingValuesAsNull); + $keepEmptyValues = (bool)(array_shift($args) ?? $this->keepEmptyValues); + + $this->items = $this->blueprints()->filter($this->items, $missingValuesAsNull, $keepEmptyValues); + + return $this; + } + + /** + * Get extra items which haven't been defined in blueprints. + * + * @return array + */ + public function extra() + { + return $this->blueprints()->extra($this->items); + } + + /** + * Return blueprints. + * + * @return Blueprint + */ + public function blueprints() + { + if (null === $this->blueprints) { + $this->blueprints = new Blueprint(); + } elseif (is_callable($this->blueprints)) { + // Lazy load blueprints. + $blueprints = $this->blueprints; + $this->blueprints = $blueprints(); + } + + return $this->blueprints; + } + + /** + * Save data if storage has been defined. + * + * @return void + * @throws RuntimeException + */ + public function save() + { + $file = $this->file(); + if ($file) { + $file->save($this->items); + } + } + + /** + * Returns whether the data already exists in the storage. + * + * NOTE: This method does not check if the data is current. + * + * @return bool + */ + public function exists() + { + $file = $this->file(); + + return $file && $file->exists(); + } + + /** + * Return unmodified data as raw string. + * + * NOTE: This function only returns data which has been saved to the storage. + * + * @return string + */ + public function raw() + { + $file = $this->file(); + + return $file ? $file->raw() : ''; + } + + /** + * Set or get the data storage. + * + * @param FileInterface|null $storage Optionally enter a new storage. + * @return FileInterface|null + */ + public function file(FileInterface $storage = null) + { + if ($storage) { + $this->storage = $storage; + } + + return $this->storage; + } + + /** + * @return array + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return $this->items; + } +} diff --git a/system/src/Grav/Common/Data/DataInterface.php b/system/src/Grav/Common/Data/DataInterface.php new file mode 100644 index 0000000..52469b1 --- /dev/null +++ b/system/src/Grav/Common/Data/DataInterface.php @@ -0,0 +1,84 @@ +value('this.is.my.nested.variable'); + * + * @param string $name Dot separated path to the requested value. + * @param mixed $default Default value (or null). + * @param string $separator Separator, defaults to '.' + * @return mixed Value. + */ + public function value($name, $default = null, $separator = '.'); + + /** + * Merge external data. + * + * @param array $data + * @return mixed + */ + public function merge(array $data); + + /** + * Return blueprints. + * + * @return Blueprint + */ + public function blueprints(); + + /** + * Validate by blueprints. + * + * @return $this + * @throws Exception + */ + public function validate(); + + /** + * Filter all items by using blueprints. + * + * @return $this + */ + public function filter(); + + /** + * Get extra items which haven't been defined in blueprints. + * + * @return array + */ + public function extra(); + + /** + * Save data into the file. + * + * @return void + */ + public function save(); + + /** + * Set or get the data storage. + * + * @param FileInterface|null $storage Optionally enter a new storage. + * @return FileInterface + */ + public function file(FileInterface $storage = null); +} diff --git a/system/src/Grav/Common/Data/Validation.php b/system/src/Grav/Common/Data/Validation.php new file mode 100644 index 0000000..d0f5bff --- /dev/null +++ b/system/src/Grav/Common/Data/Validation.php @@ -0,0 +1,1236 @@ +translate($field['validate']['message']) + : $language->translate('GRAV.FORM.INVALID_INPUT') . ' "' . $language->translate($name) . '"'; + + + // Validate type with fallback type text. + $method = 'type' . str_replace('-', '_', $type); + + // If this is a YAML field validate/filter as such + if (isset($field['yaml']) && $field['yaml'] === true) { + $method = 'typeYaml'; + } + + $messages = []; + + $success = method_exists(__CLASS__, $method) ? self::$method($value, $validate, $field) : true; + if (!$success) { + $messages[$field['name']][] = $message; + } + + // Check individual rules. + foreach ($validate as $rule => $params) { + $method = 'validate' . ucfirst(str_replace('-', '_', $rule)); + + if (method_exists(__CLASS__, $method)) { + $success = self::$method($value, $params); + + if (!$success) { + $messages[$field['name']][] = $message; + } + } + } + + return $messages; + } + + /** + * @param mixed $value + * @param array $field + * @return array + */ + public static function checkSafety($value, array $field) + { + $messages = []; + + $type = $field['validate']['type'] ?? $field['type'] ?? 'text'; + $options = $field['xss_check'] ?? []; + if ($options === false || $type === 'unset') { + return $messages; + } + if (!is_array($options)) { + $options = []; + } + + $name = ucfirst($field['label'] ?? $field['name'] ?? 'UNKNOWN'); + + /** @var UserInterface $user */ + $user = Grav::instance()['user'] ?? null; + /** @var Config $config */ + $config = Grav::instance()['config']; + + $xss_whitelist = $config->get('security.xss_whitelist', 'admin.super'); + + // Get language class. + /** @var Language $language */ + $language = Grav::instance()['language']; + + if (!static::authorize($xss_whitelist, $user)) { + $defaults = Security::getXssDefaults(); + $options += $defaults; + $options['enabled_rules'] += $defaults['enabled_rules']; + if (!empty($options['safe_protocols'])) { + $options['invalid_protocols'] = array_diff($options['invalid_protocols'], $options['safe_protocols']); + } + if (!empty($options['safe_tags'])) { + $options['dangerous_tags'] = array_diff($options['dangerous_tags'], $options['safe_tags']); + } + + if (is_string($value)) { + $violation = Security::detectXss($value, $options); + if ($violation) { + $messages[$name][] = $language->translate(['GRAV.FORM.XSS_ISSUES', $language->translate($name)], null, true); + } + } elseif (is_array($value)) { + $violations = Security::detectXssFromArray($value, "{$name}.", $options); + if ($violations) { + $messages[$name][] = $language->translate(['GRAV.FORM.XSS_ISSUES', $language->translate($name)], null, true); + } + } + } + + return $messages; + } + + /** + * Checks user authorisation to the action. + * + * @param string|string[] $action + * @param UserInterface|null $user + * @return bool + */ + public static function authorize($action, UserInterface $user = null) + { + if (!$user) { + return false; + } + + $action = (array)$action; + foreach ($action as $a) { + // Ignore 'admin.super' if it's not the only value to be checked. + if ($a === 'admin.super' && count($action) > 1 && $user instanceof FlexObjectInterface) { + continue; + } + + if ($user->authorize($a)) { + return true; + } + } + + return false; + } + + /** + * Filter value against a blueprint field definition. + * + * @param mixed $value + * @param array $field + * @return mixed Filtered value. + */ + public static function filter($value, array $field) + { + $validate = (array)($field['filter'] ?? $field['validate'] ?? null); + + // If value isn't required, we will return null if empty value is given. + if (($value === null || $value === '') && empty($validate['required'])) { + return null; + } + + if (!isset($field['type'])) { + $field['type'] = 'text'; + } + $type = $field['filter']['type'] ?? $field['validate']['type'] ?? $field['type']; + + $method = 'filter' . ucfirst(str_replace('-', '_', $type)); + + // If this is a YAML field validate/filter as such + if (isset($field['yaml']) && $field['yaml'] === true) { + $method = 'filterYaml'; + } + + if (!method_exists(__CLASS__, $method)) { + $method = isset($field['array']) && $field['array'] === true ? 'filterArray' : 'filterText'; + } + + return self::$method($value, $validate, $field); + } + + /** + * HTML5 input: text + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeText($value, array $params, array $field) + { + if (!is_string($value) && !is_numeric($value)) { + return false; + } + + $value = (string)$value; + + if (!empty($params['trim'])) { + $value = trim($value); + } + + $value = preg_replace("/\r\n|\r/um", "\n", $value); + $len = mb_strlen($value); + + $min = (int)($params['min'] ?? 0); + if ($min && $len < $min) { + return false; + } + + $multiline = isset($params['multiline']) && $params['multiline']; + + $max = (int)($params['max'] ?? ($multiline ? 65536 : 2048)); + if ($max && $len > $max) { + return false; + } + + $step = (int)($params['step'] ?? 0); + if ($step && ($len - $min) % $step === 0) { + return false; + } + + if (!$multiline && preg_match('/\R/um', $value)) { + return false; + } + + return true; + } + + /** + * @param mixed $value + * @param array $params + * @param array $field + * @return string + */ + protected static function filterText($value, array $params, array $field) + { + if (!is_string($value) && !is_numeric($value)) { + return ''; + } + + $value = (string)$value; + + if (!empty($params['trim'])) { + $value = trim($value); + } + + return preg_replace("/\r\n|\r/um", "\n", $value); + } + + /** + * @param mixed $value + * @param array $params + * @param array $field + * @return string|null + */ + protected static function filterCheckbox($value, array $params, array $field) + { + $value = (string)$value; + $field_value = (string)($field['value'] ?? '1'); + + return $value === $field_value ? $value : null; + } + + /** + * @param mixed $value + * @param array $params + * @param array $field + * @return array|array[]|false|string[] + */ + protected static function filterCommaList($value, array $params, array $field) + { + return is_array($value) ? $value : preg_split('/\s*,\s*/', $value, -1, PREG_SPLIT_NO_EMPTY); + } + + /** + * @param mixed $value + * @param array $params + * @param array $field + * @return bool + */ + public static function typeCommaList($value, array $params, array $field) + { + if (!isset($params['max'])) { + $params['max'] = 2048; + } + + return is_array($value) ? true : self::typeText($value, $params, $field); + } + + /** + * @param mixed $value + * @param array $params + * @param array $field + * @return array|array[]|false|string[] + */ + protected static function filterLines($value, array $params, array $field) + { + return is_array($value) ? $value : preg_split('/\s*[\r\n]+\s*/', $value, -1, PREG_SPLIT_NO_EMPTY); + } + + /** + * @param mixed $value + * @param array $params + * @return string + */ + protected static function filterLower($value, array $params) + { + return mb_strtolower($value); + } + + /** + * @param mixed $value + * @param array $params + * @return string + */ + protected static function filterUpper($value, array $params) + { + return mb_strtoupper($value); + } + + + /** + * HTML5 input: textarea + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeTextarea($value, array $params, array $field) + { + if (!isset($params['multiline'])) { + $params['multiline'] = true; + } + + return self::typeText($value, $params, $field); + } + + /** + * HTML5 input: password + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typePassword($value, array $params, array $field) + { + if (!isset($params['max'])) { + $params['max'] = 256; + } + + return self::typeText($value, $params, $field); + } + + /** + * HTML5 input: hidden + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeHidden($value, array $params, array $field) + { + return self::typeText($value, $params, $field); + } + + /** + * Custom input: checkbox list + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeCheckboxes($value, array $params, array $field) + { + // Set multiple: true so checkboxes can easily use min/max counts to control number of options required + $field['multiple'] = true; + + return self::typeArray((array) $value, $params, $field); + } + + /** + * @param mixed $value + * @param array $params + * @param array $field + * @return array|null + */ + protected static function filterCheckboxes($value, array $params, array $field) + { + return self::filterArray($value, $params, $field); + } + + /** + * HTML5 input: checkbox + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeCheckbox($value, array $params, array $field) + { + $value = (string)$value; + $field_value = (string)($field['value'] ?? '1'); + + return $value === $field_value; + } + + /** + * HTML5 input: radio + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeRadio($value, array $params, array $field) + { + return self::typeArray((array) $value, $params, $field); + } + + /** + * Custom input: toggle + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeToggle($value, array $params, array $field) + { + if (is_bool($value)) { + $value = (int)$value; + } + + return self::typeArray((array) $value, $params, $field); + } + + /** + * Custom input: file + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeFile($value, array $params, array $field) + { + return self::typeArray((array)$value, $params, $field); + } + + /** + * @param mixed $value + * @param array $params + * @param array $field + * @return array + */ + protected static function filterFile($value, array $params, array $field) + { + return (array)$value; + } + + /** + * HTML5 input: select + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeSelect($value, array $params, array $field) + { + return self::typeArray((array) $value, $params, $field); + } + + /** + * HTML5 input: number + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeNumber($value, array $params, array $field) + { + if (!is_numeric($value)) { + return false; + } + + $value = (float)$value; + + $min = 0; + if (isset($params['min'])) { + $min = (float)$params['min']; + if ($value < $min) { + return false; + } + } + + if (isset($params['max'])) { + $max = (float)$params['max']; + if ($value > $max) { + return false; + } + } + + if (isset($params['step'])) { + $step = (float)$params['step']; + // Count of how many steps we are above/below the minimum value. + $pos = ($value - $min) / $step; + $pos = round($pos, 10); + return is_int(static::filterNumber($pos, $params, $field)); + } + + return true; + } + + /** + * @param mixed $value + * @param array $params + * @param array $field + * @return float|int + */ + protected static function filterNumber($value, array $params, array $field) + { + return (string)(int)$value !== (string)(float)$value ? (float)$value : (int)$value; + } + + /** + * @param mixed $value + * @param array $params + * @param array $field + * @return string + */ + protected static function filterDateTime($value, array $params, array $field) + { + $format = Grav::instance()['config']->get('system.pages.dateformat.default'); + if ($format) { + $converted = new DateTime($value); + return $converted->format($format); + } + return $value; + } + + /** + * HTML5 input: range + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeRange($value, array $params, array $field) + { + return self::typeNumber($value, $params, $field); + } + + /** + * @param mixed $value + * @param array $params + * @param array $field + * @return float|int + */ + protected static function filterRange($value, array $params, array $field) + { + return self::filterNumber($value, $params, $field); + } + + /** + * HTML5 input: color + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeColor($value, array $params, array $field) + { + return (bool)preg_match('/^\#[0-9a-fA-F]{3}[0-9a-fA-F]{3}?$/u', $value); + } + + /** + * HTML5 input: email + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeEmail($value, array $params, array $field) + { + if (empty($value)) { + return false; + } + + if (!isset($params['max'])) { + $params['max'] = 320; + } + + $values = !is_array($value) ? explode(',', preg_replace('/\s+/', '', $value)) : $value; + + foreach ($values as $val) { + if (!(self::typeText($val, $params, $field) && strpos($val, '@', 1))) { + return false; + } + } + + return true; + } + + /** + * HTML5 input: url + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeUrl($value, array $params, array $field) + { + if (!isset($params['max'])) { + $params['max'] = 2048; + } + + return self::typeText($value, $params, $field) && filter_var($value, FILTER_VALIDATE_URL); + } + + /** + * HTML5 input: datetime + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeDatetime($value, array $params, array $field) + { + if ($value instanceof DateTime) { + return true; + } + if (!is_string($value)) { + return false; + } + if (!isset($params['format'])) { + return false !== strtotime($value); + } + + $dateFromFormat = DateTime::createFromFormat($params['format'], $value); + + return $dateFromFormat && $value === date($params['format'], $dateFromFormat->getTimestamp()); + } + + /** + * HTML5 input: datetime-local + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeDatetimeLocal($value, array $params, array $field) + { + return self::typeDatetime($value, $params, $field); + } + + /** + * HTML5 input: date + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeDate($value, array $params, array $field) + { + if (!isset($params['format'])) { + $params['format'] = 'Y-m-d'; + } + + return self::typeDatetime($value, $params, $field); + } + + /** + * HTML5 input: time + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeTime($value, array $params, array $field) + { + if (!isset($params['format'])) { + $params['format'] = 'H:i'; + } + + return self::typeDatetime($value, $params, $field); + } + + /** + * HTML5 input: month + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeMonth($value, array $params, array $field) + { + if (!isset($params['format'])) { + $params['format'] = 'Y-m'; + } + + return self::typeDatetime($value, $params, $field); + } + + /** + * HTML5 input: week + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeWeek($value, array $params, array $field) + { + if (!isset($params['format']) && !preg_match('/^\d{4}-W\d{2}$/u', $value)) { + return false; + } + + return self::typeDatetime($value, $params, $field); + } + + /** + * Custom input: array + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeArray($value, array $params, array $field) + { + if (!is_array($value)) { + return false; + } + + if (isset($field['multiple'])) { + if (isset($params['min']) && count($value) < $params['min']) { + return false; + } + + if (isset($params['max']) && count($value) > $params['max']) { + return false; + } + + $min = $params['min'] ?? 0; + if (isset($params['step']) && (count($value) - $min) % $params['step'] === 0) { + return false; + } + } + + // If creating new values is allowed, no further checks are needed. + $validateOptions = $field['validate']['options'] ?? null; + if (!empty($field['selectize']['create']) || $validateOptions === 'ignore') { + return true; + } + + $options = $field['options'] ?? []; + $use = $field['use'] ?? 'values'; + + if ($validateOptions) { + // Use custom options structure. + foreach ($options as &$option) { + $option = $option[$validateOptions] ?? null; + } + unset($option); + $options = array_values($options); + } elseif (empty($field['selectize']) || empty($field['multiple'])) { + $options = array_keys($options); + } + if ($use === 'keys') { + $value = array_keys($value); + } + + return !($options && array_diff($value, $options)); + } + + /** + * @param mixed $value + * @param array $params + * @param array $field + * @return array|null + */ + protected static function filterFlatten_array($value, $params, $field) + { + $value = static::filterArray($value, $params, $field); + + return is_array($value) ? Utils::arrayUnflattenDotNotation($value) : null; + } + + /** + * @param mixed $value + * @param array $params + * @param array $field + * @return array|null + */ + protected static function filterArray($value, $params, $field) + { + $values = (array) $value; + $options = isset($field['options']) ? array_keys($field['options']) : []; + $multi = $field['multiple'] ?? false; + + if (count($values) === 1 && isset($values[0]) && $values[0] === '') { + return null; + } + + + if ($options) { + $useKey = isset($field['use']) && $field['use'] === 'keys'; + foreach ($values as $key => $val) { + $values[$key] = $useKey ? (bool) $val : $val; + } + } + + if ($multi) { + foreach ($values as $key => $val) { + if (is_array($val)) { + $val = implode(',', $val); + $values[$key] = array_map('trim', explode(',', $val)); + } else { + $values[$key] = trim($val); + } + } + } + + $ignoreEmpty = isset($field['ignore_empty']) && Utils::isPositive($field['ignore_empty']); + $valueType = $params['value_type'] ?? null; + $keyType = $params['key_type'] ?? null; + if ($ignoreEmpty || $valueType || $keyType) { + $values = static::arrayFilterRecurse($values, ['value_type' => $valueType, 'key_type' => $keyType, 'ignore_empty' => $ignoreEmpty]); + } + + return $values; + } + + /** + * @param array $values + * @param array $params + * @return array + */ + protected static function arrayFilterRecurse(array $values, array $params): array + { + foreach ($values as $key => &$val) { + if ($params['key_type']) { + switch ($params['key_type']) { + case 'int': + $result = is_int($key); + break; + case 'string': + $result = is_string($key); + break; + default: + $result = false; + } + if (!$result) { + unset($values[$key]); + } + } + if (is_array($val)) { + $val = static::arrayFilterRecurse($val, $params); + if ($params['ignore_empty'] && empty($val)) { + unset($values[$key]); + } + } else { + if ($params['value_type'] && $val !== '' && $val !== null) { + switch ($params['value_type']) { + case 'bool': + if (Utils::isPositive($val)) { + $val = true; + } elseif (Utils::isNegative($val)) { + $val = false; + } else { + // Ignore invalid bool values. + $val = null; + } + break; + case 'int': + $val = (int)$val; + break; + case 'float': + $val = (float)$val; + break; + case 'string': + $val = (string)$val; + break; + case 'trim': + $val = trim($val); + break; + } + } + + if ($params['ignore_empty'] && ($val === '' || $val === null)) { + unset($values[$key]); + } + } + } + + return $values; + } + + /** + * @param mixed $value + * @param array $params + * @param array $field + * @return bool + */ + public static function typeList($value, array $params, array $field) + { + if (!is_array($value)) { + return false; + } + + if (isset($field['fields'])) { + foreach ($value as $key => $item) { + foreach ($field['fields'] as $subKey => $subField) { + $subKey = trim($subKey, '.'); + $subValue = $item[$subKey] ?? null; + self::validate($subValue, $subField); + } + } + } + + return true; + } + + /** + * @param mixed $value + * @param array $params + * @param array $field + * @return array + */ + protected static function filterList($value, array $params, array $field) + { + return (array) $value; + } + + /** + * @param mixed $value + * @param array $params + * @return array + */ + public static function filterYaml($value, $params) + { + if (!is_string($value)) { + return $value; + } + + return (array) Yaml::parse($value); + } + + /** + * Custom input: ignore (will not validate) + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeIgnore($value, array $params, array $field) + { + return true; + } + + /** + * @param mixed $value + * @param array $params + * @param array $field + * @return mixed + */ + public static function filterIgnore($value, array $params, array $field) + { + return $value; + } + + /** + * Input value which can be ignored. + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeUnset($value, array $params, array $field) + { + return true; + } + + /** + * @param mixed $value + * @param array $params + * @param array $field + * @return null + */ + public static function filterUnset($value, array $params, array $field) + { + return null; + } + + // HTML5 attributes (min, max and range are handled inside the types) + + /** + * @param mixed $value + * @param bool $params + * @return bool + */ + public static function validateRequired($value, $params) + { + if (is_scalar($value)) { + return (bool) $params !== true || $value !== ''; + } + + return (bool) $params !== true || !empty($value); + } + + /** + * @param mixed $value + * @param string $params + * @return bool + */ + public static function validatePattern($value, $params) + { + return (bool) preg_match("`^{$params}$`u", $value); + } + + // Internal types + + /** + * @param mixed $value + * @param mixed $params + * @return bool + */ + public static function validateAlpha($value, $params) + { + return ctype_alpha($value); + } + + /** + * @param mixed $value + * @param mixed $params + * @return bool + */ + public static function validateAlnum($value, $params) + { + return ctype_alnum($value); + } + + /** + * @param mixed $value + * @param mixed $params + * @return bool + */ + public static function typeBool($value, $params) + { + return is_bool($value) || $value == 1 || $value == 0; + } + + /** + * @param mixed $value + * @param mixed $params + * @return bool + */ + public static function validateBool($value, $params) + { + return is_bool($value) || $value == 1 || $value == 0; + } + + /** + * @param mixed $value + * @param mixed $params + * @return bool + */ + protected static function filterBool($value, $params) + { + return (bool) $value; + } + + /** + * @param mixed $value + * @param mixed $params + * @return bool + */ + public static function validateDigit($value, $params) + { + return ctype_digit($value); + } + + /** + * @param mixed $value + * @param mixed $params + * @return bool + */ + public static function validateFloat($value, $params) + { + return is_float(filter_var($value, FILTER_VALIDATE_FLOAT)); + } + + /** + * @param mixed $value + * @param mixed $params + * @return float + */ + protected static function filterFloat($value, $params) + { + return (float) $value; + } + + /** + * @param mixed $value + * @param mixed $params + * @return bool + */ + public static function validateHex($value, $params) + { + return ctype_xdigit($value); + } + + /** + * Custom input: int + * + * @param mixed $value Value to be validated. + * @param array $params Validation parameters. + * @param array $field Blueprint for the field. + * @return bool True if validation succeeded. + */ + public static function typeInt($value, array $params, array $field) + { + $params['step'] = max(1, (int)($params['step'] ?? 0)); + + return self::typeNumber($value, $params, $field); + } + + /** + * @param mixed $value + * @param mixed $params + * @return bool + */ + public static function validateInt($value, $params) + { + return is_numeric($value) && (int)$value == $value; + } + + /** + * @param mixed $value + * @param mixed $params + * @return int + */ + protected static function filterInt($value, $params) + { + return (int)$value; + } + + /** + * @param mixed $value + * @param mixed $params + * @return bool + */ + public static function validateArray($value, $params) + { + return is_array($value) || ($value instanceof ArrayAccess && $value instanceof Traversable && $value instanceof Countable); + } + + /** + * @param mixed $value + * @param mixed $params + * @return array + */ + public static function filterItem_List($value, $params) + { + return array_values(array_filter($value, static function ($v) { + return !empty($v); + })); + } + + /** + * @param mixed $value + * @param mixed $params + * @return bool + */ + public static function validateJson($value, $params) + { + return (bool) (@json_decode($value)); + } +} diff --git a/system/src/Grav/Common/Data/ValidationException.php b/system/src/Grav/Common/Data/ValidationException.php new file mode 100644 index 0000000..72570a1 --- /dev/null +++ b/system/src/Grav/Common/Data/ValidationException.php @@ -0,0 +1,67 @@ +messages = $messages; + + $language = Grav::instance()['language']; + $this->message = $language->translate('GRAV.FORM.VALIDATION_FAIL', null, true) . ' ' . $this->message; + + foreach ($messages as $list) { + $list = array_unique($list); + foreach ($list as $message) { + $this->message .= '
' . htmlspecialchars($message, ENT_QUOTES | ENT_HTML5, 'UTF-8'); + } + } + + return $this; + } + + public function setSimpleMessage(bool $escape = true): void + { + $first = reset($this->messages); + $message = reset($first); + + $this->message = $escape ? htmlspecialchars($message, ENT_QUOTES | ENT_HTML5, 'UTF-8') : $message; + } + + /** + * @return array + */ + public function getMessages(): array + { + return $this->messages; + } + + public function jsonSerialize(): array + { + return ['validation' => $this->messages]; + } +} diff --git a/system/src/Grav/Common/Debugger.php b/system/src/Grav/Common/Debugger.php new file mode 100644 index 0000000..6d412c3 --- /dev/null +++ b/system/src/Grav/Common/Debugger.php @@ -0,0 +1,1148 @@ +currentTime = microtime(true); + + if (!defined('GRAV_REQUEST_TIME')) { + define('GRAV_REQUEST_TIME', $this->currentTime); + } + + $this->requestTime = $_SERVER['REQUEST_TIME_FLOAT'] ?? GRAV_REQUEST_TIME; + + // Set deprecation collector. + $this->setErrorHandler(); + } + + /** + * @return Clockwork|null + */ + public function getClockwork(): ?Clockwork + { + return $this->enabled ? $this->clockwork : null; + } + + /** + * Initialize the debugger + * + * @return $this + * @throws DebugBarException + */ + public function init() + { + if ($this->initialized) { + return $this; + } + + $this->grav = Grav::instance(); + $this->config = $this->grav['config']; + + // Enable/disable debugger based on configuration. + $this->enabled = (bool)$this->config->get('system.debugger.enabled'); + $this->censored = (bool)$this->config->get('system.debugger.censored', false); + + if ($this->enabled) { + $this->initialized = true; + + $clockwork = $debugbar = null; + + switch ($this->config->get('system.debugger.provider', 'debugbar')) { + case 'clockwork': + $this->clockwork = $clockwork = new Clockwork(); + break; + default: + $this->debugbar = $debugbar = new DebugBar(); + } + + $plugins_config = (array)$this->config->get('plugins'); + ksort($plugins_config); + + if ($clockwork) { + $log = $this->grav['log']; + $clockwork->setStorage(new FileStorage('cache://clockwork')); + if (extension_loaded('xdebug')) { + $clockwork->addDataSource(new XdebugDataSource()); + } + if ($log instanceof Logger) { + $clockwork->addDataSource(new MonologDataSource($log)); + } + + $timeline = $clockwork->timeline(); + if ($this->requestTime !== GRAV_REQUEST_TIME) { + $event = $timeline->event('Server'); + $event->finalize($this->requestTime, GRAV_REQUEST_TIME); + } + if ($this->currentTime !== GRAV_REQUEST_TIME) { + $event = $timeline->event('Loading'); + $event->finalize(GRAV_REQUEST_TIME, $this->currentTime); + } + $event = $timeline->event('Site Setup'); + $event->finalize($this->currentTime, microtime(true)); + } + + if ($this->censored) { + $censored = ['CENSORED' => true]; + } + + if ($debugbar) { + $debugbar->addCollector(new PhpInfoCollector()); + $debugbar->addCollector(new MessagesCollector()); + if (!$this->censored) { + $debugbar->addCollector(new RequestDataCollector()); + } + $debugbar->addCollector(new TimeDataCollector($this->requestTime)); + $debugbar->addCollector(new MemoryCollector()); + $debugbar->addCollector(new ExceptionsCollector()); + $debugbar->addCollector(new ConfigCollector($censored ?? (array)$this->config->get('system'), 'Config')); + $debugbar->addCollector(new ConfigCollector($censored ?? $plugins_config, 'Plugins')); + $debugbar->addCollector(new ConfigCollector($this->config->get('streams.schemes'), 'Streams')); + + if ($this->requestTime !== GRAV_REQUEST_TIME) { + $debugbar['time']->addMeasure('Server', $debugbar['time']->getRequestStartTime(), GRAV_REQUEST_TIME); + } + if ($this->currentTime !== GRAV_REQUEST_TIME) { + $debugbar['time']->addMeasure('Loading', GRAV_REQUEST_TIME, $this->currentTime); + } + $debugbar['time']->addMeasure('Site Setup', $this->currentTime, microtime(true)); + } + + $this->addMessage('Grav v' . GRAV_VERSION . ' - PHP ' . PHP_VERSION); + $this->config->debug(); + + if ($clockwork) { + $clockwork->info('System Configuration', $censored ?? $this->config->get('system')); + $clockwork->info('Plugins Configuration', $censored ?? $plugins_config); + $clockwork->info('Streams', $this->config->get('streams.schemes')); + } + } + + return $this; + } + + public function finalize(): void + { + if ($this->clockwork && $this->enabled) { + $this->stopProfiling('Profiler Analysis'); + $this->addMeasures(); + + $deprecations = $this->getDeprecations(); + $count = count($deprecations); + if (!$count) { + return; + } + + /** @var UserData $userData */ + $userData = $this->clockwork->userData('Deprecated'); + $userData->counters([ + 'Deprecated' => count($deprecations) + ]); + /* + foreach ($deprecations as &$deprecation) { + $d = $deprecation; + unset($d['message']); + $this->clockwork->log('deprecated', $deprecation['message'], $d); + } + unset($deprecation); + */ + + $userData->table('Your site is using following deprecated features', $deprecations); + } + } + + public function logRequest(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface + { + if (!$this->enabled || !$this->clockwork) { + return $response; + } + + $clockwork = $this->clockwork; + + $this->finalize(); + + $clockwork->timeline()->finalize($request->getAttribute('request_time')); + + if ($this->censored) { + $censored = 'CENSORED'; + $request = $request + ->withCookieParams([$censored => '']) + ->withUploadedFiles([]) + ->withHeader('cookie', $censored); + $request = $request->withParsedBody([$censored => '']); + } + + $clockwork->addDataSource(new PsrMessageDataSource($request, $response)); + + $clockwork->resolveRequest(); + $clockwork->storeRequest(); + + $clockworkRequest = $clockwork->getRequest(); + + $response = $response + ->withHeader('X-Clockwork-Id', $clockworkRequest->id) + ->withHeader('X-Clockwork-Version', $clockwork::VERSION); + + $response = $response->withHeader('X-Clockwork-Path', Utils::url('/__clockwork/')); + + return $response->withHeader('Server-Timing', ServerTiming::fromRequest($clockworkRequest)->value()); + } + + + public function debuggerRequest(RequestInterface $request): Response + { + $clockwork = $this->clockwork; + + $headers = [ + 'Content-Type' => 'application/json', + 'Grav-Internal-SkipShutdown' => 1 + ]; + + $path = $request->getUri()->getPath(); + $clockworkDataUri = '#/__clockwork(?:/(?[0-9-]+))?(?:/(?(?:previous|next)))?(?:/(?\d+))?#'; + if (preg_match($clockworkDataUri, $path, $matches) === false) { + $response = ['message' => 'Bad Input']; + + return new Response(400, $headers, json_encode($response)); + } + + $id = $matches['id'] ?? null; + $direction = $matches['direction'] ?? 'latest'; + $count = $matches['count'] ?? null; + + $storage = $clockwork->getStorage(); + + if ($direction === 'previous') { + $data = $storage->previous($id, $count); + } elseif ($direction === 'next') { + $data = $storage->next($id, $count); + } elseif ($direction === 'latest' || $id === 'latest') { + $data = $storage->latest(); + } else { + $data = $storage->find($id); + } + + if (preg_match('#(?[0-9-]+|latest)/extended#', $path)) { + $clockwork->extendRequest($data); + } + + if (!$data) { + $response = ['message' => 'Not Found']; + + return new Response(404, $headers, json_encode($response)); + } + + $data = is_array($data) ? array_map(static function ($item) { + return $item->toArray(); + }, $data) : $data->toArray(); + + return new Response(200, $headers, json_encode($data)); + } + + /** + * @return void + */ + protected function addMeasures(): void + { + if (!$this->enabled) { + return; + } + + $nowTime = microtime(true); + $clkTimeLine = $this->clockwork ? $this->clockwork->timeline() : null; + $debTimeLine = $this->debugbar ? $this->debugbar['time'] : null; + foreach ($this->timers as $name => $data) { + $description = $data[0]; + $startTime = $data[1] ?? null; + $endTime = $data[2] ?? $nowTime; + if ($clkTimeLine) { + $event = $clkTimeLine->event($description); + $event->finalize($startTime, $endTime); + } elseif ($debTimeLine) { + if ($endTime - $startTime < 0.001) { + continue; + } + + $debTimeLine->addMeasure($description ?? $name, $startTime, $endTime); + } + } + $this->timers = []; + } + + /** + * Set/get the enabled state of the debugger + * + * @param bool|null $state If null, the method returns the enabled value. If set, the method sets the enabled state + * @return bool + */ + public function enabled($state = null) + { + if ($state !== null) { + $this->enabled = (bool)$state; + } + + return $this->enabled; + } + + /** + * Add the debugger assets to the Grav Assets + * + * @return $this + */ + public function addAssets() + { + if ($this->enabled) { + // Only add assets if Page is HTML + $page = $this->grav['page']; + if ($page->templateFormat() !== 'html') { + return $this; + } + + /** @var Assets $assets */ + $assets = $this->grav['assets']; + + // Clockwork specific assets + if ($this->clockwork) { + if ($this->config->get('plugins.clockwork-web.enabled')) { + $route = Utils::url($this->grav['config']->get('plugins.clockwork-web.route')); + } else { + $route = 'https://github.com/getgrav/grav-plugin-clockwork-web'; + } + $assets->addCss('/system/assets/debugger/clockwork.css'); + $assets->addJs('/system/assets/debugger/clockwork.js', [ + 'id' => 'clockwork-script', + 'data-route' => $route + ]); + } + + + // Debugbar specific assets + if ($this->debugbar) { + // Add jquery library + $assets->add('jquery', 101); + + $this->renderer = $this->debugbar->getJavascriptRenderer(); + $this->renderer->setIncludeVendors(false); + + [$css_files, $js_files] = $this->renderer->getAssets(null, JavascriptRenderer::RELATIVE_URL); + + foreach ((array)$css_files as $css) { + $assets->addCss($css); + } + + $assets->addCss('/system/assets/debugger/phpdebugbar.css', ['loading' => 'inline']); + + foreach ((array)$js_files as $js) { + $assets->addJs($js); + } + } + } + + return $this; + } + + /** + * @param int $limit + * @return array + */ + public function getCaller($limit = 2) + { + $trace = debug_backtrace(false, $limit); + + return array_pop($trace); + } + + /** + * Adds a data collector + * + * @param DataCollectorInterface $collector + * @return $this + * @throws DebugBarException + */ + public function addCollector($collector) + { + if ($this->debugbar && !$this->debugbar->hasCollector($collector->getName())) { + $this->debugbar->addCollector($collector); + } + + return $this; + } + + /** + * Returns a data collector + * + * @param string $name + * @return DataCollectorInterface|null + * @throws DebugBarException + */ + public function getCollector($name) + { + if ($this->debugbar && $this->debugbar->hasCollector($name)) { + return $this->debugbar->getCollector($name); + } + + return null; + } + + /** + * Displays the debug bar + * + * @return $this + */ + public function render() + { + if ($this->enabled && $this->debugbar) { + // Only add assets if Page is HTML + $page = $this->grav['page']; + if (!$this->renderer || $page->templateFormat() !== 'html') { + return $this; + } + + $this->addMeasures(); + $this->addDeprecations(); + + echo $this->renderer->render(); + } + + return $this; + } + + /** + * Sends the data through the HTTP headers + * + * @return $this + */ + public function sendDataInHeaders() + { + if ($this->enabled && $this->debugbar) { + $this->addMeasures(); + $this->addDeprecations(); + $this->debugbar->sendDataInHeaders(); + } + + return $this; + } + + /** + * Returns collected debugger data. + * + * @return array|null + */ + public function getData() + { + if (!$this->enabled || !$this->debugbar) { + return null; + } + + $this->addMeasures(); + $this->addDeprecations(); + $this->timers = []; + + return $this->debugbar->getData(); + } + + /** + * Hierarchical Profiler support. + * + * @param callable $callable + * @param string|null $message + * @return mixed + */ + public function profile(callable $callable, string $message = null) + { + $this->startProfiling(); + $response = $callable(); + $this->stopProfiling($message); + + return $response; + } + + public function addTwigProfiler(Environment $twig): void + { + $clockwork = $this->getClockwork(); + if ($clockwork) { + $source = new TwigClockworkDataSource($twig); + $source->listenToEvents(); + $clockwork->addDataSource($source); + } + } + + /** + * Start profiling code. + * + * @return void + */ + public function startProfiling(): void + { + if ($this->enabled && extension_loaded('tideways_xhprof')) { + $this->profiling++; + if ($this->profiling === 1) { + // @phpstan-ignore-next-line + \tideways_xhprof_enable(TIDEWAYS_XHPROF_FLAGS_NO_BUILTINS); + } + } + } + + /** + * Stop profiling code. Returns profiling array or null if profiling couldn't be done. + * + * @param string|null $message + * @return array|null + */ + public function stopProfiling(string $message = null): ?array + { + $timings = null; + if ($this->enabled && extension_loaded('tideways_xhprof')) { + $profiling = $this->profiling - 1; + if ($profiling === 0) { + // @phpstan-ignore-next-line + $timings = \tideways_xhprof_disable(); + $timings = $this->buildProfilerTimings($timings); + + if ($this->clockwork) { + /** @var UserData $userData */ + $userData = $this->clockwork->userData('Profiler'); + $userData->counters([ + 'Calls' => count($timings) + ]); + $userData->table('Profiler', $timings); + } else { + $this->addMessage($message ?? 'Profiler Analysis', 'debug', $timings); + } + } + $this->profiling = max(0, $profiling); + } + + return $timings; + } + + /** + * @param array $timings + * @return array + */ + protected function buildProfilerTimings(array $timings): array + { + // Filter method calls which take almost no time. + $timings = array_filter($timings, function ($value) { + return $value['wt'] > 50; + }); + + uasort($timings, function (array $a, array $b) { + return $b['wt'] <=> $a['wt']; + }); + + $table = []; + foreach ($timings as $key => $timing) { + $parts = explode('==>', $key); + $method = $this->parseProfilerCall(array_pop($parts)); + $context = $this->parseProfilerCall(array_pop($parts)); + + // Skip redundant method calls. + if ($context === 'Grav\Framework\RequestHandler\RequestHandler::handle()') { + continue; + } + + // Do not profile library calls. + if (strpos($context, 'Grav\\') !== 0) { + continue; + } + + $table[] = [ + 'Context' => $context, + 'Method' => $method, + 'Calls' => $timing['ct'], + 'Time (ms)' => $timing['wt'] / 1000, + ]; + } + + return $table; + } + + /** + * @param string|null $call + * @return mixed|string|null + */ + protected function parseProfilerCall(?string $call) + { + if (null === $call) { + return ''; + } + if (strpos($call, '@')) { + [$call,] = explode('@', $call); + } + if (strpos($call, '::')) { + [$class, $call] = explode('::', $call); + } + + if (!isset($class)) { + return $call; + } + + // It is also possible to display twig files, but they are being logged in views. + /* + if (strpos($class, '__TwigTemplate_') === 0 && class_exists($class)) { + $env = new Environment(); + / ** @var Template $template * / + $template = new $class($env); + + return $template->getTemplateName(); + } + */ + + return "{$class}::{$call}()"; + } + + /** + * Start a timer with an associated name and description + * + * @param string $name + * @param string|null $description + * @return $this + */ + public function startTimer($name, $description = null) + { + $this->timers[$name] = [$description, microtime(true)]; + + return $this; + } + + /** + * Stop the named timer + * + * @param string $name + * @return $this + */ + public function stopTimer($name) + { + if (isset($this->timers[$name])) { + $endTime = microtime(true); + $this->timers[$name][] = $endTime; + } + + return $this; + } + + /** + * Dump variables into the Messages tab of the Debug Bar + * + * @param mixed $message + * @param string $label + * @param mixed|bool $isString + * @return $this + */ + public function addMessage($message, $label = 'info', $isString = true) + { + if ($this->enabled) { + if ($this->censored) { + if (!is_scalar($message)) { + $message = 'CENSORED'; + } + if (!is_scalar($isString)) { + $isString = ['CENSORED']; + } + } + + if ($this->debugbar) { + if (is_array($isString)) { + $message = $isString; + $isString = false; + } elseif (is_string($isString)) { + $message = $isString; + $isString = true; + } + $this->debugbar['messages']->addMessage($message, $label, $isString); + } + + if ($this->clockwork) { + $context = $isString; + if (!is_scalar($message)) { + $context = $message; + $message = gettype($context); + } + if (is_bool($context)) { + $context = []; + } elseif (!is_array($context)) { + $type = gettype($context); + $context = [$type => $context]; + } + + $this->clockwork->log($label, $message, $context); + } + } + + return $this; + } + + /** + * @param string $name + * @param object $event + * @param EventDispatcherInterface $dispatcher + * @param float|null $time + * @return $this + */ + public function addEvent(string $name, $event, EventDispatcherInterface $dispatcher, float $time = null) + { + if ($this->enabled && $this->clockwork) { + $time = $time ?? microtime(true); + $duration = (microtime(true) - $time) * 1000; + + $data = null; + if ($event && method_exists($event, '__debugInfo')) { + $data = $event; + } + + $listeners = []; + foreach ($dispatcher->getListeners($name) as $listener) { + $listeners[] = $this->resolveCallable($listener); + } + + $this->clockwork->addEvent($name, $data, $time, ['listeners' => $listeners, 'duration' => $duration]); + } + + return $this; + } + + /** + * Dump exception into the Messages tab of the Debug Bar + * + * @param Throwable $e + * @return Debugger + */ + public function addException(Throwable $e) + { + if ($this->initialized && $this->enabled) { + if ($this->debugbar) { + $this->debugbar['exceptions']->addThrowable($e); + } + + if ($this->clockwork) { + /** @var UserData $exceptions */ + $exceptions = $this->clockwork->userData('Exceptions'); + $exceptions->data(['message' => $e->getMessage()]); + + $this->clockwork->alert($e->getMessage(), ['exception' => $e]); + } + } + + return $this; + } + + /** + * @return void + */ + public function setErrorHandler() + { + $this->errorHandler = set_error_handler( + [$this, 'deprecatedErrorHandler'] + ); + } + + /** + * @param int $errno + * @param string $errstr + * @param string $errfile + * @param int $errline + * @return bool + */ + public function deprecatedErrorHandler($errno, $errstr, $errfile, $errline) + { + if ($errno !== E_USER_DEPRECATED && $errno !== E_DEPRECATED) { + if ($this->errorHandler) { + return call_user_func($this->errorHandler, $errno, $errstr, $errfile, $errline); + } + + return true; + } + + if (!$this->enabled) { + return true; + } + + // Figure out error scope from the error. + $scope = 'unknown'; + if (stripos($errstr, 'grav') !== false) { + $scope = 'grav'; + } elseif (strpos($errfile, '/twig/') !== false) { + $scope = 'twig'; + // TODO: remove when upgrading to Twig 2+ + if (str_contains($errstr, '#[\ReturnTypeWillChange]') || str_contains($errstr, 'Passing null to parameter')) { + return true; + } + } elseif (stripos($errfile, '/yaml/') !== false) { + $scope = 'yaml'; + } elseif (strpos($errfile, '/vendor/') !== false) { + $scope = 'vendor'; + } + + // Clean up backtrace to make it more useful. + $backtrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT); + + // Skip current call. + array_shift($backtrace); + + // Find yaml file where the error happened. + if ($scope === 'yaml') { + foreach ($backtrace as $current) { + if (isset($current['args'])) { + foreach ($current['args'] as $arg) { + if ($arg instanceof SplFileInfo) { + $arg = $arg->getPathname(); + } + if (is_string($arg) && preg_match('/.+\.(yaml|md)$/i', $arg)) { + $errfile = $arg; + $errline = 0; + + break 2; + } + } + } + } + } + + // Filter arguments. + $cut = 0; + $previous = null; + foreach ($backtrace as $i => &$current) { + if (isset($current['args'])) { + $args = []; + foreach ($current['args'] as $arg) { + if (is_string($arg)) { + $arg = "'" . $arg . "'"; + if (mb_strlen($arg) > 100) { + $arg = 'string'; + } + } elseif (is_bool($arg)) { + $arg = $arg ? 'true' : 'false'; + } elseif (is_scalar($arg)) { + $arg = $arg; + } elseif (is_object($arg)) { + $arg = get_class($arg) . ' $object'; + } elseif (is_array($arg)) { + $arg = '$array'; + } else { + $arg = '$object'; + } + + $args[] = $arg; + } + $current['args'] = $args; + } + + $object = $current['object'] ?? null; + unset($current['object']); + + $reflection = null; + if ($object instanceof TemplateWrapper) { + $reflection = new ReflectionObject($object); + $property = $reflection->getProperty('template'); + $property->setAccessible(true); + $object = $property->getValue($object); + } + + if ($object instanceof Template) { + $file = $current['file'] ?? null; + + if (preg_match('`(Template.php|TemplateWrapper.php)$`', $file)) { + $current = null; + continue; + } + + $debugInfo = $object->getDebugInfo(); + + $line = 1; + if (!$reflection) { + foreach ($debugInfo as $codeLine => $templateLine) { + if ($codeLine <= $current['line']) { + $line = $templateLine; + break; + } + } + } + + $src = $object->getSourceContext(); + //$code = preg_split('/\r\n|\r|\n/', $src->getCode()); + //$current['twig']['twig'] = trim($code[$line - 1]); + $current['twig']['file'] = $src->getPath(); + $current['twig']['line'] = $line; + + $prevFile = $previous['file'] ?? null; + if ($prevFile && $file === $prevFile) { + $prevLine = $previous['line']; + + $line = 1; + foreach ($debugInfo as $codeLine => $templateLine) { + if ($codeLine <= $prevLine) { + $line = $templateLine; + break; + } + } + + //$previous['twig']['twig'] = trim($code[$line - 1]); + $previous['twig']['file'] = $src->getPath(); + $previous['twig']['line'] = $line; + } + + $cut = $i; + } elseif ($object instanceof ProcessorInterface) { + $cut = $cut ?: $i; + break; + } + + $previous = &$backtrace[$i]; + } + unset($current); + + if ($cut) { + $backtrace = array_slice($backtrace, 0, $cut + 1); + } + $backtrace = array_values(array_filter($backtrace)); + + // Skip vendor libraries and the method where error was triggered. + foreach ($backtrace as $i => $current) { + if (!isset($current['file'])) { + continue; + } + if (strpos($current['file'], '/vendor/') !== false) { + $cut = $i + 1; + continue; + } + if (isset($current['function']) && ($current['function'] === 'user_error' || $current['function'] === 'trigger_error')) { + $cut = $i + 1; + continue; + } + + break; + } + + if ($cut) { + $backtrace = array_slice($backtrace, $cut); + } + $backtrace = array_values(array_filter($backtrace)); + + $current = reset($backtrace); + + // If the issue happened inside twig file, change the file and line to match that file. + $file = $current['twig']['file'] ?? ''; + if ($file) { + $errfile = $file; + $errline = $current['twig']['line'] ?? 0; + } + + $deprecation = [ + 'scope' => $scope, + 'message' => $errstr, + 'file' => $errfile, + 'line' => $errline, + 'trace' => $backtrace, + 'count' => 1 + ]; + + $this->deprecations[] = $deprecation; + + // Do not pass forward. + return true; + } + + /** + * @return array + */ + protected function getDeprecations(): array + { + if (!$this->deprecations) { + return []; + } + + $list = []; + /** @var array $deprecated */ + foreach ($this->deprecations as $deprecated) { + $list[] = $this->getDepracatedMessage($deprecated)[0]; + } + + return $list; + } + + /** + * @return void + * @throws DebugBarException + */ + protected function addDeprecations() + { + if (!$this->deprecations) { + return; + } + + $collector = new MessagesCollector('deprecated'); + $this->addCollector($collector); + $collector->addMessage('Your site is using following deprecated features:'); + + /** @var array $deprecated */ + foreach ($this->deprecations as $deprecated) { + list($message, $scope) = $this->getDepracatedMessage($deprecated); + + $collector->addMessage($message, $scope); + } + } + + /** + * @param array $deprecated + * @return array + */ + protected function getDepracatedMessage($deprecated) + { + $scope = $deprecated['scope']; + + $trace = []; + if (isset($deprecated['trace'])) { + foreach ($deprecated['trace'] as $current) { + $class = $current['class'] ?? ''; + $type = $current['type'] ?? ''; + $function = $this->getFunction($current); + if (isset($current['file'])) { + $current['file'] = str_replace(GRAV_ROOT . '/', '', $current['file']); + } + + unset($current['class'], $current['type'], $current['function'], $current['args']); + + if (isset($current['twig'])) { + $trace[] = $current['twig']; + } else { + $trace[] = ['call' => $class . $type . $function] + $current; + } + } + } + + $array = [ + 'message' => $deprecated['message'], + 'file' => $deprecated['file'], + 'line' => $deprecated['line'], + 'trace' => $trace + ]; + + return [ + array_filter($array), + $scope + ]; + } + + /** + * @param array $trace + * @return string + */ + protected function getFunction($trace) + { + if (!isset($trace['function'])) { + return ''; + } + + return $trace['function'] . '(' . implode(', ', $trace['args'] ?? []) . ')'; + } + + /** + * @param callable $callable + * @return string + */ + protected function resolveCallable(callable $callable) + { + if (is_array($callable)) { + return get_class($callable[0]) . '->' . $callable[1] . '()'; + } + + return 'unknown'; + } +} diff --git a/system/src/Grav/Common/Errors/BareHandler.php b/system/src/Grav/Common/Errors/BareHandler.php new file mode 100644 index 0000000..fa5a095 --- /dev/null +++ b/system/src/Grav/Common/Errors/BareHandler.php @@ -0,0 +1,33 @@ +getInspector(); + $code = $inspector->getException()->getCode(); + if (($code >= 400) && ($code < 600)) { + $this->getRun()->sendHttpCode($code); + } + + return Handler::QUIT; + } +} diff --git a/system/src/Grav/Common/Errors/Errors.php b/system/src/Grav/Common/Errors/Errors.php new file mode 100644 index 0000000..eec79f4 --- /dev/null +++ b/system/src/Grav/Common/Errors/Errors.php @@ -0,0 +1,85 @@ +get('system.errors'); + $jsonRequest = $_SERVER && isset($_SERVER['HTTP_ACCEPT']) && $_SERVER['HTTP_ACCEPT'] === 'application/json'; + + // Setup Whoops-based error handler + $system = new SystemFacade; + $whoops = new Run($system); + + $verbosity = 1; + + if (isset($config['display'])) { + if (is_int($config['display'])) { + $verbosity = $config['display']; + } else { + $verbosity = $config['display'] ? 1 : 0; + } + } + + switch ($verbosity) { + case 1: + $error_page = new PrettyPageHandler(); + $error_page->setPageTitle('Crikey! There was an error...'); + $error_page->addResourcePath(GRAV_ROOT . '/system/assets'); + $error_page->addCustomCss('whoops.css'); + $whoops->prependHandler($error_page); + break; + case -1: + $whoops->prependHandler(new BareHandler); + break; + default: + $whoops->prependHandler(new SimplePageHandler); + break; + } + + if ($jsonRequest || Misc::isAjaxRequest()) { + $whoops->prependHandler(new JsonResponseHandler()); + } + + if (isset($config['log']) && $config['log']) { + $logger = $grav['log']; + $whoops->pushHandler(function ($exception, $inspector, $run) use ($logger) { + try { + $logger->addCritical($exception->getMessage() . ' - Trace: ' . $exception->getTraceAsString()); + } catch (Exception $e) { + echo $e; + } + }); + } + + $whoops->register(); + + // Re-register deprecation handler. + $grav['debugger']->setErrorHandler(); + } +} diff --git a/system/src/Grav/Common/Errors/Resources/error.css b/system/src/Grav/Common/Errors/Resources/error.css new file mode 100644 index 0000000..11ce3fd --- /dev/null +++ b/system/src/Grav/Common/Errors/Resources/error.css @@ -0,0 +1,52 @@ +html, body { + height: 100% +} +body { + margin:0 3rem; + padding:0; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 1.5rem; + line-height: 1.4; + display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */ + display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */ + display: -ms-flexbox; /* TWEENER - IE 10 */ + display: -webkit-flex; /* NEW - Chrome */ + display: flex; + -webkit-align-items: center; + align-items: center; + -webkit-justify-content: center; + justify-content: center; +} +.container { + margin: 0rem; + max-width: 600px; + padding-bottom:5rem; +} + +header { + color: #000; + font-size: 4rem; + letter-spacing: 2px; + line-height: 1.1; + margin-bottom: 2rem; +} +p { + font-family: Optima, Segoe, "Segoe UI", Candara, Calibri, Arial, sans-serif; + color: #666; +} + +h5 { + font-weight: normal; + color: #999; + font-size: 1rem; +} + +h6 { + font-weight: normal; + color: #999; +} + +code { + font-weight: bold; + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} diff --git a/system/src/Grav/Common/Errors/Resources/layout.html.php b/system/src/Grav/Common/Errors/Resources/layout.html.php new file mode 100644 index 0000000..6699959 --- /dev/null +++ b/system/src/Grav/Common/Errors/Resources/layout.html.php @@ -0,0 +1,30 @@ + + + + + + Whoops there was an error! + + + +
+
+
+ Server Error +
+ + + +

Sorry, something went terribly wrong!

+ +

-

+ +
For further details please review your logs/ folder, or enable displaying of errors in your system configuration.
+
+
+ + diff --git a/system/src/Grav/Common/Errors/SimplePageHandler.php b/system/src/Grav/Common/Errors/SimplePageHandler.php new file mode 100644 index 0000000..4f11fdd --- /dev/null +++ b/system/src/Grav/Common/Errors/SimplePageHandler.php @@ -0,0 +1,122 @@ +searchPaths[] = __DIR__ . '/Resources'; + } + + /** + * @return int + */ + public function handle() + { + $inspector = $this->getInspector(); + + $helper = new TemplateHelper(); + $templateFile = $this->getResource('layout.html.php'); + $cssFile = $this->getResource('error.css'); + + $code = $inspector->getException()->getCode(); + if (($code >= 400) && ($code < 600)) { + $this->getRun()->sendHttpCode($code); + } + $message = $inspector->getException()->getMessage(); + + if ($inspector->getException() instanceof ErrorException) { + $code = Misc::translateErrorCode($code); + } + + $vars = array( + 'stylesheet' => file_get_contents($cssFile), + 'code' => $code, + 'message' => htmlspecialchars(strip_tags(rawurldecode($message)), ENT_QUOTES, 'UTF-8'), + ); + + $helper->setVariables($vars); + $helper->render($templateFile); + + return Handler::QUIT; + } + + /** + * @param string $resource + * @return string + * @throws RuntimeException + */ + protected function getResource($resource) + { + // If the resource was found before, we can speed things up + // by caching its absolute, resolved path: + if (isset($this->resourceCache[$resource])) { + return $this->resourceCache[$resource]; + } + + // Search through available search paths, until we find the + // resource we're after: + foreach ($this->searchPaths as $path) { + $fullPath = "{$path}/{$resource}"; + + if (is_file($fullPath)) { + // Cache the result: + $this->resourceCache[$resource] = $fullPath; + return $fullPath; + } + } + + // If we got this far, nothing was found. + throw new RuntimeException( + "Could not find resource '{$resource}' in any resource paths (searched: " . implode(', ', $this->searchPaths). ')' + ); + } + + /** + * @param string $path + * @return void + */ + public function addResourcePath($path) + { + if (!is_dir($path)) { + throw new InvalidArgumentException( + "'{$path}' is not a valid directory" + ); + } + + array_unshift($this->searchPaths, $path); + } + + /** + * @return array + */ + public function getResourcePaths() + { + return $this->searchPaths; + } +} diff --git a/system/src/Grav/Common/Errors/SystemFacade.php b/system/src/Grav/Common/Errors/SystemFacade.php new file mode 100644 index 0000000..24c2c31 --- /dev/null +++ b/system/src/Grav/Common/Errors/SystemFacade.php @@ -0,0 +1,67 @@ +whoopsShutdownHandler = $function; + register_shutdown_function([$this, 'handleShutdown']); + } + + /** + * Special case to deal with Fatal errors and the like. + * + * @return void + */ + public function handleShutdown() + { + $error = $this->getLastError(); + + // Ignore core warnings and errors. + if ($error && !($error['type'] & (E_CORE_WARNING | E_CORE_ERROR))) { + $handler = $this->whoopsShutdownHandler; + $handler(); + } + } + + + /** + * @param int $httpCode + * + * @return int + */ + public function setHttpResponseCode($httpCode) + { + if (!headers_sent()) { + // Ensure that no 'location' header is present as otherwise this + // will override the HTTP code being set here, and mask the + // expected error page. + header_remove('location'); + + // Work around PHP bug #8218 (8.0.17 & 8.1.4). + header_remove('Content-Encoding'); + } + + return http_response_code($httpCode); + } +} diff --git a/system/src/Grav/Common/File/CompiledFile.php b/system/src/Grav/Common/File/CompiledFile.php new file mode 100644 index 0000000..1266e9d --- /dev/null +++ b/system/src/Grav/Common/File/CompiledFile.php @@ -0,0 +1,195 @@ +filename; + // If nothing has been loaded, attempt to get pre-compiled version of the file first. + if ($var === null && $this->raw === null && $this->content === null) { + $key = md5($filename); + $file = PhpFile::instance(CACHE_DIR . "compiled/files/{$key}{$this->extension}.php"); + + $modified = $this->modified(); + if (!$modified) { + try { + return $this->decode($this->raw()); + } catch (Throwable $e) { + // If the compiled file is broken, we can safely ignore the error and continue. + } + } + + $class = get_class($this); + + $size = filesize($filename); + $cache = $file->exists() ? $file->content() : null; + + // Load real file if cache isn't up to date (or is invalid). + if (!isset($cache['@class']) + || $cache['@class'] !== $class + || $cache['modified'] !== $modified + || ($cache['size'] ?? null) !== $size + || $cache['filename'] !== $filename + ) { + // Attempt to lock the file for writing. + try { + $locked = $file->lock(false); + } catch (Exception $e) { + $locked = false; + + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $debugger->addMessage(sprintf('%s(): Cannot obtain a lock for compiling cache file for %s: %s', __METHOD__, $this->filename, $e->getMessage()), 'warning'); + } + + // Decode RAW file into compiled array. + $data = (array)$this->decode($this->raw()); + $cache = [ + '@class' => $class, + 'filename' => $filename, + 'modified' => $modified, + 'size' => $size, + 'data' => $data + ]; + + // If compiled file wasn't already locked by another process, save it. + if ($locked) { + $file->save($cache); + $file->unlock(); + + // Compile cached file into bytecode cache + if (function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN)) { + $lockName = $file->filename(); + + // Silence error if function exists, but is restricted. + @opcache_invalidate($lockName, true); + @opcache_compile_file($lockName); + } + } + } + $file->free(); + + $this->content = $cache['data']; + } + } catch (Exception $e) { + throw new RuntimeException(sprintf('Failed to read %s: %s', Utils::basename($filename), $e->getMessage()), 500, $e); + } + + return parent::content($var); + } + + /** + * Save file. + * + * @param mixed $data Optional data to be saved, usually array. + * @return void + * @throws RuntimeException + */ + public function save($data = null) + { + // Make sure that the cache file is always up to date! + $key = md5($this->filename); + $file = PhpFile::instance(CACHE_DIR . "compiled/files/{$key}{$this->extension}.php"); + try { + $locked = $file->lock(); + } catch (Exception $e) { + $locked = false; + + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $debugger->addMessage(sprintf('%s(): Cannot obtain a lock for compiling cache file for %s: %s', __METHOD__, $this->filename, $e->getMessage()), 'warning'); + } + + parent::save($data); + + if ($locked) { + $modified = $this->modified(); + $filename = $this->filename; + $class = get_class($this); + $size = filesize($filename); + + // windows doesn't play nicely with this as it can't read when locked + if (!Utils::isWindows()) { + // Reload data from the filesystem. This ensures that we always cache the correct data (see issue #2282). + $this->raw = $this->content = null; + $data = (array)$this->decode($this->raw()); + } + + // Decode data into compiled array. + $cache = [ + '@class' => $class, + 'filename' => $filename, + 'modified' => $modified, + 'size' => $size, + 'data' => $data + ]; + + $file->save($cache); + $file->unlock(); + + // Compile cached file into bytecode cache + if (function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN)) { + $lockName = $file->filename(); + // Silence error if function exists, but is restricted. + @opcache_invalidate($lockName, true); + @opcache_compile_file($lockName); + } + } + } + + /** + * Serialize file. + * + * @return array + */ + public function __sleep() + { + return [ + 'filename', + 'extension', + 'raw', + 'content', + 'settings' + ]; + } + + /** + * Unserialize file. + */ + public function __wakeup() + { + if (!isset(static::$instances[$this->filename])) { + static::$instances[$this->filename] = $this; + } + } +} diff --git a/system/src/Grav/Common/File/CompiledJsonFile.php b/system/src/Grav/Common/File/CompiledJsonFile.php new file mode 100644 index 0000000..ed5787e --- /dev/null +++ b/system/src/Grav/Common/File/CompiledJsonFile.php @@ -0,0 +1,33 @@ + ['.DS_Store'], + 'exclude_paths' => [] + ]; + + /** @var string */ + protected $archive_file; + + /** + * @param string $compression + * @return ZipArchiver + */ + public static function create($compression) + { + if ($compression === 'zip') { + return new ZipArchiver(); + } + + return new ZipArchiver(); + } + + /** + * @param string $archive_file + * @return $this + */ + public function setArchive($archive_file) + { + $this->archive_file = $archive_file; + + return $this; + } + + /** + * @param array $options + * @return $this + */ + public function setOptions($options) + { + // Set infinite PHP execution time if possible. + if (Utils::functionExists('set_time_limit')) { + @set_time_limit(0); + } + + $this->options = $options + $this->options; + + return $this; + } + + /** + * @param string $folder + * @param callable|null $status + * @return $this + */ + abstract public function compress($folder, callable $status = null); + + /** + * @param string $destination + * @param callable|null $status + * @return $this + */ + abstract public function extract($destination, callable $status = null); + + /** + * @param array $folders + * @param callable|null $status + * @return $this + */ + abstract public function addEmptyFolders($folders, callable $status = null); + + /** + * @param string $rootPath + * @return RecursiveIteratorIterator + */ + protected function getArchiveFiles($rootPath) + { + $exclude_paths = $this->options['exclude_paths']; + $exclude_files = $this->options['exclude_files']; + $dirItr = new RecursiveDirectoryIterator($rootPath, RecursiveDirectoryIterator::SKIP_DOTS | FilesystemIterator::FOLLOW_SYMLINKS | FilesystemIterator::UNIX_PATHS); + $filterItr = new RecursiveDirectoryFilterIterator($dirItr, $rootPath, $exclude_paths, $exclude_files); + $files = new RecursiveIteratorIterator($filterItr, RecursiveIteratorIterator::SELF_FIRST); + + return $files; + } +} diff --git a/system/src/Grav/Common/Filesystem/Folder.php b/system/src/Grav/Common/Filesystem/Folder.php new file mode 100644 index 0000000..06f489d --- /dev/null +++ b/system/src/Grav/Common/Filesystem/Folder.php @@ -0,0 +1,548 @@ +isStream($path)) { + $directory = $locator->getRecursiveIterator($path, $flags); + } else { + $directory = new RecursiveDirectoryIterator($path, $flags); + } + $filter = new RecursiveFolderFilterIterator($directory); + $iterator = new RecursiveIteratorIterator($filter, RecursiveIteratorIterator::SELF_FIRST); + + foreach ($iterator as $dir) { + $dir_modified = $dir->getMTime(); + if ($dir_modified > $last_modified) { + $last_modified = $dir_modified; + } + } + } + + return $last_modified; + } + + /** + * Recursively find the last modified time under given path by file. + * + * @param array $paths + * @param string $extensions which files to search for specifically + * @return int + */ + public static function lastModifiedFile(array $paths, $extensions = 'md|yaml'): int + { + $last_modified = 0; + + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $flags = RecursiveDirectoryIterator::SKIP_DOTS; + + foreach($paths as $path) { + if (!file_exists($path)) { + return 0; + } + if ($locator->isStream($path)) { + $directory = $locator->getRecursiveIterator($path, $flags); + } else { + $directory = new RecursiveDirectoryIterator($path, $flags); + } + $recursive = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST); + $iterator = new RegexIterator($recursive, '/^.+\.'.$extensions.'$/i'); + + /** @var RecursiveDirectoryIterator $file */ + foreach ($iterator as $file) { + try { + $file_modified = $file->getMTime(); + if ($file_modified > $last_modified) { + $last_modified = $file_modified; + } + } catch (Exception $e) { + Grav::instance()['log']->error('Could not process file: ' . $e->getMessage()); + } + } + } + + return $last_modified; + } + + /** + * Recursively md5 hash all files in a path + * + * @param array $paths + * @return string + */ + public static function hashAllFiles(array $paths): string + { + $files = []; + + foreach ($paths as $path) { + if (file_exists($path)) { + $flags = RecursiveDirectoryIterator::SKIP_DOTS; + + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + if ($locator->isStream($path)) { + $directory = $locator->getRecursiveIterator($path, $flags); + } else { + $directory = new RecursiveDirectoryIterator($path, $flags); + } + + $iterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST); + + foreach ($iterator as $file) { + $files[] = $file->getPathname() . '?'. $file->getMTime(); + } + } + } + + return md5(serialize($files)); + } + + /** + * Get relative path between target and base path. If path isn't relative, return full path. + * + * @param string $path + * @param string $base + * @return string + */ + public static function getRelativePath($path, $base = GRAV_ROOT) + { + if ($base) { + $base = preg_replace('![\\\/]+!', '/', $base); + $path = preg_replace('![\\\/]+!', '/', $path); + if (strpos($path, $base) === 0) { + $path = ltrim(substr($path, strlen($base)), '/'); + } + } + + return $path; + } + + /** + * Get relative path between target and base path. If path isn't relative, return full path. + * + * @param string $path + * @param string $base + * @return string + */ + public static function getRelativePathDotDot($path, $base) + { + // Normalize paths. + $base = preg_replace('![\\\/]+!', '/', $base); + $path = preg_replace('![\\\/]+!', '/', $path); + + if ($path === $base) { + return ''; + } + + $baseParts = explode('/', ltrim($base, '/')); + $pathParts = explode('/', ltrim($path, '/')); + + array_pop($baseParts); + $lastPart = array_pop($pathParts); + foreach ($baseParts as $i => $directory) { + if (isset($pathParts[$i]) && $pathParts[$i] === $directory) { + unset($baseParts[$i], $pathParts[$i]); + } else { + break; + } + } + $pathParts[] = $lastPart; + $path = str_repeat('../', count($baseParts)) . implode('/', $pathParts); + + return '' === $path + || strpos($path, '/') === 0 + || false !== ($colonPos = strpos($path, ':')) && ($colonPos < ($slashPos = strpos($path, '/')) || false === $slashPos) + ? "./$path" : $path; + } + + /** + * Shift first directory out of the path. + * + * @param string $path + * @return string|null + */ + public static function shift(&$path) + { + $parts = explode('/', trim($path, '/'), 2); + $result = array_shift($parts); + $path = array_shift($parts); + + return $result ?: null; + } + + /** + * Return recursive list of all files and directories under given path. + * + * @param string $path + * @param array $params + * @return array + * @throws RuntimeException + */ + public static function all($path, array $params = []) + { + if (!$path) { + throw new RuntimeException("Path doesn't exist."); + } + if (!file_exists($path)) { + return []; + } + + $compare = isset($params['compare']) ? 'get' . $params['compare'] : null; + $pattern = $params['pattern'] ?? null; + $filters = $params['filters'] ?? null; + $recursive = $params['recursive'] ?? true; + $levels = $params['levels'] ?? -1; + $key = isset($params['key']) ? 'get' . $params['key'] : null; + $value = 'get' . ($params['value'] ?? ($recursive ? 'SubPathname' : 'Filename')); + $folders = $params['folders'] ?? true; + $files = $params['files'] ?? true; + + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + if ($recursive) { + $flags = RecursiveDirectoryIterator::SKIP_DOTS + FilesystemIterator::UNIX_PATHS + + FilesystemIterator::CURRENT_AS_SELF + FilesystemIterator::FOLLOW_SYMLINKS; + if ($locator->isStream($path)) { + $directory = $locator->getRecursiveIterator($path, $flags); + } else { + $directory = new RecursiveDirectoryIterator($path, $flags); + } + $iterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST); + $iterator->setMaxDepth(max($levels, -1)); + } else { + if ($locator->isStream($path)) { + $iterator = $locator->getIterator($path); + } else { + $iterator = new FilesystemIterator($path); + } + } + + $results = []; + + /** @var RecursiveDirectoryIterator $file */ + foreach ($iterator as $file) { + // Ignore hidden files. + if (strpos($file->getFilename(), '.') === 0 && $file->isFile()) { + continue; + } + if (!$folders && $file->isDir()) { + continue; + } + if (!$files && $file->isFile()) { + continue; + } + if ($compare && $pattern && !preg_match($pattern, $file->{$compare}())) { + continue; + } + $fileKey = $key ? $file->{$key}() : null; + $filePath = $file->{$value}(); + if ($filters) { + if (isset($filters['key'])) { + $pre = !empty($filters['pre-key']) ? $filters['pre-key'] : ''; + $fileKey = $pre . preg_replace($filters['key'], '', $fileKey); + } + if (isset($filters['value'])) { + $filter = $filters['value']; + if (is_callable($filter)) { + $filePath = $filter($file); + } else { + $filePath = preg_replace($filter, '', $filePath); + } + } + } + + if ($fileKey !== null) { + $results[$fileKey] = $filePath; + } else { + $results[] = $filePath; + } + } + + return $results; + } + + /** + * Recursively copy directory in filesystem. + * + * @param string $source + * @param string $target + * @param string|null $ignore Ignore files matching pattern (regular expression). + * @return void + * @throws RuntimeException + */ + public static function copy($source, $target, $ignore = null) + { + $source = rtrim($source, '\\/'); + $target = rtrim($target, '\\/'); + + if (!is_dir($source)) { + throw new RuntimeException('Cannot copy non-existing folder.'); + } + + // Make sure that path to the target exists before copying. + self::create($target); + + $success = true; + + // Go through all sub-directories and copy everything. + $files = self::all($source); + foreach ($files as $file) { + if ($ignore && preg_match($ignore, $file)) { + continue; + } + $src = $source .'/'. $file; + $dst = $target .'/'. $file; + + if (is_dir($src)) { + // Create current directory (if it doesn't exist). + if (!is_dir($dst)) { + $success &= @mkdir($dst, 0777, true); + } + } else { + // Or copy current file. + $success &= @copy($src, $dst); + } + } + + if (!$success) { + $error = error_get_last(); + throw new RuntimeException($error['message'] ?? 'Unknown error'); + } + + // Make sure that the change will be detected when caching. + @touch(dirname($target)); + } + + /** + * Move directory in filesystem. + * + * @param string $source + * @param string $target + * @return void + * @throws RuntimeException + */ + public static function move($source, $target) + { + if (!file_exists($source) || !is_dir($source)) { + // Rename fails if source folder does not exist. + throw new RuntimeException('Cannot move non-existing folder.'); + } + + // Don't do anything if the source is the same as the new target + if ($source === $target) { + return; + } + + if (strpos($target, $source . '/') === 0) { + throw new RuntimeException('Cannot move folder to itself'); + } + + if (file_exists($target)) { + // Rename fails if target folder exists. + throw new RuntimeException('Cannot move files to existing folder/file.'); + } + + // Make sure that path to the target exists before moving. + self::create(dirname($target)); + + // Silence warnings (chmod failed etc). + @rename($source, $target); + + // Rename function can fail while still succeeding, so let's check if the folder exists. + if (is_dir($source)) { + // Rename doesn't support moving folders across filesystems. Use copy instead. + self::copy($source, $target); + self::delete($source); + } + + // Make sure that the change will be detected when caching. + @touch(dirname($source)); + @touch(dirname($target)); + @touch($target); + } + + /** + * Recursively delete directory from filesystem. + * + * @param string $target + * @param bool $include_target + * @return bool + * @throws RuntimeException + */ + public static function delete($target, $include_target = true) + { + if (!is_dir($target)) { + return false; + } + + $success = self::doDelete($target, $include_target); + + if (!$success) { + $error = error_get_last(); + + throw new RuntimeException($error['message'] ?? 'Unknown error'); + } + + // Make sure that the change will be detected when caching. + if ($include_target) { + @touch(dirname($target)); + } else { + @touch($target); + } + + return $success; + } + + /** + * @param string $folder + * @return void + * @throws RuntimeException + */ + public static function mkdir($folder) + { + self::create($folder); + } + + /** + * @param string $folder + * @return void + * @throws RuntimeException + */ + public static function create($folder) + { + // Silence error for open_basedir; should fail in mkdir instead. + if (@is_dir($folder)) { + return; + } + + $success = @mkdir($folder, 0777, true); + + if (!$success) { + // Take yet another look, make sure that the folder doesn't exist. + clearstatcache(true, $folder); + if (!@is_dir($folder)) { + throw new RuntimeException(sprintf('Unable to create directory: %s', $folder)); + } + } + } + + /** + * Recursive copy of one directory to another + * + * @param string $src + * @param string $dest + * @return bool + * @throws RuntimeException + */ + public static function rcopy($src, $dest) + { + + // If the src is not a directory do a simple file copy + if (!is_dir($src)) { + copy($src, $dest); + return true; + } + + // If the destination directory does not exist create it + if (!is_dir($dest)) { + static::create($dest); + } + + // Open the source directory to read in files + $i = new DirectoryIterator($src); + foreach ($i as $f) { + if ($f->isFile()) { + copy($f->getRealPath(), "{$dest}/" . $f->getFilename()); + } else { + if (!$f->isDot() && $f->isDir()) { + static::rcopy($f->getRealPath(), "{$dest}/{$f}"); + } + } + } + return true; + } + + /** + * Does a directory contain children + * + * @param string $directory + * @return int|false + */ + public static function countChildren($directory) + { + if (!is_dir($directory)) { + return false; + } + $directories = glob($directory . '/*', GLOB_ONLYDIR); + + return $directories ? count($directories) : false; + } + + /** + * @param string $folder + * @param bool $include_target + * @return bool + * @internal + */ + protected static function doDelete($folder, $include_target = true) + { + // Special case for symbolic links. + if ($include_target && is_link($folder)) { + return @unlink($folder); + } + + // Go through all items in filesystem and recursively remove everything. + $files = scandir($folder, SCANDIR_SORT_NONE); + $files = $files ? array_diff($files, ['.', '..']) : []; + foreach ($files as $file) { + $path = "{$folder}/{$file}"; + is_dir($path) ? self::doDelete($path) : @unlink($path); + } + + return $include_target ? @rmdir($folder) : true; + } +} diff --git a/system/src/Grav/Common/Filesystem/RecursiveDirectoryFilterIterator.php b/system/src/Grav/Common/Filesystem/RecursiveDirectoryFilterIterator.php new file mode 100644 index 0000000..5422ffd --- /dev/null +++ b/system/src/Grav/Common/Filesystem/RecursiveDirectoryFilterIterator.php @@ -0,0 +1,82 @@ +current(); + $filename = $file->getFilename(); + $relative_filename = str_replace($this::$root . '/', '', $file->getPathname()); + + if ($file->isDir()) { + if (in_array($relative_filename, $this::$ignore_folders, true)) { + return false; + } + if (!in_array($filename, $this::$ignore_files, true)) { + return true; + } + } elseif ($file->isFile() && !in_array($filename, $this::$ignore_files, true)) { + return true; + } + return false; + } + + /** + * @return RecursiveDirectoryFilterIterator|RecursiveFilterIterator + */ + public function getChildren() :RecursiveFilterIterator + { + /** @var RecursiveDirectoryFilterIterator $iterator */ + $iterator = $this->getInnerIterator(); + + return new self($iterator->getChildren(), $this::$root, $this::$ignore_folders, $this::$ignore_files); + } +} diff --git a/system/src/Grav/Common/Filesystem/RecursiveFolderFilterIterator.php b/system/src/Grav/Common/Filesystem/RecursiveFolderFilterIterator.php new file mode 100644 index 0000000..d027b6b --- /dev/null +++ b/system/src/Grav/Common/Filesystem/RecursiveFolderFilterIterator.php @@ -0,0 +1,55 @@ +get('system.pages.ignore_folders'); + } + + $this::$ignore_folders = $ignore_folders; + } + + /** + * Check whether the current element of the iterator is acceptable + * + * @return bool true if the current element is acceptable, otherwise false. + */ + public function accept() :bool + { + /** @var SplFileInfo $current */ + $current = $this->current(); + + return $current->isDir() && !in_array($current->getFilename(), $this::$ignore_folders, true); + } +} diff --git a/system/src/Grav/Common/Filesystem/ZipArchiver.php b/system/src/Grav/Common/Filesystem/ZipArchiver.php new file mode 100644 index 0000000..8e61a5d --- /dev/null +++ b/system/src/Grav/Common/Filesystem/ZipArchiver.php @@ -0,0 +1,135 @@ +open($this->archive_file); + + if ($archive === true) { + Folder::create($destination); + + if (!$zip->extractTo($destination)) { + throw new RuntimeException('ZipArchiver: ZIP failed to extract ' . $this->archive_file . ' to ' . $destination); + } + + $zip->close(); + + return $this; + } + + throw new RuntimeException('ZipArchiver: Failed to open ' . $this->archive_file); + } + + /** + * @param string $source + * @param callable|null $status + * @return $this + */ + public function compress($source, callable $status = null) + { + if (!extension_loaded('zip')) { + throw new InvalidArgumentException('ZipArchiver: Zip PHP module not installed...'); + } + + // Get real path for our folder + $rootPath = realpath($source); + if (!$rootPath) { + throw new InvalidArgumentException('ZipArchiver: ' . $source . ' cannot be found...'); + } + + $zip = new ZipArchive(); + if (!$zip->open($this->archive_file, ZipArchive::CREATE)) { + throw new InvalidArgumentException('ZipArchiver:' . $this->archive_file . ' cannot be created...'); + } + + $files = $this->getArchiveFiles($rootPath); + + $status && $status([ + 'type' => 'count', + 'steps' => iterator_count($files), + ]); + + foreach ($files as $file) { + $filePath = $file->getPathname(); + $relativePath = ltrim(substr($filePath, strlen($rootPath)), '/'); + + if ($file->isDir()) { + $zip->addEmptyDir($relativePath); + } else { + $zip->addFile($filePath, $relativePath); + } + + $status && $status([ + 'type' => 'progress', + ]); + } + + $status && $status([ + 'type' => 'message', + 'message' => 'Compressing...' + ]); + + $zip->close(); + + return $this; + } + + /** + * @param array $folders + * @param callable|null $status + * @return $this + */ + public function addEmptyFolders($folders, callable $status = null) + { + if (!extension_loaded('zip')) { + throw new InvalidArgumentException('ZipArchiver: Zip PHP module not installed...'); + } + + $zip = new ZipArchive(); + if (!$zip->open($this->archive_file)) { + throw new InvalidArgumentException('ZipArchiver: ' . $this->archive_file . ' cannot be opened...'); + } + + $status && $status([ + 'type' => 'message', + 'message' => 'Adding empty folders...' + ]); + + foreach ($folders as $folder) { + $zip->addEmptyDir($folder); + $status && $status([ + 'type' => 'progress', + ]); + } + + $zip->close(); + + return $this; + } +} diff --git a/system/src/Grav/Common/Flex/FlexCollection.php b/system/src/Grav/Common/Flex/FlexCollection.php new file mode 100644 index 0000000..9e43e27 --- /dev/null +++ b/system/src/Grav/Common/Flex/FlexCollection.php @@ -0,0 +1,28 @@ + + */ +abstract class FlexCollection extends \Grav\Framework\Flex\FlexCollection +{ + use FlexGravTrait; + use FlexCollectionTrait; +} diff --git a/system/src/Grav/Common/Flex/FlexIndex.php b/system/src/Grav/Common/Flex/FlexIndex.php new file mode 100644 index 0000000..2fe02f0 --- /dev/null +++ b/system/src/Grav/Common/Flex/FlexIndex.php @@ -0,0 +1,29 @@ + + */ +abstract class FlexIndex extends \Grav\Framework\Flex\FlexIndex +{ + use FlexGravTrait; + use FlexIndexTrait; +} diff --git a/system/src/Grav/Common/Flex/FlexObject.php b/system/src/Grav/Common/Flex/FlexObject.php new file mode 100644 index 0000000..870bc05 --- /dev/null +++ b/system/src/Grav/Common/Flex/FlexObject.php @@ -0,0 +1,74 @@ +getNestedProperty($name, null, $separator); + + // Handle media order field. + if (null === $value && $name === 'media_order') { + return implode(',', $this->getMediaOrder()); + } + + // Handle media fields. + $settings = $this->getFieldSettings($name); + if (($settings['media_field'] ?? false) === true) { + return $this->parseFileProperty($value, $settings); + } + + return $value ?? $default; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::prepareStorage() + */ + public function prepareStorage(): array + { + // Remove extra content from media fields. + $fields = $this->getMediaFields(); + foreach ($fields as $field) { + $data = $this->getNestedProperty($field); + if (is_array($data)) { + foreach ($data as $name => &$image) { + unset($image['image_url'], $image['thumb_url']); + } + unset($image); + $this->setNestedProperty($field, $data); + } + } + + return parent::prepareStorage(); + } +} diff --git a/system/src/Grav/Common/Flex/Traits/FlexCollectionTrait.php b/system/src/Grav/Common/Flex/Traits/FlexCollectionTrait.php new file mode 100644 index 0000000..ba1b8a1 --- /dev/null +++ b/system/src/Grav/Common/Flex/Traits/FlexCollectionTrait.php @@ -0,0 +1,51 @@ + 'flex', + 'directory' => $this->getFlexDirectory(), + 'collection' => $this + ]); + } + if (strpos($name, 'onFlexCollection') !== 0 && strpos($name, 'on') === 0) { + $name = 'onFlexCollection' . substr($name, 2); + } + + $container = $this->getContainer(); + if ($event instanceof Event) { + $container->fireEvent($name, $event); + } else { + $container->dispatchEvent($event); + } + + return $this; + } +} diff --git a/system/src/Grav/Common/Flex/Traits/FlexCommonTrait.php b/system/src/Grav/Common/Flex/Traits/FlexCommonTrait.php new file mode 100644 index 0000000..4647dfc --- /dev/null +++ b/system/src/Grav/Common/Flex/Traits/FlexCommonTrait.php @@ -0,0 +1,54 @@ +getContainer(); + + /** @var Twig $twig */ + $twig = $container['twig']; + + try { + return $twig->twig()->resolveTemplate($this->getTemplatePaths($layout)); + } catch (LoaderError $e) { + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $debugger->addException($e); + + return $twig->twig()->resolveTemplate(['flex/404.html.twig']); + } + } + + abstract protected function getTemplatePaths(string $layout): array; + abstract protected function getContainer(): Grav; +} diff --git a/system/src/Grav/Common/Flex/Traits/FlexGravTrait.php b/system/src/Grav/Common/Flex/Traits/FlexGravTrait.php new file mode 100644 index 0000000..1272d5d --- /dev/null +++ b/system/src/Grav/Common/Flex/Traits/FlexGravTrait.php @@ -0,0 +1,74 @@ +getContainer(); + + /** @var Flex $flex */ + $flex = $container['flex']; + + return $flex; + } + + /** + * @return UserInterface|null + */ + protected function getActiveUser(): ?UserInterface + { + $container = $this->getContainer(); + + /** @var UserInterface|null $user */ + $user = $container['user'] ?? null; + + return $user; + } + + /** + * @return bool + */ + protected function isAdminSite(): bool + { + $container = $this->getContainer(); + + return isset($container['admin']); + } + + /** + * @return string + */ + protected function getAuthorizeScope(): string + { + return $this->isAdminSite() ? 'admin' : 'site'; + } +} diff --git a/system/src/Grav/Common/Flex/Traits/FlexIndexTrait.php b/system/src/Grav/Common/Flex/Traits/FlexIndexTrait.php new file mode 100644 index 0000000..418b769 --- /dev/null +++ b/system/src/Grav/Common/Flex/Traits/FlexIndexTrait.php @@ -0,0 +1,20 @@ + 'onFlexObjectRender', + 'onBeforeSave' => 'onFlexObjectBeforeSave', + 'onAfterSave' => 'onFlexObjectAfterSave', + 'onBeforeDelete' => 'onFlexObjectBeforeDelete', + 'onAfterDelete' => 'onFlexObjectAfterDelete' + ]; + + if (null === $event) { + $event = new Event([ + 'type' => 'flex', + 'directory' => $this->getFlexDirectory(), + 'object' => $this + ]); + } + + if (isset($events['name'])) { + $name = $events['name']; + } elseif (strpos($name, 'onFlexObject') !== 0 && strpos($name, 'on') === 0) { + $name = 'onFlexObject' . substr($name, 2); + } + + $container = $this->getContainer(); + if ($event instanceof Event) { + $container->fireEvent($name, $event); + } else { + $container->dispatchEvent($event); + } + + return $this; + } +} diff --git a/system/src/Grav/Common/Flex/Types/Generic/GenericCollection.php b/system/src/Grav/Common/Flex/Types/Generic/GenericCollection.php new file mode 100644 index 0000000..6cb2874 --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/Generic/GenericCollection.php @@ -0,0 +1,24 @@ + + */ +class GenericCollection extends FlexCollection +{ +} diff --git a/system/src/Grav/Common/Flex/Types/Generic/GenericIndex.php b/system/src/Grav/Common/Flex/Types/Generic/GenericIndex.php new file mode 100644 index 0000000..a3b2f71 --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/Generic/GenericIndex.php @@ -0,0 +1,24 @@ + + */ +class GenericIndex extends FlexIndex +{ +} diff --git a/system/src/Grav/Common/Flex/Types/Generic/GenericObject.php b/system/src/Grav/Common/Flex/Types/Generic/GenericObject.php new file mode 100644 index 0000000..ae03d68 --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/Generic/GenericObject.php @@ -0,0 +1,22 @@ + + * @implements PageCollectionInterface + * + * Incompatibilities with Grav\Common\Page\Collection: + * $page = $collection->key() will not work at all + * $clone = clone $collection does not clone objects inside the collection, does it matter? + * $string = (string)$collection returns collection id instead of comma separated list + * $collection->add() incompatible method signature + * $collection->remove() incompatible method signature + * $collection->filter() incompatible method signature (takes closure instead of callable) + * $collection->prev() does not rewind the internal pointer + * AND most methods are immutable; they do not update the current collection, but return updated one + * + * @method PageIndex getIndex() + */ +class PageCollection extends FlexPageCollection implements PageCollectionInterface +{ + use FlexGravTrait; + use FlexCollectionTrait; + + /** @var array|null */ + protected $_params; + + /** + * @return array + */ + public static function getCachedMethods(): array + { + return [ + // Collection specific methods + 'getRoot' => false, + 'getParams' => false, + 'setParams' => false, + 'params' => false, + 'addPage' => false, + 'merge' => false, + 'intersect' => false, + 'prev' => false, + 'nth' => false, + 'random' => false, + 'append' => false, + 'batch' => false, + 'order' => false, + + // Collection filtering + 'dateRange' => true, + 'visible' => true, + 'nonVisible' => true, + 'pages' => true, + 'modules' => true, + 'modular' => true, + 'nonModular' => true, + 'published' => true, + 'nonPublished' => true, + 'routable' => true, + 'nonRoutable' => true, + 'ofType' => true, + 'ofOneOfTheseTypes' => true, + 'ofOneOfTheseAccessLevels' => true, + 'withOrdered' => true, + 'withModules' => true, + 'withPages' => true, + 'withTranslation' => true, + 'filterBy' => true, + + 'toExtendedArray' => false, + 'getLevelListing' => false, + ] + parent::getCachedMethods(); + } + + /** + * @return PageInterface + */ + public function getRoot() + { + return $this->getIndex()->getRoot(); + } + + /** + * Get the collection params + * + * @return array + */ + public function getParams(): array + { + return $this->_params ?? []; + } + + /** + * Set parameters to the Collection + * + * @param array $params + * @return $this + */ + public function setParams(array $params) + { + $this->_params = $this->_params ? array_merge($this->_params, $params) : $params; + + return $this; + } + + /** + * Get the collection params + * + * @return array + */ + public function params(): array + { + return $this->getParams(); + } + + /** + * Add a single page to a collection + * + * @param PageInterface $page + * @return $this + */ + public function addPage(PageInterface $page) + { + if (!$page instanceof PageObject) { + throw new InvalidArgumentException('$page is not a flex page.'); + } + + // FIXME: support other keys. + $this->set($page->getKey(), $page); + + return $this; + } + + /** + * + * Merge another collection with the current collection + * + * @param PageCollectionInterface $collection + * @return static + * @phpstan-return static + */ + public function merge(PageCollectionInterface $collection) + { + throw new RuntimeException(__METHOD__ . '(): Not Implemented'); + } + + /** + * Intersect another collection with the current collection + * + * @param PageCollectionInterface $collection + * @return static + * @phpstan-return static + */ + public function intersect(PageCollectionInterface $collection) + { + throw new RuntimeException(__METHOD__ . '(): Not Implemented'); + } + + /** + * Set current page. + */ + public function setCurrent(string $path): void + { + throw new RuntimeException(__METHOD__ . '(): Not Implemented'); + } + + /** + * Return previous item. + * + * @return PageInterface|false + * @phpstan-return T|false + */ + public function prev() + { + // FIXME: this method does not rewind the internal pointer! + $key = (string)$this->key(); + $prev = $this->prevSibling($key); + + return $prev !== $this->current() ? $prev : false; + } + + /** + * Return nth item. + * @param int $key + * @return PageInterface|bool + * @phpstan-return T|false + */ + public function nth($key) + { + return $this->slice($key, 1)[0] ?? false; + } + + /** + * Pick one or more random entries. + * + * @param int $num Specifies how many entries should be picked. + * @return static + * @phpstan-return static + */ + public function random($num = 1) + { + return $this->createFrom($this->shuffle()->slice(0, $num)); + } + + /** + * Append new elements to the list. + * + * @param array $items Items to be appended. Existing keys will be overridden with the new values. + * @return static + * @phpstan-return static + */ + public function append($items) + { + throw new RuntimeException(__METHOD__ . '(): Not Implemented'); + } + + /** + * Split collection into array of smaller collections. + * + * @param int $size + * @return static[] + * @phpstan-return static[] + */ + public function batch($size): array + { + $chunks = $this->chunk($size); + + $list = []; + foreach ($chunks as $chunk) { + $list[] = $this->createFrom($chunk); + } + + return $list; + } + + /** + * Reorder collection. + * + * @param string $by + * @param string $dir + * @param array|null $manual + * @param int|null $sort_flags + * @return static + * @phpstan-return static + */ + public function order($by, $dir = 'asc', $manual = null, $sort_flags = null) + { + if (!$this->count()) { + return $this; + } + + if ($by === 'random') { + return $this->shuffle(); + } + + $keys = $this->buildSort($by, $dir, $manual, $sort_flags); + + return $this->createFrom(array_replace(array_flip($keys), $this->toArray()) ?? []); + } + + /** + * @param string $order_by + * @param string $order_dir + * @param array|null $manual + * @param int|null $sort_flags + * @return array + */ + protected function buildSort($order_by = 'default', $order_dir = 'asc', $manual = null, $sort_flags = null): array + { + // do this header query work only once + $header_query = null; + $header_default = null; + if (strpos($order_by, 'header.') === 0) { + $query = explode('|', str_replace('header.', '', $order_by), 2); + $header_query = array_shift($query) ?? ''; + $header_default = array_shift($query); + } + + $list = []; + foreach ($this as $key => $child) { + switch ($order_by) { + case 'title': + $list[$key] = $child->title(); + break; + case 'date': + $list[$key] = $child->date(); + $sort_flags = SORT_REGULAR; + break; + case 'modified': + $list[$key] = $child->modified(); + $sort_flags = SORT_REGULAR; + break; + case 'publish_date': + $list[$key] = $child->publishDate(); + $sort_flags = SORT_REGULAR; + break; + case 'unpublish_date': + $list[$key] = $child->unpublishDate(); + $sort_flags = SORT_REGULAR; + break; + case 'slug': + $list[$key] = $child->slug(); + break; + case 'basename': + $list[$key] = Utils::basename($key); + break; + case 'folder': + $list[$key] = $child->folder(); + break; + case 'manual': + case 'default': + default: + if (is_string($header_query)) { + /** @var Header $child_header */ + $child_header = $child->header(); + $header_value = $child_header->get($header_query); + if (is_array($header_value)) { + $list[$key] = implode(',', $header_value); + } elseif ($header_value) { + $list[$key] = $header_value; + } else { + $list[$key] = $header_default ?: $key; + } + $sort_flags = $sort_flags ?: SORT_REGULAR; + break; + } + $list[$key] = $key; + $sort_flags = $sort_flags ?: SORT_REGULAR; + } + } + + if (null === $sort_flags) { + $sort_flags = SORT_NATURAL | SORT_FLAG_CASE; + } + + // else just sort the list according to specified key + if (extension_loaded('intl') && Grav::instance()['config']->get('system.intl_enabled')) { + $locale = setlocale(LC_COLLATE, '0'); //`setlocale` with a '0' param returns the current locale set + $col = Collator::create($locale); + if ($col) { + $col->setAttribute(Collator::NUMERIC_COLLATION, Collator::ON); + if (($sort_flags & SORT_NATURAL) === SORT_NATURAL) { + $list = preg_replace_callback('~([0-9]+)\.~', static function ($number) { + return sprintf('%032d.', $number[0]); + }, $list); + if (!is_array($list)) { + throw new RuntimeException('Internal Error'); + } + + $list_vals = array_values($list); + if (is_numeric(array_shift($list_vals))) { + $sort_flags = Collator::SORT_REGULAR; + } else { + $sort_flags = Collator::SORT_STRING; + } + } + + $col->asort($list, $sort_flags); + } else { + asort($list, $sort_flags); + } + } else { + asort($list, $sort_flags); + } + + // Move manually ordered items into the beginning of the list. Order of the unlisted items does not change. + if (is_array($manual) && !empty($manual)) { + $i = count($manual); + $new_list = []; + foreach ($list as $key => $dummy) { + $child = $this[$key] ?? null; + $order = $child ? array_search($child->slug, $manual, true) : false; + if ($order === false) { + $order = $i++; + } + $new_list[$key] = (int)$order; + } + + $list = $new_list; + + // Apply manual ordering to the list. + asort($list, SORT_NUMERIC); + } + + if ($order_dir !== 'asc') { + $list = array_reverse($list); + } + + return array_keys($list); + } + + /** + * Mimicks Pages class. + * + * @return $this + * @deprecated 1.7 Not needed anymore in Flex Pages (does nothing). + */ + public function all() + { + return $this; + } + + /** + * Returns the items between a set of date ranges of either the page date field (default) or + * an arbitrary datetime page field where start date and end date are optional + * Dates must be passed in as text that strtotime() can process + * http://php.net/manual/en/function.strtotime.php + * + * @param string|null $startDate + * @param string|null $endDate + * @param string|null $field + * @return static + * @phpstan-return static + * @throws Exception + */ + public function dateRange($startDate = null, $endDate = null, $field = null) + { + $start = $startDate ? Utils::date2timestamp($startDate) : null; + $end = $endDate ? Utils::date2timestamp($endDate) : null; + + $entries = []; + foreach ($this as $key => $object) { + if (!$object) { + continue; + } + + $date = $field ? strtotime($object->getNestedProperty($field)) : $object->date(); + + if ((!$start || $date >= $start) && (!$end || $date <= $end)) { + $entries[$key] = $object; + } + } + + return $this->createFrom($entries); + } + + /** + * Creates new collection with only visible pages + * + * @return static The collection with only visible pages + * @phpstan-return static + */ + public function visible() + { + $entries = []; + foreach ($this as $key => $object) { + if ($object && $object->visible()) { + $entries[$key] = $object; + } + } + + return $this->createFrom($entries); + } + + /** + * Creates new collection with only non-visible pages + * + * @return static The collection with only non-visible pages + * @phpstan-return static + */ + public function nonVisible() + { + $entries = []; + foreach ($this as $key => $object) { + if ($object && !$object->visible()) { + $entries[$key] = $object; + } + } + + return $this->createFrom($entries); + } + + /** + * Creates new collection with only pages + * + * @return static The collection with only pages + * @phpstan-return static + */ + public function pages() + { + $entries = []; + /** + * @var int|string $key + * @var PageInterface|null $object + */ + foreach ($this as $key => $object) { + if ($object && !$object->isModule()) { + $entries[$key] = $object; + } + } + + return $this->createFrom($entries); + } + + /** + * Creates new collection with only modules + * + * @return static The collection with only modules + * @phpstan-return static + */ + public function modules() + { + $entries = []; + /** + * @var int|string $key + * @var PageInterface|null $object + */ + foreach ($this as $key => $object) { + if ($object && $object->isModule()) { + $entries[$key] = $object; + } + } + + return $this->createFrom($entries); + } + + /** + * Alias of modules() + * + * @return static + * @phpstan-return static + */ + public function modular() + { + return $this->modules(); + } + + /** + * Alias of pages() + * + * @return static + * @phpstan-return static + */ + public function nonModular() + { + return $this->pages(); + } + + /** + * Creates new collection with only published pages + * + * @return static The collection with only published pages + * @phpstan-return static + */ + public function published() + { + $entries = []; + foreach ($this as $key => $object) { + if ($object && $object->published()) { + $entries[$key] = $object; + } + } + + return $this->createFrom($entries); + } + + /** + * Creates new collection with only non-published pages + * + * @return static The collection with only non-published pages + * @phpstan-return static + */ + public function nonPublished() + { + $entries = []; + foreach ($this as $key => $object) { + if ($object && !$object->published()) { + $entries[$key] = $object; + } + } + + return $this->createFrom($entries); + } + + /** + * Creates new collection with only routable pages + * + * @return static The collection with only routable pages + * @phpstan-return static + */ + public function routable() + { + $entries = []; + foreach ($this as $key => $object) { + if ($object && $object->routable()) { + $entries[$key] = $object; + } + } + + return $this->createFrom($entries); + } + + /** + * Creates new collection with only non-routable pages + * + * @return static The collection with only non-routable pages + * @phpstan-return static + */ + public function nonRoutable() + { + $entries = []; + foreach ($this as $key => $object) { + if ($object && !$object->routable()) { + $entries[$key] = $object; + } + } + + return $this->createFrom($entries); + } + + /** + * Creates new collection with only pages of the specified type + * + * @param string $type + * @return static The collection + * @phpstan-return static + */ + public function ofType($type) + { + $entries = []; + foreach ($this as $key => $object) { + if ($object && $object->template() === $type) { + $entries[$key] = $object; + } + } + + return $this->createFrom($entries); + } + + /** + * Creates new collection with only pages of one of the specified types + * + * @param string[] $types + * @return static The collection + * @phpstan-return static + */ + public function ofOneOfTheseTypes($types) + { + $entries = []; + foreach ($this as $key => $object) { + if ($object && in_array($object->template(), $types, true)) { + $entries[$key] = $object; + } + } + + return $this->createFrom($entries); + } + + /** + * Creates new collection with only pages of one of the specified access levels + * + * @param array $accessLevels + * @return static The collection + * @phpstan-return static + */ + public function ofOneOfTheseAccessLevels($accessLevels) + { + $entries = []; + foreach ($this as $key => $object) { + if ($object && isset($object->header()->access)) { + if (is_array($object->header()->access)) { + //Multiple values for access + $valid = false; + + foreach ($object->header()->access as $index => $accessLevel) { + if (is_array($accessLevel)) { + foreach ($accessLevel as $innerIndex => $innerAccessLevel) { + if (in_array($innerAccessLevel, $accessLevels)) { + $valid = true; + } + } + } else { + if (in_array($index, $accessLevels)) { + $valid = true; + } + } + } + if ($valid) { + $entries[$key] = $object; + } + } else { + //Single value for access + if (in_array($object->header()->access, $accessLevels)) { + $entries[$key] = $object; + } + } + } + } + + return $this->createFrom($entries); + } + + /** + * @param bool $bool + * @return static + * @phpstan-return static + */ + public function withOrdered(bool $bool = true) + { + $list = array_keys(array_filter($this->call('isOrdered', [$bool]))); + + return $this->select($list); + } + + /** + * @param bool $bool + * @return static + * @phpstan-return static + */ + public function withModules(bool $bool = true) + { + $list = array_keys(array_filter($this->call('isModule', [$bool]))); + + return $this->select($list); + } + + /** + * @param bool $bool + * @return static + * @phpstan-return static + */ + public function withPages(bool $bool = true) + { + $list = array_keys(array_filter($this->call('isPage', [$bool]))); + + return $this->select($list); + } + + /** + * @param bool $bool + * @param string|null $languageCode + * @param bool|null $fallback + * @return static + * @phpstan-return static + */ + public function withTranslation(bool $bool = true, string $languageCode = null, bool $fallback = null) + { + $list = array_keys(array_filter($this->call('hasTranslation', [$languageCode, $fallback]))); + + return $bool ? $this->select($list) : $this->unselect($list); + } + + /** + * @param string|null $languageCode + * @param bool|null $fallback + * @return PageIndex + */ + public function withTranslated(string $languageCode = null, bool $fallback = null) + { + return $this->getIndex()->withTranslated($languageCode, $fallback); + } + + /** + * Filter pages by given filters. + * + * - search: string + * - page_type: string|string[] + * - modular: bool + * - visible: bool + * - routable: bool + * - published: bool + * - page: bool + * - translated: bool + * + * @param array $filters + * @param bool $recursive + * @return static + * @phpstan-return static + */ + public function filterBy(array $filters, bool $recursive = false) + { + $list = array_keys(array_filter($this->call('filterBy', [$filters, $recursive]))); + + return $this->select($list); + } + + /** + * Get the extended version of this Collection with each page keyed by route + * + * @return array + * @throws Exception + */ + public function toExtendedArray(): array + { + $entries = []; + foreach ($this as $key => $object) { + if ($object) { + $entries[$object->route()] = $object->toArray(); + } + } + + return $entries; + } + + /** + * @param array $options + * @return array + */ + public function getLevelListing(array $options): array + { + /** @var PageIndex $index */ + $index = $this->getIndex(); + + return method_exists($index, 'getLevelListing') ? $index->getLevelListing($options) : []; + } +} diff --git a/system/src/Grav/Common/Flex/Types/Pages/PageIndex.php b/system/src/Grav/Common/Flex/Types/Pages/PageIndex.php new file mode 100644 index 0000000..21e02ab --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/Pages/PageIndex.php @@ -0,0 +1,1198 @@ + + * @implements PageCollectionInterface + * + * @method PageIndex withModules(bool $bool = true) + * @method PageIndex withPages(bool $bool = true) + * @method PageIndex withTranslation(bool $bool = true, string $languageCode = null, bool $fallback = null) + */ +class PageIndex extends FlexPageIndex implements PageCollectionInterface +{ + use FlexGravTrait; + use FlexIndexTrait; + + public const VERSION = parent::VERSION . '.5'; + public const ORDER_LIST_REGEX = '/(\/\d+)\.[^\/]+/u'; + public const PAGE_ROUTE_REGEX = '/\/\d+\./u'; + + /** @var PageObject|array */ + protected $_root; + /** @var array|null */ + protected $_params; + + /** + * @param array $entries + * @param FlexDirectory|null $directory + */ + public function __construct(array $entries = [], FlexDirectory $directory = null) + { + // Remove root if it's taken. + if (isset($entries[''])) { + $this->_root = $entries['']; + unset($entries['']); + } + + parent::__construct($entries, $directory); + } + + /** + * @param FlexStorageInterface $storage + * @return array + */ + public static function loadEntriesFromStorage(FlexStorageInterface $storage): array + { + // Load saved index. + $index = static::loadIndex($storage); + + $version = $index['version'] ?? 0; + $force = static::VERSION !== $version; + + // TODO: Following check flex index to be out of sync after some saves, disabled until better solution is found. + //$timestamp = $index['timestamp'] ?? 0; + //if (!$force && $timestamp && $timestamp > time() - 1) { + // return $index['index']; + //} + + // Load up to date index. + $entries = parent::loadEntriesFromStorage($storage); + + return static::updateIndexFile($storage, $index['index'], $entries, ['include_missing' => true, 'force_update' => $force]); + } + + /** + * @param string $key + * @return PageObject|null + * @phpstan-return T|null + */ + public function get($key) + { + if (mb_strpos($key, '|') !== false) { + [$key, $params] = explode('|', $key, 2); + } + + $element = parent::get($key); + if (null === $element) { + return null; + } + + if (isset($params)) { + $element = $element->getTranslation(ltrim($params, '.')); + } + + \assert(null === $element || $element instanceof PageObject); + + return $element; + } + + /** + * @return PageInterface + */ + public function getRoot() + { + $root = $this->_root; + if (is_array($root)) { + $directory = $this->getFlexDirectory(); + $storage = $directory->getStorage(); + + $defaults = [ + 'header' => [ + 'routable' => false, + 'permissions' => [ + 'inherit' => false + ] + ] + ]; + + $row = $storage->readRows(['' => null])[''] ?? null; + if (null !== $row) { + if (isset($row['__ERROR'])) { + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $message = sprintf('Flex Pages: root page is broken in storage: %s', $row['__ERROR']); + + $debugger->addException(new RuntimeException($message)); + $debugger->addMessage($message, 'error'); + + $row = ['__META' => $root]; + } + + } else { + $row = ['__META' => $root]; + } + + $row = array_merge_recursive($defaults, $row); + + /** @var PageObject $root */ + $root = $this->getFlexDirectory()->createObject($row, '/', false); + $root->name('root.md'); + $root->root(true); + + $this->_root = $root; + } + + return $root; + } + + /** + * @param string|null $languageCode + * @param bool|null $fallback + * @return static + * @phpstan-return static + */ + public function withTranslated(string $languageCode = null, bool $fallback = null) + { + if (null === $languageCode) { + return $this; + } + + $entries = $this->translateEntries($this->getEntries(), $languageCode, $fallback); + $params = ['language' => $languageCode, 'language_fallback' => $fallback] + $this->getParams(); + + return $this->createFrom($entries)->setParams($params); + } + + /** + * @return string|null + */ + public function getLanguage(): ?string + { + return $this->_params['language'] ?? null; + } + + /** + * Get the collection params + * + * @return array + */ + public function getParams(): array + { + return $this->_params ?? []; + } + + /** + * Get the collection param + * + * @param string $name + * @return mixed + */ + public function getParam(string $name) + { + return $this->_params[$name] ?? null; + } + + /** + * Set parameters to the Collection + * + * @param array $params + * @return $this + */ + public function setParams(array $params) + { + $this->_params = $this->_params ? array_merge($this->_params, $params) : $params; + + return $this; + } + + /** + * Set a parameter to the Collection + * + * @param string $name + * @param mixed $value + * @return $this + */ + public function setParam(string $name, $value) + { + $this->_params[$name] = $value; + + return $this; + } + + /** + * Get the collection params + * + * @return array + */ + public function params(): array + { + return $this->getParams(); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getCacheKey() + */ + public function getCacheKey(): string + { + return $this->getTypePrefix() . $this->getFlexType() . '.' . sha1(json_encode($this->getKeys()) . $this->getKeyField() . $this->getLanguage()); + } + + /** + * Filter pages by given filters. + * + * - search: string + * - page_type: string|string[] + * - modular: bool + * - visible: bool + * - routable: bool + * - published: bool + * - page: bool + * - translated: bool + * + * @param array $filters + * @param bool $recursive + * @return static + * @phpstan-return static + */ + public function filterBy(array $filters, bool $recursive = false) + { + if (!$filters) { + return $this; + } + + if ($recursive) { + return $this->__call('filterBy', [$filters, true]); + } + + $list = []; + $index = $this; + foreach ($filters as $key => $value) { + switch ($key) { + case 'search': + $index = $index->search((string)$value); + break; + case 'page_type': + if (!is_array($value)) { + $value = is_string($value) && $value !== '' ? explode(',', $value) : []; + } + $index = $index->ofOneOfTheseTypes($value); + break; + case 'routable': + $index = $index->withRoutable((bool)$value); + break; + case 'published': + $index = $index->withPublished((bool)$value); + break; + case 'visible': + $index = $index->withVisible((bool)$value); + break; + case 'module': + $index = $index->withModules((bool)$value); + break; + case 'page': + $index = $index->withPages((bool)$value); + break; + case 'folder': + $index = $index->withPages(!$value); + break; + case 'translated': + $index = $index->withTranslation((bool)$value); + break; + default: + $list[$key] = $value; + } + } + + return $list ? $index->filterByParent($list) : $index; + } + + /** + * @param array $filters + * @return static + * @phpstan-return static + */ + protected function filterByParent(array $filters) + { + /** @var static $index */ + $index = parent::filterBy($filters); + + return $index; + } + + /** + * @param array $options + * @return array + */ + public function getLevelListing(array $options): array + { + // Undocumented B/C + $order = $options['order'] ?? 'asc'; + if ($order === SORT_ASC) { + $options['order'] = 'asc'; + } elseif ($order === SORT_DESC) { + $options['order'] = 'desc'; + } + + $options += [ + 'field' => null, + 'route' => null, + 'leaf_route' => null, + 'sortby' => null, + 'order' => 'asc', + 'lang' => null, + 'filters' => [], + ]; + + $options['filters'] += [ + 'type' => ['root', 'dir'], + ]; + + $key = 'page.idx.lev.' . sha1(json_encode($options, JSON_THROW_ON_ERROR) . $this->getCacheKey()); + $checksum = $this->getCacheChecksum(); + + $cache = $this->getCache('object'); + + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + + $result = null; + try { + $cached = $cache->get($key); + $test = $cached[0] ?? null; + $result = $test === $checksum ? ($cached[1] ?? null) : null; + } catch (\Psr\SimpleCache\InvalidArgumentException $e) { + $debugger->addException($e); + } + + try { + if (null === $result) { + $result = $this->getLevelListingRecurse($options); + $cache->set($key, [$checksum, $result]); + } + } catch (\Psr\SimpleCache\InvalidArgumentException $e) { + $debugger->addException($e); + } + + return $result; + } + + /** + * @param array $entries + * @param string|null $keyField + * @return static + * @phpstan-return static + */ + protected function createFrom(array $entries, string $keyField = null) + { + /** @var static $index */ + $index = parent::createFrom($entries, $keyField); + $index->_root = $this->getRoot(); + + return $index; + } + + /** + * @param array $entries + * @param string $lang + * @param bool|null $fallback + * @return array + */ + protected function translateEntries(array $entries, string $lang, bool $fallback = null): array + { + $languages = $this->getFallbackLanguages($lang, $fallback); + foreach ($entries as $key => &$entry) { + // Find out which version of the page we should load. + $translations = $this->getLanguageTemplates((string)$key); + if (!$translations) { + // No translations found, is this a folder? + continue; + } + + // Find a translation. + $template = null; + foreach ($languages as $code) { + if (isset($translations[$code])) { + $template = $translations[$code]; + break; + } + } + + // We couldn't find a translation, remove entry from the list. + if (!isset($code, $template)) { + unset($entries['key']); + continue; + } + + // Get the main key without template and language. + [$main_key,] = explode('|', $entry['storage_key'] . '|', 2); + + // Update storage key and language. + $entry['storage_key'] = $main_key . '|' . $template . '.' . $code; + $entry['lang'] = $code; + } + unset($entry); + + return $entries; + } + + /** + * @return array + */ + protected function getLanguageTemplates(string $key): array + { + $meta = $this->getMetaData($key); + $template = $meta['template'] ?? 'folder'; + $translations = $meta['markdown'] ?? []; + $list = []; + foreach ($translations as $code => $search) { + if (isset($search[$template])) { + // Use main template if possible. + $list[$code] = $template; + } elseif (!empty($search)) { + // Fall back to first matching template. + $list[$code] = key($search); + } + } + + return $list; + } + + /** + * @param string|null $languageCode + * @param bool|null $fallback + * @return array + */ + protected function getFallbackLanguages(string $languageCode = null, bool $fallback = null): array + { + $fallback = $fallback ?? true; + if (!$fallback && null !== $languageCode) { + return [$languageCode]; + } + + $grav = Grav::instance(); + + /** @var Language $language */ + $language = $grav['language']; + $languageCode = $languageCode ?? ''; + if ($languageCode === '' && $fallback) { + return $language->getFallbackLanguages(null, true); + } + + return $fallback ? $language->getFallbackLanguages($languageCode, true) : [$languageCode]; + } + + /** + * @param array $options + * @return array + */ + protected function getLevelListingRecurse(array $options): array + { + $filters = $options['filters'] ?? []; + $field = $options['field']; + $route = $options['route']; + $leaf_route = $options['leaf_route']; + $sortby = $options['sortby']; + $order = $options['order']; + $language = $options['lang']; + + $status = 'error'; + $response = []; + $extra = null; + + // Handle leaf_route + $leaf = null; + if ($leaf_route && $route !== $leaf_route) { + $nodes = explode('/', $leaf_route); + $sub_route = '/' . implode('/', array_slice($nodes, 1, $options['level']++)); + $options['route'] = $sub_route; + + [$status,,$leaf,$extra] = $this->getLevelListingRecurse($options); + } + + // Handle no route, assume page tree root + if (!$route) { + $page = $this->getRoot(); + } else { + $page = $this->get(trim($route, '/')); + } + $path = $page ? $page->path() : null; + + if ($field) { + // Get forced filters from the field. + $blueprint = $page ? $page->getBlueprint() : $this->getFlexDirectory()->getBlueprint(); + $settings = $blueprint->schema()->getProperty($field); + $filters = array_merge([], $filters, $settings['filters'] ?? []); + } + + // Clean up filter. + $filter_type = (array)($filters['type'] ?? []); + unset($filters['type']); + $filters = array_filter($filters, static function($val) { return $val !== null && $val !== ''; }); + + if ($page) { + $status = 'success'; + $msg = 'PLUGIN_ADMIN.PAGE_ROUTE_FOUND'; + + if ($page->root() && (!$filter_type || in_array('root', $filter_type, true))) { + if ($field) { + $response[] = [ + 'name' => '', + 'value' => '/', + 'item-key' => '', + 'filename' => '.', + 'extension' => '', + 'type' => 'root', + 'modified' => $page->modified(), + 'size' => 0, + 'symlink' => false, + 'has-children' => false + ]; + } else { + $response[] = [ + 'item-key' => '-root-', + 'icon' => 'root', + 'title' => 'Root', // FIXME + 'route' => [ + 'display' => '<root>', // FIXME + 'raw' => '_root', + ], + 'modified' => $page->modified(), + 'extras' => [ + 'template' => $page->template(), + //'lang' => null, + //'translated' => null, + 'langs' => [], + 'published' => false, + 'visible' => false, + 'routable' => false, + 'tags' => ['root', 'non-routable'], + 'actions' => ['edit'], // FIXME + ] + ]; + } + } + + /** @var PageCollection|PageIndex $children */ + $children = $page->children(); + /** @var PageIndex $children */ + $children = $children->getIndex(); + $selectedChildren = $children->filterBy($filters + ['language' => $language], true); + + /** @var Header $header */ + $header = $page->header(); + + if (!$field && $header->get('admin.children_display_order', 'collection') === 'collection' && ($orderby = $header->get('content.order.by'))) { + // Use custom sorting by page header. + $sortby = $orderby; + $order = $header->get('content.order.dir', $order); + $custom = $header->get('content.order.custom'); + } + + if ($sortby) { + // Sort children. + $selectedChildren = $selectedChildren->order($sortby, $order, $custom ?? null); + } + + /** @var UserInterface|null $user */ + $user = Grav::instance()['user'] ?? null; + + /** @var PageObject $child */ + foreach ($selectedChildren as $child) { + $selected = $child->path() === $extra; + $includeChildren = is_array($leaf) && !empty($leaf) && $selected; + if ($field) { + $child_count = count($child->children()); + $payload = [ + 'name' => $child->menu(), + 'value' => $child->rawRoute(), + 'item-key' => Utils::basename($child->rawRoute() ?? ''), + 'filename' => $child->folder(), + 'extension' => $child->extension(), + 'type' => 'dir', + 'modified' => $child->modified(), + 'size' => $child_count, + 'symlink' => false, + 'has-children' => $child_count > 0 + ]; + } else { + $lang = $child->findTranslation($language) ?? 'n/a'; + /** @var PageObject $child */ + $child = $child->getTranslation($language) ?? $child; + + // TODO: all these features are independent from each other, we cannot just have one icon/color to catch all. + // TODO: maybe icon by home/modular/page/folder (or even from blueprints) and color by visibility etc.. + if ($child->home()) { + $icon = 'home'; + } elseif ($child->isModule()) { + $icon = 'modular'; + } elseif ($child->visible()) { + $icon = 'visible'; + } elseif ($child->isPage()) { + $icon = 'page'; + } else { + // TODO: add support + $icon = 'folder'; + } + $tags = [ + $child->published() ? 'published' : 'non-published', + $child->visible() ? 'visible' : 'non-visible', + $child->routable() ? 'routable' : 'non-routable' + ]; + $extras = [ + 'template' => $child->template(), + 'lang' => $lang ?: null, + 'translated' => $lang ? $child->hasTranslation($language, false) : null, + 'langs' => $child->getAllLanguages(true) ?: null, + 'published' => $child->published(), + 'published_date' => $this->jsDate($child->publishDate()), + 'unpublished_date' => $this->jsDate($child->unpublishDate()), + 'visible' => $child->visible(), + 'routable' => $child->routable(), + 'tags' => $tags, + 'actions' => $this->getListingActions($child, $user), + ]; + $extras = array_filter($extras, static function ($v) { + return $v !== null; + }); + + /** @var PageIndex $tmp */ + $tmp = $child->children()->getIndex(); + $child_count = $tmp->count(); + $count = $filters ? $tmp->filterBy($filters, true)->count() : null; + $route = $child->getRoute(); + $route = $route ? ($route->toString(false) ?: '/') : ''; + $payload = [ + 'item-key' => htmlspecialchars(Utils::basename($child->rawRoute() ?? $child->getKey())), + 'icon' => $icon, + 'title' => htmlspecialchars($child->menu()), + 'route' => [ + 'display' => htmlspecialchars($route) ?: null, + 'raw' => htmlspecialchars($child->rawRoute()), + ], + 'modified' => $this->jsDate($child->modified()), + 'child_count' => $child_count ?: null, + 'count' => $count ?? null, + 'filters_hit' => $filters ? ($child->filterBy($filters, false) ?: null) : null, + 'extras' => $extras + ]; + $payload = array_filter($payload, static function ($v) { + return $v !== null; + }); + } + + // Add children if any + if ($includeChildren) { + $payload['children'] = array_values($leaf); + } + + $response[] = $payload; + } + } else { + $msg = 'PLUGIN_ADMIN.PAGE_ROUTE_NOT_FOUND'; + } + + if ($field) { + $temp_array = []; + foreach ($response as $index => $item) { + $temp_array[$item['type']][$index] = $item; + } + + $sorted = Utils::sortArrayByArray($temp_array, $filter_type); + $response = Utils::arrayFlatten($sorted); + } + + return [$status, $msg, $response, $path]; + } + + /** + * @param PageObject $object + * @param UserInterface $user + * @return array + */ + protected function getListingActions(PageObject $object, UserInterface $user): array + { + $actions = []; + if ($object->isAuthorized('read', null, $user)) { + $actions[] = 'preview'; + $actions[] = 'edit'; + } + if ($object->isAuthorized('update', null, $user)) { + $actions[] = 'copy'; + $actions[] = 'move'; + } + if ($object->isAuthorized('delete', null, $user)) { + $actions[] = 'delete'; + } + + return $actions; + } + + /** + * @param FlexStorageInterface $storage + * @return CompiledJsonFile|CompiledYamlFile|null + */ + protected static function getIndexFile(FlexStorageInterface $storage) + { + if (!method_exists($storage, 'isIndexed') || !$storage->isIndexed()) { + return null; + } + + // Load saved index file. + $grav = Grav::instance(); + $locator = $grav['locator']; + + $filename = $locator->findResource('user-data://flex/indexes/pages.json', true, true); + + return CompiledJsonFile::instance($filename); + } + + /** + * @param int|null $timestamp + * @return string|null + */ + private function jsDate(int $timestamp = null): ?string + { + if (!$timestamp) { + return null; + } + + $config = Grav::instance()['config']; + $dateFormat = $config->get('system.pages.dateformat.long'); + + return date($dateFormat, $timestamp) ?: null; + } + + /** + * Add a single page to a collection + * + * @param PageInterface $page + * @return PageCollection + * @phpstan-return C + */ + public function addPage(PageInterface $page) + { + return $this->getCollection()->addPage($page); + } + + /** + * + * Create a copy of this collection + * + * @return static + * @phpstan-return static + */ + public function copy() + { + return clone $this; + } + + /** + * + * Merge another collection with the current collection + * + * @param PageCollectionInterface $collection + * @return PageCollection + * @phpstan-return C + */ + public function merge(PageCollectionInterface $collection) + { + return $this->getCollection()->merge($collection); + } + + + /** + * Intersect another collection with the current collection + * + * @param PageCollectionInterface $collection + * @return PageCollection + * @phpstan-return C + */ + public function intersect(PageCollectionInterface $collection) + { + return $this->getCollection()->intersect($collection); + } + + /** + * Split collection into array of smaller collections. + * + * @param int $size + * @return PageCollection[] + * @phpstan-return C[] + */ + public function batch($size) + { + return $this->getCollection()->batch($size); + } + + /** + * Remove item from the list. + * + * @param string $key + * @return PageObject|null + * @phpstan-return T|null + * @throws InvalidArgumentException + */ + public function remove($key) + { + return $this->getCollection()->remove($key); + } + + /** + * Reorder collection. + * + * @param string $by + * @param string $dir + * @param array $manual + * @param string $sort_flags + * @return static + * @phpstan-return static + */ + public function order($by, $dir = 'asc', $manual = null, $sort_flags = null) + { + /** @var PageCollectionInterface $collection */ + $collection = $this->__call('order', [$by, $dir, $manual, $sort_flags]); + + return $collection; + } + + /** + * Check to see if this item is the first in the collection. + * + * @param string $path + * @return bool True if item is first. + */ + public function isFirst($path): bool + { + /** @var bool $result */ + $result = $this->__call('isFirst', [$path]); + + return $result; + + } + + /** + * Check to see if this item is the last in the collection. + * + * @param string $path + * @return bool True if item is last. + */ + public function isLast($path): bool + { + /** @var bool $result */ + $result = $this->__call('isLast', [$path]); + + return $result; + } + + /** + * Gets the previous sibling based on current position. + * + * @param string $path + * @return PageObject|null The previous item. + * @phpstan-return T|null + */ + public function prevSibling($path) + { + /** @var PageObject|null $result */ + $result = $this->__call('prevSibling', [$path]); + + return $result; + } + + /** + * Gets the next sibling based on current position. + * + * @param string $path + * @return PageObject|null The next item. + * @phpstan-return T|null + */ + public function nextSibling($path) + { + /** @var PageObject|null $result */ + $result = $this->__call('nextSibling', [$path]); + + return $result; + } + + /** + * Returns the adjacent sibling based on a direction. + * + * @param string $path + * @param int $direction either -1 or +1 + * @return PageObject|false The sibling item. + * @phpstan-return T|false + */ + public function adjacentSibling($path, $direction = 1) + { + /** @var PageObject|false $result */ + $result = $this->__call('adjacentSibling', [$path, $direction]); + + return $result; + } + + /** + * Returns the item in the current position. + * + * @param string $path the path the item + * @return int|null The index of the current page, null if not found. + */ + public function currentPosition($path): ?int + { + /** @var int|null $result */ + $result = $this->__call('currentPosition', [$path]); + + return $result; + } + + /** + * Returns the items between a set of date ranges of either the page date field (default) or + * an arbitrary datetime page field where start date and end date are optional + * Dates must be passed in as text that strtotime() can process + * http://php.net/manual/en/function.strtotime.php + * + * @param string|null $startDate + * @param string|null $endDate + * @param string|null $field + * @return static + * @phpstan-return static + * @throws Exception + */ + public function dateRange($startDate = null, $endDate = null, $field = null) + { + $collection = $this->__call('dateRange', [$startDate, $endDate, $field]); + + return $collection; + } + + /** + * Mimicks Pages class. + * + * @return $this + * @deprecated 1.7 Not needed anymore in Flex Pages (does nothing). + */ + public function all() + { + return $this; + } + + /** + * Creates new collection with only visible pages + * + * @return static The collection with only visible pages + * @phpstan-return static + */ + public function visible() + { + $collection = $this->__call('visible', []); + + return $collection; + } + + /** + * Creates new collection with only non-visible pages + * + * @return static The collection with only non-visible pages + * @phpstan-return static + */ + public function nonVisible() + { + $collection = $this->__call('nonVisible', []); + + return $collection; + } + + /** + * Creates new collection with only non-modular pages + * + * @return static The collection with only non-modular pages + * @phpstan-return static + */ + public function pages() + { + $collection = $this->__call('pages', []); + + return $collection; + } + + /** + * Creates new collection with only modular pages + * + * @return static The collection with only modular pages + * @phpstan-return static + */ + public function modules() + { + $collection = $this->__call('modules', []); + + return $collection; + } + + /** + * Creates new collection with only modular pages + * + * @return static The collection with only modular pages + * @phpstan-return static + */ + public function modular() + { + return $this->modules(); + } + + /** + * Creates new collection with only non-modular pages + * + * @return static The collection with only non-modular pages + * @phpstan-return static + */ + public function nonModular() + { + return $this->pages(); + } + + /** + * Creates new collection with only published pages + * + * @return static The collection with only published pages + * @phpstan-return static + */ + public function published() + { + $collection = $this->__call('published', []); + + return $collection; + } + + /** + * Creates new collection with only non-published pages + * + * @return static The collection with only non-published pages + * @phpstan-return static + */ + public function nonPublished() + { + $collection = $this->__call('nonPublished', []); + + return $collection; + } + + /** + * Creates new collection with only routable pages + * + * @return static The collection with only routable pages + * @phpstan-return static + */ + public function routable() + { + $collection = $this->__call('routable', []); + + return $collection; + } + + /** + * Creates new collection with only non-routable pages + * + * @return static The collection with only non-routable pages + * @phpstan-return static + */ + public function nonRoutable() + { + $collection = $this->__call('nonRoutable', []); + + return $collection; + } + + /** + * Creates new collection with only pages of the specified type + * + * @param string $type + * @return static The collection + * @phpstan-return static + */ + public function ofType($type) + { + $collection = $this->__call('ofType', [$type]); + + return $collection; + } + + /** + * Creates new collection with only pages of one of the specified types + * + * @param string[] $types + * @return static The collection + * @phpstan-return static + */ + public function ofOneOfTheseTypes($types) + { + $collection = $this->__call('ofOneOfTheseTypes', [$types]); + + return $collection; + } + + /** + * Creates new collection with only pages of one of the specified access levels + * + * @param array $accessLevels + * @return static The collection + * @phpstan-return static + */ + public function ofOneOfTheseAccessLevels($accessLevels) + { + $collection = $this->__call('ofOneOfTheseAccessLevels', [$accessLevels]); + + return $collection; + } + + /** + * Converts collection into an array. + * + * @return array + */ + public function toArray() + { + return $this->getCollection()->toArray(); + } + + /** + * Get the extended version of this Collection with each page keyed by route + * + * @return array + * @throws Exception + */ + public function toExtendedArray() + { + return $this->getCollection()->toExtendedArray(); + } + +} diff --git a/system/src/Grav/Common/Flex/Types/Pages/PageObject.php b/system/src/Grav/Common/Flex/Types/Pages/PageObject.php new file mode 100644 index 0000000..9f71df7 --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/Pages/PageObject.php @@ -0,0 +1,744 @@ + true, + 'full_order' => true, + 'filterBy' => true, + 'translated' => false, + ] + parent::getCachedMethods(); + } + + /** + * @return void + */ + public function initialize(): void + { + if (!$this->_initialized) { + Grav::instance()->fireEvent('onPageProcessed', new Event(['page' => $this])); + $this->_initialized = true; + } + } + + /** + * @param string|array $query + * @return Route|null + */ + public function getRoute($query = []): ?Route + { + $path = $this->route(); + if (null === $path) { + return null; + } + + $route = RouteFactory::createFromString($path); + if ($lang = $route->getLanguage()) { + $grav = Grav::instance(); + if (!$grav['config']->get('system.languages.include_default_lang')) { + /** @var Language $language */ + $language = $grav['language']; + if ($lang === $language->getDefault()) { + $route = $route->withLanguage(''); + } + } + } + if (is_array($query)) { + foreach ($query as $key => $value) { + $route = $route->withQueryParam($key, $value); + } + } else { + $route = $route->withAddedPath($query); + } + + return $route; + } + + /** + * @inheritdoc PageInterface + */ + public function getFormValue(string $name, $default = null, string $separator = null) + { + $test = new stdClass(); + + $value = $this->pageContentValue($name, $test); + if ($value !== $test) { + return $value; + } + + switch ($name) { + case 'name': + // TODO: this should not be template! + return $this->getProperty('template'); + case 'route': + $filesystem = Filesystem::getInstance(false); + $key = $filesystem->dirname($this->hasKey() ? '/' . $this->getKey() : '/'); + return $key !== '/' ? $key : null; + case 'full_route': + return $this->hasKey() ? '/' . $this->getKey() : ''; + case 'full_order': + return $this->full_order(); + case 'lang': + return $this->getLanguage() ?? ''; + case 'translations': + return $this->getLanguages(); + } + + return parent::getFormValue($name, $default, $separator); + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::getCacheKey() + */ + public function getCacheKey(): string + { + $cacheKey = parent::getCacheKey(); + if ($cacheKey) { + /** @var Language $language */ + $language = Grav::instance()['language']; + $cacheKey .= '_' . $language->getActive(); + } + + return $cacheKey; + } + + /** + * @param array $variables + * @return array + */ + protected function onBeforeSave(array $variables) + { + $reorder = $variables[0] ?? true; + + $meta = $this->getMetaData(); + if (($meta['copy'] ?? false) === true) { + $this->folder = $this->getKey(); + } + + // Figure out storage path to the new route. + $parentKey = $this->getProperty('parent_key'); + if ($parentKey !== '') { + $parentRoute = $this->getProperty('route'); + + // Root page cannot be moved. + if ($this->root()) { + throw new RuntimeException(sprintf('Root page cannot be moved to %s', $parentRoute)); + } + + // Make sure page isn't being moved under itself. + $key = $this->getStorageKey(); + + /** @var PageObject|null $parent */ + $parent = $parentKey !== false ? $this->getFlexDirectory()->getObject($parentKey, 'storage_key') : null; + if (!$parent) { + // Page cannot be moved to non-existing location. + throw new RuntimeException(sprintf('Page /%s cannot be moved to non-existing path %s', $key, $parentRoute)); + } + + // TODO: make sure that the page doesn't exist yet if moved/copied. + } + + if ($reorder === true && !$this->root()) { + $reorder = $this->_reorder; + } + + // Force automatic reorder if item is supposed to be added to the last. + if (!is_array($reorder) && (int)$this->order() >= 999999) { + $reorder = []; + } + + // Reorder siblings. + $siblings = is_array($reorder) ? ($this->reorderSiblings($reorder) ?? []) : []; + + $data = $this->prepareStorage(); + unset($data['header']); + + foreach ($siblings as $sibling) { + $data = $sibling->prepareStorage(); + unset($data['header']); + } + + return ['reorder' => $reorder, 'siblings' => $siblings]; + } + + /** + * @param array $variables + * @return array + */ + protected function onSave(array $variables): array + { + /** @var PageCollection $siblings */ + $siblings = $variables['siblings']; + /** @var PageObject $sibling */ + foreach ($siblings as $sibling) { + $sibling->save(false); + } + + return $variables; + } + + /** + * @param array $variables + */ + protected function onAfterSave(array $variables): void + { + $this->getFlexDirectory()->reloadIndex(); + } + + /** + * @param UserInterface|null $user + */ + public function check(UserInterface $user = null): void + { + parent::check($user); + + if ($user && $this->isMoved()) { + $parentKey = $this->getProperty('parent_key'); + + /** @var PageObject|null $parent */ + $parent = $this->getFlexDirectory()->getObject($parentKey, 'storage_key'); + if (!$parent || !$parent->isAuthorized('create', null, $user)) { + throw new \RuntimeException('Forbidden', 403); + } + } + } + + /** + * @param array|bool $reorder + * @return static + */ + public function save($reorder = true) + { + $variables = $this->onBeforeSave(func_get_args()); + + // Backwards compatibility with older plugins. + $fireEvents = $reorder && $this->isAdminSite() && $this->getFlexDirectory()->getConfig('object.compat.events', true); + $grav = $this->getContainer(); + if ($fireEvents) { + $self = $this; + $grav->fireEvent('onAdminSave', new Event(['type' => 'flex', 'directory' => $this->getFlexDirectory(), 'object' => &$self])); + if ($self !== $this) { + throw new RuntimeException('Switching Flex Page object during onAdminSave event is not supported! Please update plugin.'); + } + } + + /** @var static $instance */ + $instance = parent::save(); + $variables = $this->onSave($variables); + + $this->onAfterSave($variables); + + // Backwards compatibility with older plugins. + if ($fireEvents) { + $grav->fireEvent('onAdminAfterSave', new Event(['type' => 'flex', 'directory' => $this->getFlexDirectory(), 'object' => $this])); + } + + // Reset original after save events have all been called. + $this->_originalObject = null; + + return $instance; + } + + /** + * @return static + */ + public function delete() + { + $result = parent::delete(); + + // Backwards compatibility with older plugins. + $fireEvents = $this->isAdminSite() && $this->getFlexDirectory()->getConfig('object.compat.events', true); + if ($fireEvents) { + $this->getContainer()->fireEvent('onAdminAfterDelete', new Event(['object' => $this])); + } + + return $result; + } + + /** + * Prepare move page to new location. Moves also everything that's under the current page. + * + * You need to call $this->save() in order to perform the move. + * + * @param PageInterface $parent New parent page. + * @return $this + */ + public function move(PageInterface $parent) + { + if (!$parent instanceof FlexObjectInterface) { + throw new RuntimeException('Failed: Parent is not Flex Object'); + } + + $this->_reorder = []; + $this->setProperty('parent_key', $parent->getStorageKey()); + $this->storeOriginal(); + + return $this; + } + + /** + * @param UserInterface $user + * @param string $action + * @param string $scope + * @param bool $isMe + * @return bool|null + */ + protected function isAuthorizedOverride(UserInterface $user, string $action, string $scope, bool $isMe): ?bool + { + // Special case: creating a new page means checking parent for its permissions. + if ($action === 'create' && !$this->exists()) { + $parent = $this->parent(); + if ($parent && method_exists($parent, 'isAuthorized')) { + return $parent->isAuthorized($action, $scope, $user); + } + + return false; + } + + return parent::isAuthorizedOverride($user, $action, $scope, $isMe); + } + + /** + * @return bool + */ + protected function isMoved(): bool + { + $storageKey = $this->getMasterKey(); + $filesystem = Filesystem::getInstance(false); + $oldParentKey = ltrim($filesystem->dirname("/{$storageKey}"), '/'); + $newParentKey = $this->getProperty('parent_key'); + + return $this->exists() && $oldParentKey !== $newParentKey; + } + + /** + * @param array $ordering + * @return PageCollection|null + * @phpstan-return ObjectCollection|null + */ + protected function reorderSiblings(array $ordering) + { + $storageKey = $this->getMasterKey(); + $isMoved = $this->isMoved(); + $order = !$isMoved ? $this->order() : false; + if ($order !== false) { + $order = (int)$order; + } + + $parent = $this->parent(); + if (!$parent) { + throw new RuntimeException('Cannot reorder a page which has no parent'); + } + + /** @var PageCollection $siblings */ + $siblings = $parent->children(); + $siblings = $siblings->getCollection()->withOrdered(); + + // Handle special case where ordering isn't given. + if ($ordering === []) { + if ($order >= 999999) { + // Set ordering to point to be the last item, ignoring the object itself. + $order = 0; + foreach ($siblings as $sibling) { + if ($sibling->getKey() !== $this->getKey()) { + $order = max($order, (int)$sibling->order()); + } + } + $this->order($order + 1); + } + + // Do not change sibling ordering. + return null; + } + + $siblings = $siblings->orderBy(['order' => 'ASC']); + + if ($storageKey !== null) { + if ($order !== false) { + // Add current page back to the list if it's ordered. + $siblings->set($storageKey, $this); + } else { + // Remove old copy of the current page from the siblings list. + $siblings->remove($storageKey); + } + } + + // Add missing siblings into the end of the list, keeping the previous ordering between them. + foreach ($siblings as $sibling) { + $folder = (string)$sibling->getProperty('folder'); + $basename = preg_replace('|^\d+\.|', '', $folder); + if (!in_array($basename, $ordering, true)) { + $ordering[] = $basename; + } + } + + // Reorder. + $ordering = array_flip(array_values($ordering)); + $count = count($ordering); + foreach ($siblings as $sibling) { + $folder = (string)$sibling->getProperty('folder'); + $basename = preg_replace('|^\d+\.|', '', $folder); + $newOrder = $ordering[$basename] ?? null; + $newOrder = null !== $newOrder ? $newOrder + 1 : (int)$sibling->order() + $count; + $sibling->order($newOrder); + } + + $siblings = $siblings->orderBy(['order' => 'ASC']); + $siblings->removeElement($this); + + // If menu item was moved, just make it to be the last in order. + if ($isMoved && $this->order() !== false) { + $parentKey = $this->getProperty('parent_key'); + if ($parentKey === '') { + /** @var PageIndex $index */ + $index = $this->getFlexDirectory()->getIndex(); + $newParent = $index->getRoot(); + } else { + $newParent = $this->getFlexDirectory()->getObject($parentKey, 'storage_key'); + if (!$newParent instanceof PageInterface) { + throw new RuntimeException("New parent page '{$parentKey}' not found."); + } + } + /** @var PageCollection $newSiblings */ + $newSiblings = $newParent->children(); + $newSiblings = $newSiblings->getCollection()->withOrdered(); + $order = 0; + foreach ($newSiblings as $sibling) { + $order = max($order, (int)$sibling->order()); + } + $this->order($order + 1); + } + + return $siblings; + } + + /** + * @return string + */ + public function full_order(): string + { + $route = $this->path() . '/' . $this->folder(); + + return preg_replace(PageIndex::ORDER_LIST_REGEX, '\\1', $route) ?? $route; + } + + /** + * @param string $name + * @return Blueprint + */ + protected function doGetBlueprint(string $name = ''): Blueprint + { + try { + // Make sure that pages has been initialized. + Pages::getTypes(); + + // TODO: We need to move raw blueprint logic to Grav itself to remove admin dependency here. + if ($name === 'raw') { + // Admin RAW mode. + if ($this->isAdminSite()) { + /** @var Admin $admin */ + $admin = Grav::instance()['admin']; + + $template = $this->isModule() ? 'modular_raw' : ($this->root() ? 'root_raw' : 'raw'); + + return $admin->blueprints("admin/pages/{$template}"); + } + } + + $template = $this->getProperty('template') . ($name ? '.' . $name : ''); + + $blueprint = $this->getFlexDirectory()->getBlueprint($template, 'blueprints://pages'); + } catch (RuntimeException $e) { + $template = 'default' . ($name ? '.' . $name : ''); + + $blueprint = $this->getFlexDirectory()->getBlueprint($template, 'blueprints://pages'); + } + + $isNew = $blueprint->get('initialized', false) === false; + if ($isNew === true && $name === '') { + // Support onBlueprintCreated event just like in Pages::blueprints($template) + $blueprint->set('initialized', true); + $blueprint->setFilename($template); + + Grav::instance()->fireEvent('onBlueprintCreated', new Event(['blueprint' => $blueprint, 'type' => $template])); + } + + return $blueprint; + } + + /** + * @param array $options + * @return array + */ + public function getLevelListing(array $options): array + { + $index = $this->getFlexDirectory()->getIndex(); + if (!is_callable([$index, 'getLevelListing'])) { + return []; + } + + // Deal with relative paths. + $initial = $options['initial'] ?? null; + $var = $initial ? 'leaf_route' : 'route'; + $route = $options[$var] ?? ''; + if ($route !== '' && !str_starts_with($route, '/')) { + $filesystem = Filesystem::getInstance(); + + $route = "/{$this->getKey()}/{$route}"; + $route = $filesystem->normalize($route); + + $options[$var] = $route; + } + + [$status, $message, $response,] = $index->getLevelListing($options); + + return [$status, $message, $response, $options[$var] ?? null]; + } + + /** + * Filter page (true/false) by given filters. + * + * - search: string + * - extension: string + * - module: bool + * - visible: bool + * - routable: bool + * - published: bool + * - page: bool + * - translated: bool + * + * @param array $filters + * @param bool $recursive + * @return bool + */ + public function filterBy(array $filters, bool $recursive = false): bool + { + $language = $filters['language'] ?? null; + if (null !== $language) { + /** @var PageObject $test */ + $test = $this->getTranslation($language) ?? $this; + } else { + $test = $this; + } + + foreach ($filters as $key => $value) { + switch ($key) { + case 'search': + $matches = $test->search((string)$value) > 0.0; + break; + case 'page_type': + $types = $value ? explode(',', $value) : []; + $matches = in_array($test->template(), $types, true); + break; + case 'extension': + $matches = Utils::contains((string)$value, $test->extension()); + break; + case 'routable': + $matches = $test->isRoutable() === (bool)$value; + break; + case 'published': + $matches = $test->isPublished() === (bool)$value; + break; + case 'visible': + $matches = $test->isVisible() === (bool)$value; + break; + case 'module': + $matches = $test->isModule() === (bool)$value; + break; + case 'page': + $matches = $test->isPage() === (bool)$value; + break; + case 'folder': + $matches = $test->isPage() === !$value; + break; + case 'translated': + $matches = $test->hasTranslation() === (bool)$value; + break; + default: + $matches = true; + break; + } + + // If current filter does not match, we still may have match as a parent. + if ($matches === false) { + if (!$recursive) { + return false; + } + + /** @var PageIndex $index */ + $index = $this->children()->getIndex(); + + return $index->filterBy($filters, true)->count() > 0; + } + } + + return true; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::exists() + */ + public function exists(): bool + { + return $this->root ?: parent::exists(); + } + + /** + * @return array + */ + public function __debugInfo(): array + { + $list = parent::__debugInfo(); + + return $list + [ + '_content_meta:private' => $this->getContentMeta(), + '_content:private' => $this->getRawContent() + ]; + } + + /** + * @param array $elements + * @param bool $extended + */ + protected function filterElements(array &$elements, bool $extended = false): void + { + // Change parent page if needed. + if (array_key_exists('route', $elements) && isset($elements['folder'], $elements['name'])) { + $elements['template'] = $elements['name']; + + // Figure out storage path to the new route. + $parentKey = trim($elements['route'] ?? '', '/'); + if ($parentKey !== '') { + /** @var PageObject|null $parent */ + $parent = $this->getFlexDirectory()->getObject($parentKey); + $parentKey = $parent ? $parent->getStorageKey() : $parentKey; + } + + $elements['parent_key'] = $parentKey; + } + + // Deal with ordering=bool and order=page1,page2,page3. + if ($this->root()) { + // Root page doesn't have ordering. + unset($elements['ordering'], $elements['order']); + } elseif (array_key_exists('ordering', $elements) && array_key_exists('order', $elements)) { + // Store ordering. + $ordering = $elements['order'] ?? null; + $this->_reorder = !empty($ordering) ? explode(',', $ordering) : []; + + $order = false; + if ((bool)($elements['ordering'] ?? false)) { + $order = $this->order(); + if ($order === false) { + $order = 999999; + } + } + + $elements['order'] = $order; + } + + parent::filterElements($elements, true); + } + + /** + * @return array + */ + public function prepareStorage(): array + { + $meta = $this->getMetaData(); + $oldLang = $meta['lang'] ?? ''; + $newLang = $this->getProperty('lang') ?? ''; + + // Always clone the page to the new language. + if ($oldLang !== $newLang) { + $meta['clone'] = true; + } + + // Make sure that certain elements are always sent to the storage layer. + $elements = [ + '__META' => $meta, + 'storage_key' => $this->getStorageKey(), + 'parent_key' => $this->getProperty('parent_key'), + 'order' => $this->getProperty('order'), + 'folder' => preg_replace('|^\d+\.|', '', $this->getProperty('folder') ?? ''), + 'template' => preg_replace('|modular/|', '', $this->getProperty('template') ?? ''), + 'lang' => $newLang + ] + parent::prepareStorage(); + + return $elements; + } +} diff --git a/system/src/Grav/Common/Flex/Types/Pages/Storage/PageStorage.php b/system/src/Grav/Common/Flex/Types/Pages/Storage/PageStorage.php new file mode 100644 index 0000000..577a0d7 --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/Pages/Storage/PageStorage.php @@ -0,0 +1,700 @@ +flags = FilesystemIterator::KEY_AS_FILENAME | FilesystemIterator::CURRENT_AS_FILEINFO + | FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS; + + $grav = Grav::instance(); + + $config = $grav['config']; + $this->ignore_hidden = (bool)$config->get('system.pages.ignore_hidden'); + $this->ignore_files = (array)$config->get('system.pages.ignore_files'); + $this->ignore_folders = (array)$config->get('system.pages.ignore_folders'); + $this->include_default_lang_file_extension = (bool)$config->get('system.languages.include_default_lang_file_extension', true); + $this->recurse = (bool)($options['recurse'] ?? true); + $this->regex = '/(\.([\w\d_-]+))?\.md$/D'; + } + + /** + * @param string $key + * @param bool $variations + * @return array + */ + public function parseKey(string $key, bool $variations = true): array + { + if (mb_strpos($key, '|') !== false) { + [$key, $params] = explode('|', $key, 2); + } else { + $params = ''; + } + $key = ltrim($key, '/'); + + $keys = parent::parseKey($key, false) + ['params' => $params]; + + if ($variations) { + $keys += $this->parseParams($key, $params); + } + + return $keys; + } + + /** + * @param string $key + * @return string + */ + public function readFrontmatter(string $key): string + { + $path = $this->getPathFromKey($key); + $file = $this->getFile($path); + try { + if ($file instanceof MarkdownFile) { + $frontmatter = $file->frontmatter(); + } else { + $frontmatter = $file->raw(); + } + } catch (RuntimeException $e) { + $frontmatter = 'ERROR: ' . $e->getMessage(); + } finally { + $file->free(); + unset($file); + } + + return $frontmatter; + } + + /** + * @param string $key + * @return string + */ + public function readRaw(string $key): string + { + $path = $this->getPathFromKey($key); + $file = $this->getFile($path); + try { + $raw = $file->raw(); + } catch (RuntimeException $e) { + $raw = 'ERROR: ' . $e->getMessage(); + } finally { + $file->free(); + unset($file); + } + + return $raw; + } + + /** + * @param array $keys + * @param bool $includeParams + * @return string + */ + public function buildStorageKey(array $keys, bool $includeParams = true): string + { + $key = $keys['key'] ?? null; + if (null === $key) { + $key = $keys['parent_key'] ?? ''; + if ($key !== '') { + $key .= '/'; + } + $order = $keys['order'] ?? null; + $folder = $keys['folder'] ?? 'undefined'; + $key .= is_numeric($order) ? sprintf('%02d.%s', $order, $folder) : $folder; + } + + $params = $includeParams ? $this->buildStorageKeyParams($keys) : ''; + + return $params ? "{$key}|{$params}" : $key; + } + + /** + * @param array $keys + * @return string + */ + public function buildStorageKeyParams(array $keys): string + { + $params = $keys['template'] ?? ''; + $language = $keys['lang'] ?? ''; + if ($language) { + $params .= '.' . $language; + } + + return $params; + } + + /** + * @param array $keys + * @return string + */ + public function buildFolder(array $keys): string + { + return $this->dataFolder . '/' . $this->buildStorageKey($keys, false); + } + + /** + * @param array $keys + * @return string + */ + public function buildFilename(array $keys): string + { + $file = $this->buildStorageKeyParams($keys); + + // Template is optional; if it is missing, we need to have to load the object metadata. + if ($file && $file[0] === '.') { + $meta = $this->getObjectMeta($this->buildStorageKey($keys, false)); + $file = ($meta['template'] ?? 'folder') . $file; + } + + return $file . $this->dataExt; + } + + /** + * @param array $keys + * @return string + */ + public function buildFilepath(array $keys): string + { + $folder = $this->buildFolder($keys); + $filename = $this->buildFilename($keys); + + return rtrim($folder, '/') !== $folder ? $folder . $filename : $folder . '/' . $filename; + } + + /** + * @param array $row + * @param bool $setDefaultLang + * @return array + */ + public function extractKeysFromRow(array $row, bool $setDefaultLang = true): array + { + $meta = $row['__META'] ?? null; + $storageKey = $row['storage_key'] ?? $meta['storage_key'] ?? ''; + $keyMeta = $storageKey !== '' ? $this->extractKeysFromStorageKey($storageKey) : null; + $parentKey = $row['parent_key'] ?? $meta['parent_key'] ?? $keyMeta['parent_key'] ?? ''; + $order = $row['order'] ?? $meta['order'] ?? $keyMeta['order'] ?? null; + $folder = $row['folder'] ?? $meta['folder'] ?? $keyMeta['folder'] ?? ''; + $template = $row['template'] ?? $meta['template'] ?? $keyMeta['template'] ?? ''; + $lang = $row['lang'] ?? $meta['lang'] ?? $keyMeta['lang'] ?? ''; + + // Handle default language, if it should be saved without language extension. + if ($setDefaultLang && empty($meta['markdown'][$lang])) { + $grav = Grav::instance(); + + /** @var Language $language */ + $language = $grav['language']; + $default = $language->getDefault(); + // Make sure that the default language file doesn't exist before overriding it. + if (empty($meta['markdown'][$default])) { + if ($this->include_default_lang_file_extension) { + if ($lang === '') { + $lang = $language->getDefault(); + } + } elseif ($lang === $language->getDefault()) { + $lang = ''; + } + } + } + + $keys = [ + 'key' => null, + 'params' => null, + 'parent_key' => $parentKey, + 'order' => is_numeric($order) ? (int)$order : null, + 'folder' => $folder, + 'template' => $template, + 'lang' => $lang + ]; + + $keys['key'] = $this->buildStorageKey($keys, false); + $keys['params'] = $this->buildStorageKeyParams($keys); + + return $keys; + } + + /** + * @param string $key + * @return array + */ + public function extractKeysFromStorageKey(string $key): array + { + if (mb_strpos($key, '|') !== false) { + [$key, $params] = explode('|', $key, 2); + [$template, $language] = mb_strpos($params, '.') !== false ? explode('.', $params, 2) : [$params, '']; + } else { + $params = $template = $language = ''; + } + $objectKey = Utils::basename($key); + if (preg_match('|^(\d+)\.(.+)$|', $objectKey, $matches)) { + [, $order, $folder] = $matches; + } else { + [$order, $folder] = ['', $objectKey]; + } + + $filesystem = Filesystem::getInstance(false); + + $parentKey = ltrim($filesystem->dirname('/' . $key), '/'); + + return [ + 'key' => $key, + 'params' => $params, + 'parent_key' => $parentKey, + 'order' => is_numeric($order) ? (int)$order : null, + 'folder' => $folder, + 'template' => $template, + 'lang' => $language + ]; + } + + /** + * @param string $key + * @param string $params + * @return array + */ + protected function parseParams(string $key, string $params): array + { + if (mb_strpos($params, '.') !== false) { + [$template, $language] = explode('.', $params, 2); + } else { + $template = $params; + $language = ''; + } + + if ($template === '') { + $meta = $this->getObjectMeta($key); + $template = $meta['template'] ?? 'folder'; + } + + return [ + 'file' => $template . ($language ? '.' . $language : ''), + 'template' => $template, + 'lang' => $language + ]; + } + + /** + * Prepares the row for saving and returns the storage key for the record. + * + * @param array $row + */ + protected function prepareRow(array &$row): void + { + // Remove keys used in the filesystem. + unset($row['parent_key'], $row['order'], $row['folder'], $row['template'], $row['lang']); + } + + /** + * @param string $key + * @return array + */ + protected function loadRow(string $key): ?array + { + $data = parent::loadRow($key); + + // Special case for root page. + if ($key === '' && null !== $data) { + $data['root'] = true; + } + + return $data; + } + + /** + * Page storage supports moving and copying the pages and their languages. + * + * $row['__META']['copy'] = true Use this if you want to copy the whole folder, otherwise it will be moved + * $row['__META']['clone'] = true Use this if you want to clone the file, otherwise it will be renamed + * + * @param string $key + * @param array $row + * @return array + */ + protected function saveRow(string $key, array $row): array + { + // Initialize all key-related variables. + $newKeys = $this->extractKeysFromRow($row); + $newKey = $this->buildStorageKey($newKeys); + $newFolder = $this->buildFolder($newKeys); + $newFilename = $this->buildFilename($newKeys); + $newFilepath = rtrim($newFolder, '/') !== $newFolder ? $newFolder . $newFilename : $newFolder . '/' . $newFilename; + + try { + if ($key === '' && empty($row['root'])) { + throw new RuntimeException('Page has no path'); + } + + $grav = Grav::instance(); + + /** @var Debugger $debugger */ + $debugger = $grav['debugger']; + $debugger->addMessage("Save page: {$newKey}", 'debug'); + + // Check if the row already exists. + $oldKey = $row['__META']['storage_key'] ?? null; + if (is_string($oldKey)) { + // Initialize all old key-related variables. + $oldKeys = $this->extractKeysFromRow(['__META' => $row['__META']], false); + $oldFolder = $this->buildFolder($oldKeys); + $oldFilename = $this->buildFilename($oldKeys); + + // Check if folder has changed. + if ($oldFolder !== $newFolder && file_exists($oldFolder)) { + $isCopy = $row['__META']['copy'] ?? false; + if ($isCopy) { + if (strpos($newFolder, $oldFolder . '/') === 0) { + throw new RuntimeException(sprintf('Page /%s cannot be copied to itself', $oldKey)); + } + + $this->copyRow($oldKey, $newKey); + $debugger->addMessage("Page copied: {$oldFolder} => {$newFolder}", 'debug'); + } else { + if (strpos($newFolder, $oldFolder . '/') === 0) { + throw new RuntimeException(sprintf('Page /%s cannot be moved to itself', $oldKey)); + } + + $this->renameRow($oldKey, $newKey); + $debugger->addMessage("Page moved: {$oldFolder} => {$newFolder}", 'debug'); + } + } + + // Check if filename has changed. + if ($oldFilename !== $newFilename) { + // Get instance of the old file (we have already copied/moved it). + $oldFilepath = "{$newFolder}/{$oldFilename}"; + $file = $this->getFile($oldFilepath); + + // Rename the file if we aren't supposed to clone it. + $isClone = $row['__META']['clone'] ?? false; + if (!$isClone && $file->exists()) { + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + $toPath = $locator->isStream($newFilepath) ? $locator->findResource($newFilepath, true, true) : GRAV_ROOT . "/{$newFilepath}"; + $success = $file->rename($toPath); + if (!$success) { + throw new RuntimeException("Changing page template failed: {$oldFilepath} => {$newFilepath}"); + } + $debugger->addMessage("Page template changed: {$oldFilename} => {$newFilename}", 'debug'); + } else { + $file = null; + $debugger->addMessage("Page template created: {$newFilename}", 'debug'); + } + } + } + + // Clean up the data to be saved. + $this->prepareRow($row); + unset($row['__META'], $row['__ERROR']); + + if (!isset($file)) { + $file = $this->getFile($newFilepath); + } + + // Compare existing file content to the new one and save the file only if content has been changed. + $file->free(); + $oldRaw = $file->raw(); + $file->content($row); + $newRaw = $file->raw(); + if ($oldRaw !== $newRaw) { + $file->save($row); + $debugger->addMessage("Page content saved: {$newFilepath}", 'debug'); + } else { + $debugger->addMessage('Page content has not been changed, do not update the file', 'debug'); + } + } catch (RuntimeException $e) { + $name = isset($file) ? $file->filename() : $newKey; + + throw new RuntimeException(sprintf('Flex saveRow(%s): %s', $name, $e->getMessage())); + } finally { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $locator->clearCache(); + + if (isset($file)) { + $file->free(); + unset($file); + } + } + + $row['__META'] = $this->getObjectMeta($newKey, true); + + return $row; + } + + /** + * Check if page folder should be deleted. + * + * Deleting page can be done either by deleting everything or just a single language. + * If key contains the language, delete only it, unless it is the last language. + * + * @param string $key + * @return bool + */ + protected function canDeleteFolder(string $key): bool + { + // Return true if there's no language in the key. + $keys = $this->extractKeysFromStorageKey($key); + if (!$keys['lang']) { + return true; + } + + // Get the main key and reload meta. + $key = $this->buildStorageKey($keys); + $meta = $this->getObjectMeta($key, true); + + // Return true if there aren't any markdown files left. + return empty($meta['markdown'] ?? []); + } + + /** + * Get key from the filesystem path. + * + * @param string $path + * @return string + */ + protected function getKeyFromPath(string $path): string + { + if ($this->base_path) { + $path = $this->base_path . '/' . $path; + } + + return $path; + } + + /** + * Returns list of all stored keys in [key => timestamp] pairs. + * + * @return array + */ + protected function buildIndex(): array + { + $this->clearCache(); + + return $this->getIndexMeta(); + } + + /** + * @param string $key + * @param bool $reload + * @return array + */ + protected function getObjectMeta(string $key, bool $reload = false): array + { + $keys = $this->extractKeysFromStorageKey($key); + $key = $keys['key']; + + if ($reload || !isset($this->meta[$key])) { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + if (mb_strpos($key, '@@') === false) { + $path = $this->getStoragePath($key); + if (is_string($path)) { + $path = $locator->isStream($path) ? $locator->findResource($path) : GRAV_ROOT . "/{$path}"; + } else { + $path = null; + } + } else { + $path = null; + } + + $modified = 0; + $markdown = []; + $children = []; + + if (is_string($path) && is_dir($path)) { + $modified = filemtime($path); + $iterator = new FilesystemIterator($path, $this->flags); + + /** @var SplFileInfo $info */ + foreach ($iterator as $k => $info) { + // Ignore all hidden files if set. + if ($k === '' || ($this->ignore_hidden && $k[0] === '.')) { + continue; + } + + if ($info->isDir()) { + // Ignore all folders in ignore list. + if ($this->ignore_folders && in_array($k, $this->ignore_folders, true)) { + continue; + } + + $children[$k] = false; + } else { + // Ignore all files in ignore list. + if ($this->ignore_files && in_array($k, $this->ignore_files, true)) { + continue; + } + + $timestamp = $info->getMTime(); + + // Page is the one that matches to $page_extensions list with the lowest index number. + if (preg_match($this->regex, $k, $matches)) { + $mark = $matches[2] ?? ''; + $ext = $matches[1] ?? ''; + $ext .= $this->dataExt; + $markdown[$mark][Utils::basename($k, $ext)] = $timestamp; + } + + $modified = max($modified, $timestamp); + } + } + } + + $rawRoute = trim(preg_replace(PageIndex::PAGE_ROUTE_REGEX, '/', "/{$key}") ?? '', '/'); + $route = PageIndex::normalizeRoute($rawRoute); + + ksort($markdown, SORT_NATURAL | SORT_FLAG_CASE); + ksort($children, SORT_NATURAL | SORT_FLAG_CASE); + + $file = array_key_first($markdown[''] ?? (reset($markdown) ?: [])); + + $meta = [ + 'key' => $route, + 'storage_key' => $key, + 'template' => $file, + 'storage_timestamp' => $modified, + ]; + if ($markdown) { + $meta['markdown'] = $markdown; + } + if ($children) { + $meta['children'] = $children; + } + $meta['checksum'] = md5(json_encode($meta) ?: ''); + + // Cache meta as copy. + $this->meta[$key] = $meta; + } else { + $meta = $this->meta[$key]; + } + + $params = $keys['params']; + if ($params) { + $language = $keys['lang']; + $template = $keys['template'] ?: array_key_first($meta['markdown'][$language]) ?? $meta['template']; + $meta['exists'] = ($template && !empty($meta['children'])) || isset($meta['markdown'][$language][$template]); + $meta['storage_key'] .= '|' . $params; + $meta['template'] = $template; + $meta['lang'] = $language; + } + + return $meta; + } + + /** + * @return array + */ + protected function getIndexMeta(): array + { + $queue = ['']; + $list = []; + do { + $current = array_pop($queue); + if ($current === null) { + break; + } + + $meta = $this->getObjectMeta($current); + $storage_key = $meta['storage_key']; + + if (!empty($meta['children'])) { + $prefix = $storage_key . ($storage_key !== '' ? '/' : ''); + + foreach ($meta['children'] as $child => $value) { + $queue[] = $prefix . $child; + } + } + + $list[$storage_key] = $meta; + } while ($queue); + + ksort($list, SORT_NATURAL | SORT_FLAG_CASE); + + // Update parent timestamps. + foreach (array_reverse($list) as $storage_key => $meta) { + if ($storage_key !== '') { + $filesystem = Filesystem::getInstance(false); + + $storage_key = (string)$storage_key; + $parentKey = $filesystem->dirname($storage_key); + if ($parentKey === '.') { + $parentKey = ''; + } + + /** @phpstan-var array{'storage_key': string, 'storage_timestamp': int, 'children': array} $parent */ + $parent = &$list[$parentKey]; + $basename = Utils::basename($storage_key); + + if (isset($parent['children'][$basename])) { + $timestamp = $meta['storage_timestamp']; + $parent['children'][$basename] = $timestamp; + if ($basename && $basename[0] === '_') { + $parent['storage_timestamp'] = max($parent['storage_timestamp'], $timestamp); + } + } + } + } + + return $list; + } + + /** + * @return string + */ + protected function getNewKey(): string + { + throw new RuntimeException('Generating random key is disabled for pages'); + } +} diff --git a/system/src/Grav/Common/Flex/Types/Pages/Traits/PageContentTrait.php b/system/src/Grav/Common/Flex/Types/Pages/Traits/PageContentTrait.php new file mode 100644 index 0000000..b6452b0 --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/Pages/Traits/PageContentTrait.php @@ -0,0 +1,75 @@ +getProperty($property) : null; + if (null === $value) { + $value = $this->language() . ($var ?? ($this->modified() . md5($this->filePath() ?? $this->getKey()))); + + $this->setProperty($property, $value); + if ($this->doHasProperty($property)) { + $value = $this->getProperty($property); + } + } + + return $value; + } + + + /** + * @inheritdoc + */ + public function date($var = null): int + { + return $this->loadHeaderProperty( + 'date', + $var, + function ($value) { + $value = $value ? Utils::date2timestamp($value, $this->getProperty('dateformat')) : false; + + if (!$value) { + // Get the specific translation updated date. + $meta = $this->getMetaData(); + $language = $meta['lang'] ?? ''; + $template = $this->getProperty('template'); + $value = $meta['markdown'][$language][$template] ?? 0; + } + + return $value ?: $this->modified(); + } + ); + } + + /** + * @inheritdoc + * @param bool $bool + */ + public function isPage(bool $bool = true): bool + { + $meta = $this->getMetaData(); + + return empty($meta['markdown']) !== $bool; + } +} diff --git a/system/src/Grav/Common/Flex/Types/Pages/Traits/PageLegacyTrait.php b/system/src/Grav/Common/Flex/Types/Pages/Traits/PageLegacyTrait.php new file mode 100644 index 0000000..9fdd718 --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/Pages/Traits/PageLegacyTrait.php @@ -0,0 +1,236 @@ +path() ?? ''; + + return $pages->children($path); + } + + /** + * Check to see if this item is the first in an array of sub-pages. + * + * @return bool True if item is first. + */ + public function isFirst(): bool + { + if (Utils::isAdminPlugin()) { + return parent::isFirst(); + } + + $path = $this->path(); + $parent = $this->parent(); + $collection = $parent ? $parent->collection('content', false) : null; + if (null !== $path && $collection instanceof PageCollectionInterface) { + return $collection->isFirst($path); + } + + return true; + } + + /** + * Check to see if this item is the last in an array of sub-pages. + * + * @return bool True if item is last + */ + public function isLast(): bool + { + if (Utils::isAdminPlugin()) { + return parent::isLast(); + } + + $path = $this->path(); + $parent = $this->parent(); + $collection = $parent ? $parent->collection('content', false) : null; + if (null !== $path && $collection instanceof PageCollectionInterface) { + return $collection->isLast($path); + } + + return true; + } + + /** + * Returns the adjacent sibling based on a direction. + * + * @param int $direction either -1 or +1 + * @return PageInterface|false the sibling page + */ + public function adjacentSibling($direction = 1) + { + if (Utils::isAdminPlugin()) { + return parent::adjacentSibling($direction); + } + + $path = $this->path(); + $parent = $this->parent(); + $collection = $parent ? $parent->collection('content', false) : null; + if (null !== $path && $collection instanceof PageCollectionInterface) { + $child = $collection->adjacentSibling($path, $direction); + if ($child instanceof PageInterface) { + return $child; + } + } + + return false; + } + + /** + * Helper method to return an ancestor page. + * + * @param string|null $lookup Name of the parent folder + * @return PageInterface|null page you were looking for if it exists + */ + public function ancestor($lookup = null) + { + if (Utils::isAdminPlugin()) { + return parent::ancestor($lookup); + } + + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + return $pages->ancestor($this->getProperty('parent_route'), $lookup); + } + + /** + * Method that contains shared logic for inherited() and inheritedField() + * + * @param string $field Name of the parent folder + * @return array + */ + protected function getInheritedParams($field): array + { + if (Utils::isAdminPlugin()) { + return parent::getInheritedParams($field); + } + + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + $inherited = $pages->inherited($this->getProperty('parent_route'), $field); + $inheritedParams = $inherited ? (array)$inherited->value('header.' . $field) : []; + $currentParams = (array)$this->getFormValue('header.' . $field); + if ($inheritedParams && is_array($inheritedParams)) { + $currentParams = array_replace_recursive($inheritedParams, $currentParams); + } + + return [$inherited, $currentParams]; + } + + /** + * Helper method to return a page. + * + * @param string $url the url of the page + * @param bool $all + * @return PageInterface|null page you were looking for if it exists + */ + public function find($url, $all = false) + { + if (Utils::isAdminPlugin()) { + return parent::find($url, $all); + } + + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + return $pages->find($url, $all); + } + + /** + * Get a collection of pages in the current context. + * + * @param string|array $params + * @param bool $pagination + * @return PageCollectionInterface|Collection + * @throws InvalidArgumentException + */ + public function collection($params = 'content', $pagination = true) + { + if (Utils::isAdminPlugin()) { + return parent::collection($params, $pagination); + } + + if (is_string($params)) { + // Look into a page header field. + $params = (array)$this->getFormValue('header.' . $params); + } elseif (!is_array($params)) { + throw new InvalidArgumentException('Argument should be either header variable name or array of parameters'); + } + + $context = [ + 'pagination' => $pagination, + 'self' => $this + ]; + + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + return $pages->getCollection($params, $context); + } + + /** + * @param string|array $value + * @param bool $only_published + * @return PageCollectionInterface|Collection + */ + public function evaluate($value, $only_published = true) + { + if (Utils::isAdminPlugin()) { + return parent::collection($value, $only_published); + } + + $params = [ + 'items' => $value, + 'published' => $only_published + ]; + $context = [ + 'event' => false, + 'pagination' => false, + 'url_taxonomy_filters' => false, + 'self' => $this + ]; + + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + return $pages->getCollection($params, $context); + } +} diff --git a/system/src/Grav/Common/Flex/Types/Pages/Traits/PageRoutableTrait.php b/system/src/Grav/Common/Flex/Types/Pages/Traits/PageRoutableTrait.php new file mode 100644 index 0000000..2cfe450 --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/Pages/Traits/PageRoutableTrait.php @@ -0,0 +1,122 @@ +root()) { + return null; + } + + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + $filesystem = Filesystem::getInstance(false); + + // FIXME: this does not work, needs to use $pages->get() with cached parent id! + $key = $this->getKey(); + $parent_route = $filesystem->dirname('/' . $key); + + return $parent_route !== '/' ? $pages->find($parent_route) : $pages->root(); + } + + /** + * Returns the item in the current position. + * + * @return int|null the index of the current page. + */ + public function currentPosition(): ?int + { + $path = $this->path(); + $parent = $this->parent(); + $collection = $parent ? $parent->collection('content', false) : null; + if (null !== $path && $collection instanceof PageCollectionInterface) { + return $collection->currentPosition($path); + } + + return 1; + } + + /** + * Returns whether or not this page is the currently active page requested via the URL. + * + * @return bool True if it is active + */ + public function active(): bool + { + $grav = Grav::instance(); + $uri_path = rtrim(urldecode($grav['uri']->path()), '/') ?: '/'; + $routes = $grav['pages']->routes(); + + return isset($routes[$uri_path]) && $routes[$uri_path] === $this->path(); + } + + /** + * Returns whether or not this URI's URL contains the URL of the active page. + * Or in other words, is this page's URL in the current URL + * + * @return bool True if active child exists + */ + public function activeChild(): bool + { + $grav = Grav::instance(); + /** @var Uri $uri */ + $uri = $grav['uri']; + /** @var Pages $pages */ + $pages = $grav['pages']; + $uri_path = rtrim(urldecode($uri->path()), '/'); + $routes = $pages->routes(); + + if (isset($routes[$uri_path])) { + $page = $pages->find($uri->route()); + /** @var PageInterface|null $child_page */ + $child_page = $page ? $page->parent() : null; + while ($child_page && !$child_page->root()) { + if ($this->path() === $child_page->path()) { + return true; + } + $child_page = $child_page->parent(); + } + } + + return false; + } +} diff --git a/system/src/Grav/Common/Flex/Types/Pages/Traits/PageTranslateTrait.php b/system/src/Grav/Common/Flex/Types/Pages/Traits/PageTranslateTrait.php new file mode 100644 index 0000000..d8d86b0 --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/Pages/Traits/PageTranslateTrait.php @@ -0,0 +1,108 @@ +getLanguageTemplates(); + if (!$translated) { + return $translated; + } + + $grav = Grav::instance(); + + /** @var Language $language */ + $language = $grav['language']; + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + + $languages = $language->getLanguages(); + $languages[] = ''; + $defaultCode = $language->getDefault(); + + if (isset($translated[$defaultCode])) { + unset($translated['']); + } + + foreach ($translated as $key => &$template) { + $template .= $key !== '' ? ".{$key}.md" : '.md'; + } + unset($template); + + $translated = array_intersect_key($translated, array_flip($languages)); + + $folder = $this->getStorageFolder(); + if (!$folder) { + return []; + } + $folder = $locator->isStream($folder) ? $locator->getResource($folder) : GRAV_ROOT . "/{$folder}"; + + $list = array_fill_keys($languages, null); + foreach ($translated as $languageCode => $languageFile) { + $languageExtension = $languageCode ? ".{$languageCode}.md" : '.md'; + $path = "{$folder}/{$languageFile}"; + + // FIXME: use flex, also rawRoute() does not fully work? + $aPage = new Page(); + $aPage->init(new SplFileInfo($path), $languageExtension); + if ($onlyPublished && !$aPage->published()) { + continue; + } + + $header = $aPage->header(); + // @phpstan-ignore-next-line + $routes = $header->routes ?? []; + $route = $routes['default'] ?? $aPage->rawRoute(); + if (!$route) { + $route = $aPage->route(); + } + + $list[$languageCode ?: $defaultCode] = $route ?? ''; + } + + $list = array_filter($list, static function ($var) { + return null !== $var; + }); + + // Hack to get the same result as with old pages. + foreach ($list as &$path) { + if ($path === '') { + $path = null; + } + } + + return $list; + } +} diff --git a/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupCollection.php b/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupCollection.php new file mode 100644 index 0000000..daaa942 --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupCollection.php @@ -0,0 +1,56 @@ + + */ +class UserGroupCollection extends FlexCollection +{ + /** + * @return array + */ + public static function getCachedMethods(): array + { + return [ + 'authorize' => false, + ] + parent::getCachedMethods(); + } + + /** + * Checks user authorization to the action. + * + * @param string $action + * @param string|null $scope + * @return bool|null + */ + public function authorize(string $action, string $scope = null): ?bool + { + $authorized = null; + /** @var UserGroupObject $object */ + foreach ($this as $object) { + $auth = $object->authorize($action, $scope); + if ($auth === true) { + $authorized = true; + } elseif ($auth === false) { + return false; + } + } + + return $authorized; + } +} diff --git a/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupIndex.php b/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupIndex.php new file mode 100644 index 0000000..86b9c37 --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupIndex.php @@ -0,0 +1,24 @@ + + */ +class UserGroupIndex extends FlexIndex +{ +} diff --git a/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupObject.php b/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupObject.php new file mode 100644 index 0000000..c8da8a2 --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupObject.php @@ -0,0 +1,134 @@ + false, + ] + parent::getCachedMethods(); + } + + /** + * @return string + */ + public function getTitle(): string + { + return $this->getProperty('readableName'); + } + + /** + * Checks user authorization to the action. + * + * @param string $action + * @param string|null $scope + * @return bool|null + */ + public function authorize(string $action, string $scope = null): ?bool + { + if ($scope === 'test') { + $scope = null; + } elseif (!$this->getProperty('enabled', true)) { + return null; + } + + $access = $this->getAccess(); + + $authorized = $access->authorize($action, $scope); + if (is_bool($authorized)) { + return $authorized; + } + + return $access->authorize('admin.super') ? true : null; + } + + public static function groupNames(): array + { + $groups = []; + $user_groups = Grav::instance()['user_groups'] ?? []; + + foreach ($user_groups as $key => $group) { + $groups[$key] = $group->readableName; + } + + return $groups; + } + + /** + * @return Access + */ + protected function getAccess(): Access + { + if (null === $this->_access) { + $this->getProperty('access'); + } + + return $this->_access; + } + + /** + * @param mixed $value + * @return array + */ + protected function offsetLoad_access($value): array + { + if (!$value instanceof Access) { + $value = new Access($value); + } + + $this->_access = $value; + + return $value->jsonSerialize(); + } + + /** + * @param mixed $value + * @return array + */ + protected function offsetPrepare_access($value): array + { + return $this->offsetLoad_access($value); + } + + /** + * @param array|null $value + * @return array|null + */ + protected function offsetSerialize_access(?array $value): ?array + { + return $value; + } +} diff --git a/system/src/Grav/Common/Flex/Types/Users/Storage/UserFileStorage.php b/system/src/Grav/Common/Flex/Types/Users/Storage/UserFileStorage.php new file mode 100644 index 0000000..01e3f96 --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/Users/Storage/UserFileStorage.php @@ -0,0 +1,47 @@ +update($data)` instead (same but with data validation & filtering, file upload support). + */ + public function merge(array $data) + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use ->update($data) method instead', E_USER_DEPRECATED); + + $this->setElements($this->getBlueprint()->mergeData($this->toArray(), $data)); + + return $this; + } + + /** + * Return media object for the User's avatar. + * + * @return ImageMedium|StaticImageMedium|null + * @deprecated 1.6 Use ->getAvatarImage() method instead. + */ + public function getAvatarMedia() + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use ->getAvatarImage() method instead', E_USER_DEPRECATED); + + return $this->getAvatarImage(); + } + + /** + * Return the User's avatar URL + * + * @return string + * @deprecated 1.6 Use ->getAvatarUrl() method instead. + */ + public function avatarUrl() + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use ->getAvatarUrl() method instead', E_USER_DEPRECATED); + + return $this->getAvatarUrl(); + } + + /** + * Checks user authorization to the action. + * Ensures backwards compatibility + * + * @param string $action + * @return bool + * @deprecated 1.5 Use ->authorize() method instead. + */ + public function authorise($action) + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use ->authorize() method instead', E_USER_DEPRECATED); + + return $this->authorize($action) ?? false; + } + + /** + * Implements Countable interface. + * + * @return int + * @deprecated 1.6 Method makes no sense for user account. + */ + #[\ReturnTypeWillChange] + public function count() + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6', E_USER_DEPRECATED); + + return count($this->jsonSerialize()); + } +} diff --git a/system/src/Grav/Common/Flex/Types/Users/UserCollection.php b/system/src/Grav/Common/Flex/Types/Users/UserCollection.php new file mode 100644 index 0000000..9e86bde --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/Users/UserCollection.php @@ -0,0 +1,135 @@ + + */ +class UserCollection extends FlexCollection implements UserCollectionInterface +{ + /** + * @return array + */ + public static function getCachedMethods(): array + { + return [ + 'authorize' => 'session', + ] + parent::getCachedMethods(); + } + + /** + * Load user account. + * + * Always creates user object. To check if user exists, use $this->exists(). + * + * @param string $username + * @return UserObject + */ + public function load($username): UserInterface + { + $username = (string)$username; + + if ($username !== '') { + $key = $this->filterUsername($username); + $user = $this->get($key); + if ($user) { + return $user; + } + } else { + $key = ''; + } + + $directory = $this->getFlexDirectory(); + + /** @var UserObject $object */ + $object = $directory->createObject( + [ + 'username' => $username, + 'state' => 'enabled' + ], + $key + ); + + return $object; + } + + /** + * Find a user by username, email, etc + * + * @param string $query the query to search for + * @param string|string[] $fields the fields to search + * @return UserObject + */ + public function find($query, $fields = ['username', 'email']): UserInterface + { + if (is_string($query) && $query !== '') { + foreach ((array)$fields as $field) { + if ($field === 'key') { + $user = $this->get($query); + } elseif ($field === 'storage_key') { + $user = $this->withKeyField('storage_key')->get($query); + } elseif ($field === 'flex_key') { + $user = $this->withKeyField('flex_key')->get($query); + } elseif ($field === 'username') { + $user = $this->get($this->filterUsername($query)); + } else { + $user = parent::find($query, $field); + } + if ($user instanceof UserObject) { + return $user; + } + } + } + + return $this->load(''); + } + + /** + * Delete user account. + * + * @param string $username + * @return bool True if user account was found and was deleted. + */ + public function delete($username): bool + { + $user = $this->load($username); + + $exists = $user->exists(); + if ($exists) { + $user->delete(); + } + + return $exists; + } + + /** + * @param string $key + * @return string + */ + protected function filterUsername(string $key): string + { + $storage = $this->getFlexDirectory()->getStorage(); + if (method_exists($storage, 'normalizeKey')) { + return $storage->normalizeKey($key); + } + + return mb_strtolower($key); + } +} diff --git a/system/src/Grav/Common/Flex/Types/Users/UserIndex.php b/system/src/Grav/Common/Flex/Types/Users/UserIndex.php new file mode 100644 index 0000000..d6781af --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/Users/UserIndex.php @@ -0,0 +1,206 @@ + + */ +class UserIndex extends FlexIndex implements UserCollectionInterface +{ + public const VERSION = parent::VERSION . '.2'; + + /** + * @param FlexStorageInterface $storage + * @return array + */ + public static function loadEntriesFromStorage(FlexStorageInterface $storage): array + { + // Load saved index. + $index = static::loadIndex($storage); + + $version = $index['version'] ?? 0; + $force = static::VERSION !== $version; + + // TODO: Following check flex index to be out of sync after some saves, disabled until better solution is found. + //$timestamp = $index['timestamp'] ?? 0; + //if (!$force && $timestamp && $timestamp > time() - 1) { + // return $index['index']; + //} + + // Load up-to-date index. + $entries = parent::loadEntriesFromStorage($storage); + + return static::updateIndexFile($storage, $index['index'], $entries, ['force_update' => $force]); + } + + /** + * @param array $meta + * @param array $data + * @param FlexStorageInterface $storage + * @return void + */ + public static function updateObjectMeta(array &$meta, array $data, FlexStorageInterface $storage): void + { + // Username can also be number and stored as such. + $key = (string)($data['username'] ?? $meta['key'] ?? $meta['storage_key']); + $meta['key'] = static::filterUsername($key, $storage); + $meta['email'] = isset($data['email']) ? mb_strtolower($data['email']) : null; + } + + /** + * Load user account. + * + * Always creates user object. To check if user exists, use $this->exists(). + * + * @param string $username + * @return UserObject + */ + public function load($username): UserInterface + { + $username = (string)$username; + + if ($username !== '') { + $key = static::filterUsername($username, $this->getFlexDirectory()->getStorage()); + $user = $this->get($key); + if ($user) { + return $user; + } + } else { + $key = ''; + } + + $directory = $this->getFlexDirectory(); + + /** @var UserObject $object */ + $object = $directory->createObject( + [ + 'username' => $username, + 'state' => 'enabled' + ], + $key + ); + + return $object; + } + + /** + * Delete user account. + * + * @param string $username + * @return bool True if user account was found and was deleted. + */ + public function delete($username): bool + { + $user = $this->load($username); + + $exists = $user->exists(); + if ($exists) { + $user->delete(); + } + + return $exists; + } + + /** + * Find a user by username, email, etc + * + * @param string $query the query to search for + * @param array $fields the fields to search + * @return UserObject + */ + public function find($query, $fields = ['username', 'email']): UserInterface + { + if (is_string($query) && $query !== '') { + foreach ((array)$fields as $field) { + if ($field === 'key') { + $user = $this->get($query); + } elseif ($field === 'storage_key') { + $user = $this->withKeyField('storage_key')->get($query); + } elseif ($field === 'flex_key') { + $user = $this->withKeyField('flex_key')->get($query); + } elseif ($field === 'email') { + $email = mb_strtolower($query); + $user = $this->withKeyField('email')->get($email); + } elseif ($field === 'username') { + $username = static::filterUsername($query, $this->getFlexDirectory()->getStorage()); + $user = $this->get($username); + } else { + $user = $this->__call('find', [$query, $field]); + } + if ($user) { + return $user; + } + } + } + + return $this->load(''); + } + + /** + * @param string $key + * @param FlexStorageInterface $storage + * @return string + */ + protected static function filterUsername(string $key, FlexStorageInterface $storage): string + { + return method_exists($storage, 'normalizeKey') ? $storage->normalizeKey($key) : $key; + } + + /** + * @param FlexStorageInterface $storage + * @return CompiledYamlFile|null + */ + protected static function getIndexFile(FlexStorageInterface $storage) + { + // Load saved index file. + $grav = Grav::instance(); + $locator = $grav['locator']; + $filename = $locator->findResource('user-data://flex/indexes/accounts.yaml', true, true); + + return CompiledYamlFile::instance($filename); + } + + /** + * @param array $entries + * @param array $added + * @param array $updated + * @param array $removed + */ + protected static function onChanges(array $entries, array $added, array $updated, array $removed): void + { + $message = sprintf('Flex: User index updated, %d objects (%d added, %d updated, %d removed).', count($entries), count($added), count($updated), count($removed)); + + $grav = Grav::instance(); + + /** @var Logger $logger */ + $logger = $grav['log']; + $logger->addDebug($message); + + /** @var Debugger $debugger */ + $debugger = $grav['debugger']; + $debugger->addMessage($message, 'debug'); + } +} diff --git a/system/src/Grav/Common/Flex/Types/Users/UserObject.php b/system/src/Grav/Common/Flex/Types/Users/UserObject.php new file mode 100644 index 0000000..5cdaafd --- /dev/null +++ b/system/src/Grav/Common/Flex/Types/Users/UserObject.php @@ -0,0 +1,1059 @@ + 'session', + 'load' => false, + 'find' => false, + 'remove' => false, + 'get' => true, + 'set' => false, + 'undef' => false, + 'def' => false, + ] + parent::getCachedMethods(); + } + + /** + * UserObject constructor. + * @param array $elements + * @param string $key + * @param FlexDirectory $directory + * @param bool $validate + */ + public function __construct(array $elements, $key, FlexDirectory $directory, bool $validate = false) + { + // User can only be authenticated via login. + unset($elements['authenticated'], $elements['authorized']); + + // Define username if it's not set. + if (!isset($elements['username'])) { + $storageKey = $elements['__META']['storage_key'] ?? null; + $storage = $directory->getStorage(); + if (null !== $storageKey && method_exists($storage, 'normalizeKey') && $key === $storage->normalizeKey($storageKey)) { + $elements['username'] = $storageKey; + } else { + $elements['username'] = $key; + } + } + + // Define state if it isn't set. + if (!isset($elements['state'])) { + $elements['state'] = 'enabled'; + } + + parent::__construct($elements, $key, $directory, $validate); + } + + public function __clone() + { + $this->_access = null; + $this->_groups = null; + + parent::__clone(); + } + + /** + * @return void + */ + public function onPrepareRegistration(): void + { + if (!$this->getProperty('access')) { + /** @var Config $config */ + $config = Grav::instance()['config']; + + $groups = $config->get('plugins.login.user_registration.groups', ''); + $access = $config->get('plugins.login.user_registration.access', ['site' => ['login' => true]]); + + $this->setProperty('groups', $groups); + $this->setProperty('access', $access); + } + } + + /** + * Helper to get content editor will fall back if not set + * + * @return string + */ + public function getContentEditor(): string + { + return $this->getProperty('content_editor', 'default'); + } + + /** + * Get value by using dot notation for nested arrays/objects. + * + * @example $value = $this->get('this.is.my.nested.variable'); + * + * @param string $name Dot separated path to the requested value. + * @param mixed $default Default value (or null). + * @param string|null $separator Separator, defaults to '.' + * @return mixed Value. + */ + public function get($name, $default = null, $separator = null) + { + return $this->getNestedProperty($name, $default, $separator); + } + + /** + * Set value by using dot notation for nested arrays/objects. + * + * @example $data->set('this.is.my.nested.variable', $value); + * + * @param string $name Dot separated path to the requested value. + * @param mixed $value New value. + * @param string|null $separator Separator, defaults to '.' + * @return $this + */ + public function set($name, $value, $separator = null) + { + $this->setNestedProperty($name, $value, $separator); + + return $this; + } + + /** + * Unset value by using dot notation for nested arrays/objects. + * + * @example $data->undef('this.is.my.nested.variable'); + * + * @param string $name Dot separated path to the requested value. + * @param string|null $separator Separator, defaults to '.' + * @return $this + */ + public function undef($name, $separator = null) + { + $this->unsetNestedProperty($name, $separator); + + return $this; + } + + /** + * Set default value by using dot notation for nested arrays/objects. + * + * @example $data->def('this.is.my.nested.variable', 'default'); + * + * @param string $name Dot separated path to the requested value. + * @param mixed $default Default value (or null). + * @param string|null $separator Separator, defaults to '.' + * @return $this + */ + public function def($name, $default = null, $separator = null) + { + $this->defNestedProperty($name, $default, $separator); + + return $this; + } + + /** + * @param UserInterface|null $user + * @return bool + */ + public function isMyself(?UserInterface $user = null): bool + { + if (null === $user) { + $user = $this->getActiveUser(); + if ($user && !$user->authenticated) { + $user = null; + } + } + + return $user && $this->username === $user->username; + } + + /** + * Checks user authorization to the action. + * + * @param string $action + * @param string|null $scope + * @return bool|null + */ + public function authorize(string $action, string $scope = null): ?bool + { + if ($scope === 'test') { + // Special scope to test user permissions. + $scope = null; + } else { + // User needs to be enabled. + if ($this->getProperty('state') !== 'enabled') { + return false; + } + + // User needs to be logged in. + if (!$this->getProperty('authenticated')) { + return false; + } + + if (strpos($action, 'login') === false && !$this->getProperty('authorized')) { + // User needs to be authorized (2FA). + return false; + } + + // Workaround bug in Login::isUserAuthorizedForPage() <= Login v3.0.4 + if ((string)(int)$action === $action) { + return false; + } + } + + // Check custom application access. + $authorizeCallable = static::$authorizeCallable; + if ($authorizeCallable instanceof Closure) { + $callable = $authorizeCallable->bindTo($this, $this); + $authorized = $callable($action, $scope); + if (is_bool($authorized)) { + return $authorized; + } + } + + // Check user access. + $access = $this->getAccess(); + $authorized = $access->authorize($action, $scope); + if (is_bool($authorized)) { + return $authorized; + } + + // Check group access. + $authorized = $this->getGroups()->authorize($action, $scope); + if (is_bool($authorized)) { + return $authorized; + } + + // If any specific rule isn't hit, check if user is a superuser. + return $access->authorize('admin.super') === true; + } + + /** + * @param string $property + * @param mixed $default + * @return mixed + */ + public function getProperty($property, $default = null) + { + $value = parent::getProperty($property, $default); + + if ($property === 'avatar') { + $settings = $this->getMediaFieldSettings($property); + $value = $this->parseFileProperty($value, $settings); + } + + return $value; + } + + /** + * @return UserGroupIndex + */ + public function getRoles(): UserGroupIndex + { + return $this->getGroups(); + } + + /** + * Convert object into an array. + * + * @return array + */ + public function toArray() + { + $array = $this->jsonSerialize(); + + $settings = $this->getMediaFieldSettings('avatar'); + $array['avatar'] = $this->parseFileProperty($array['avatar'] ?? null, $settings); + + return $array; + } + + /** + * Convert object into YAML string. + * + * @param int $inline The level where you switch to inline YAML. + * @param int $indent The amount of spaces to use for indentation of nested nodes. + * @return string A YAML string representing the object. + */ + public function toYaml($inline = 5, $indent = 2) + { + $yaml = new YamlFormatter(['inline' => $inline, 'indent' => $indent]); + + return $yaml->encode($this->toArray()); + } + + /** + * Convert object into JSON string. + * + * @return string + */ + public function toJson() + { + $json = new JsonFormatter(); + + return $json->encode($this->toArray()); + } + + /** + * Join nested values together by using blueprints. + * + * @param string $name Dot separated path to the requested value. + * @param mixed $value Value to be joined. + * @param string|null $separator Separator, defaults to '.' + * @return $this + * @throws RuntimeException + */ + public function join($name, $value, $separator = null) + { + $separator = $separator ?? '.'; + $old = $this->get($name, null, $separator); + if ($old !== null) { + if (!is_array($old)) { + throw new RuntimeException('Value ' . $old); + } + + if (is_object($value)) { + $value = (array) $value; + } elseif (!is_array($value)) { + throw new RuntimeException('Value ' . $value); + } + + $value = $this->getBlueprint()->mergeData($old, $value, $name, $separator); + } + + $this->set($name, $value, $separator); + + return $this; + } + + /** + * Get nested structure containing default values defined in the blueprints. + * + * Fields without default value are ignored in the list. + + * @return array + */ + public function getDefaults() + { + return $this->getBlueprint()->getDefaults(); + } + + /** + * Set default values by using blueprints. + * + * @param string $name Dot separated path to the requested value. + * @param mixed $value Value to be joined. + * @param string|null $separator Separator, defaults to '.' + * @return $this + */ + public function joinDefaults($name, $value, $separator = null) + { + if (is_object($value)) { + $value = (array) $value; + } + + $old = $this->get($name, null, $separator); + if ($old !== null) { + $value = $this->getBlueprint()->mergeData($value, $old, $name, $separator ?? '.'); + } + + $this->setNestedProperty($name, $value, $separator); + + return $this; + } + + /** + * Get value from the configuration and join it with given data. + * + * @param string $name Dot separated path to the requested value. + * @param array|object $value Value to be joined. + * @param string $separator Separator, defaults to '.' + * @return array + * @throws RuntimeException + */ + public function getJoined($name, $value, $separator = null) + { + if (is_object($value)) { + $value = (array) $value; + } elseif (!is_array($value)) { + throw new RuntimeException('Value ' . $value); + } + + $old = $this->get($name, null, $separator); + + if ($old === null) { + // No value set; no need to join data. + return $value; + } + + if (!is_array($old)) { + throw new RuntimeException('Value ' . $old); + } + + // Return joined data. + return $this->getBlueprint()->mergeData($old, $value, $name, $separator ?? '.'); + } + + /** + * Set default values to the configuration if variables were not set. + * + * @param array $data + * @return $this + */ + public function setDefaults(array $data) + { + $this->setElements($this->getBlueprint()->mergeData($data, $this->toArray())); + + return $this; + } + + /** + * Validate by blueprints. + * + * @return $this + * @throws \Exception + */ + public function validate() + { + $this->getBlueprint()->validate($this->toArray()); + + return $this; + } + + /** + * Filter all items by using blueprints. + * @return $this + */ + public function filter() + { + $this->setElements($this->getBlueprint()->filter($this->toArray())); + + return $this; + } + + /** + * Get extra items which haven't been defined in blueprints. + * + * @return array + */ + public function extra() + { + return $this->getBlueprint()->extra($this->toArray()); + } + + /** + * Return unmodified data as raw string. + * + * NOTE: This function only returns data which has been saved to the storage. + * + * @return string + */ + public function raw() + { + $file = $this->file(); + + return $file ? $file->raw() : ''; + } + + /** + * Set or get the data storage. + * + * @param FileInterface|null $storage Optionally enter a new storage. + * @return FileInterface|null + */ + public function file(FileInterface $storage = null) + { + if (null !== $storage) { + $this->_storage = $storage; + } + + return $this->_storage; + } + + /** + * @return bool + */ + public function isValid(): bool + { + return $this->getProperty('state') !== null; + } + + /** + * Save user + * + * @return static + */ + public function save() + { + // TODO: We may want to handle this in the storage layer in the future. + $key = $this->getStorageKey(); + if (!$key || strpos($key, '@@')) { + $storage = $this->getFlexDirectory()->getStorage(); + if ($storage instanceof FileStorage) { + $this->setStorageKey($this->getKey()); + } + } + + $password = $this->getProperty('password') ?? $this->getProperty('password1'); + if (null !== $password && '' !== $password) { + $password2 = $this->getProperty('password2'); + if (!\is_string($password) || ($password2 && $password !== $password2)) { + throw new \RuntimeException('Passwords did not match.'); + } + + $this->setProperty('hashed_password', Authentication::create($password)); + } + $this->unsetProperty('password'); + $this->unsetProperty('password1'); + $this->unsetProperty('password2'); + + // Backwards compatibility with older plugins. + $fireEvents = $this->isAdminSite() && $this->getFlexDirectory()->getConfig('object.compat.events', true); + $grav = $this->getContainer(); + if ($fireEvents) { + $self = $this; + $grav->fireEvent('onAdminSave', new Event(['type' => 'flex', 'directory' => $this->getFlexDirectory(), 'object' => &$self])); + if ($self !== $this) { + throw new RuntimeException('Switching Flex User object during onAdminSave event is not supported! Please update plugin.'); + } + } + + $instance = parent::save(); + + // Backwards compatibility with older plugins. + if ($fireEvents) { + $grav->fireEvent('onAdminAfterSave', new Event(['type' => 'flex', 'directory' => $this->getFlexDirectory(), 'object' => $this])); + } + + return $instance; + } + + /** + * @return array + */ + public function prepareStorage(): array + { + $elements = parent::prepareStorage(); + + // Do not save authorization information. + unset($elements['authenticated'], $elements['authorized']); + + return $elements; + } + + /** + * @return MediaCollectionInterface + */ + public function getMedia() + { + /** @var Media $media */ + $media = $this->getFlexMedia(); + + // Deal with shared avatar folder. + $path = $this->getAvatarFile(); + if ($path && !$media[$path] && is_file($path)) { + $medium = MediumFactory::fromFile($path); + if ($medium) { + $media->add($path, $medium); + $name = Utils::basename($path); + if ($name !== $path) { + $media->add($name, $medium); + } + } + } + + return $media; + } + + /** + * @return string|null + */ + public function getMediaFolder(): ?string + { + $folder = $this->getFlexMediaFolder(); + + // Check for shared media + if (!$folder && !$this->getFlexDirectory()->getMediaFolder()) { + $this->_loadMedia = false; + $folder = $this->getBlueprint()->fields()['avatar']['destination'] ?? 'account://avatars'; + } + + return $folder; + } + + /** + * @param string $name + * @return array|object|null + * @internal + */ + public function initRelationship(string $name) + { + switch ($name) { + case 'media': + $list = []; + foreach ($this->getMedia()->all() as $filename => $object) { + $list[] = $this->buildMediaObject(null, $filename, $object); + } + + return $list; + case 'avatar': + return $this->buildMediaObject('avatar', basename($this->getAvatarUrl()), $this->getAvatarImage()); + } + + throw new \InvalidArgumentException(sprintf('%s: Relationship %s does not exist', $this->getFlexType(), $name)); + } + + /** + * @return bool Return true if relationships were updated. + */ + protected function updateRelationships(): bool + { + $modified = $this->getRelationships()->getModified(); + if ($modified) { + foreach ($modified as $relationship) { + $name = $relationship->getName(); + switch ($name) { + case 'avatar': + \assert($relationship instanceof ToOneRelationshipInterface); + $this->updateAvatarRelationship($relationship); + break; + default: + throw new \InvalidArgumentException(sprintf('%s: Relationship %s cannot be modified', $this->getFlexType(), $name), 400); + } + } + + $this->resetRelationships(); + + return true; + } + + return false; + } + + /** + * @param ToOneRelationshipInterface $relationship + */ + protected function updateAvatarRelationship(ToOneRelationshipInterface $relationship): void + { + $files = []; + $avatar = $this->getAvatarImage(); + if ($avatar) { + $files['avatar'][$avatar->filename] = null; + } + + $identifier = $relationship->getIdentifier(); + if ($identifier) { + \assert($identifier instanceof MediaIdentifier); + $object = $identifier->getObject(); + if ($object instanceof UploadedMediaObject) { + $uploadedFile = $object->getUploadedFile(); + if ($uploadedFile) { + $files['avatar'][$uploadedFile->getClientFilename()] = $uploadedFile; + } + } + } + + $this->update([], $files); + } + + /** + * @param string $name + * @return Blueprint + */ + protected function doGetBlueprint(string $name = ''): Blueprint + { + $blueprint = $this->getFlexDirectory()->getBlueprint($name ? '.' . $name : $name); + + // HACK: With folder storage we need to ignore the avatar destination. + if ($this->getFlexDirectory()->getMediaFolder()) { + $field = $blueprint->get('form/fields/avatar'); + if ($field) { + unset($field['destination']); + $blueprint->set('form/fields/avatar', $field); + } + } + + return $blueprint; + } + + /** + * @param UserInterface $user + * @param string $action + * @param string $scope + * @param bool $isMe + * @return bool|null + */ + protected function isAuthorizedOverride(UserInterface $user, string $action, string $scope, bool $isMe = false): ?bool + { + // Check custom application access. + $isAuthorizedCallable = static::$isAuthorizedCallable; + if ($isAuthorizedCallable instanceof Closure) { + $callable = $isAuthorizedCallable->bindTo($this, $this); + $authorized = $callable($user, $action, $scope, $isMe); + if (is_bool($authorized)) { + return $authorized; + } + } + + if ($user instanceof self && $user->getStorageKey() === $this->getStorageKey()) { + // User cannot delete his own account, otherwise he has full access. + return $action !== 'delete'; + } + + return parent::isAuthorizedOverride($user, $action, $scope, $isMe); + } + + /** + * @return string|null + */ + protected function getAvatarFile(): ?string + { + $avatars = $this->getElement('avatar'); + if (is_array($avatars) && $avatars) { + $avatar = array_shift($avatars); + + return $avatar['path'] ?? null; + } + + return null; + } + + /** + * Gets the associated media collection (original images). + * + * @return MediaCollectionInterface Representation of associated media. + */ + protected function getOriginalMedia() + { + $folder = $this->getMediaFolder(); + if ($folder) { + $folder .= '/original'; + } + + return (new Media($folder ?? '', $this->getMediaOrder()))->setTimestamps(); + } + + /** + * @param array $files + * @return void + */ + protected function setUpdatedMedia(array $files): void + { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + + $media = $this->getMedia(); + if (!$media instanceof MediaUploadInterface) { + return; + } + + $filesystem = Filesystem::getInstance(false); + + $list = []; + $list_original = []; + foreach ($files as $field => $group) { + // Ignore files without a field. + if ($field === '') { + continue; + } + $field = (string)$field; + + // Load settings for the field. + $settings = $this->getMediaFieldSettings($field); + foreach ($group as $filename => $file) { + if ($file) { + // File upload. + $filename = $file->getClientFilename(); + + /** @var FormFlashFile $file */ + $data = $file->jsonSerialize(); + unset($data['tmp_name'], $data['path']); + } else { + // File delete. + $data = null; + } + + if ($file) { + // Check file upload against media limits (except for max size). + $filename = $media->checkUploadedFile($file, $filename, ['filesize' => 0] + $settings); + } + + $self = $settings['self']; + if ($this->_loadMedia && $self) { + $filepath = $filename; + } else { + $filepath = "{$settings['destination']}/{$filename}"; + + // For backwards compatibility we are always using relative path from the installation root. + if ($locator->isStream($filepath)) { + $filepath = $locator->findResource($filepath, false, true); + } + } + + // Special handling for original images. + if (strpos($field, '/original')) { + if ($this->_loadMedia && $self) { + $list_original[$filename] = [$file, $settings]; + } + continue; + } + + // Calculate path without the retina scaling factor. + $realpath = $filesystem->pathname($filepath) . str_replace(['@3x', '@2x'], '', Utils::basename($filepath)); + + $list[$filename] = [$file, $settings]; + + $path = str_replace('.', "\n", $field); + if (null !== $data) { + $data['name'] = $filename; + $data['path'] = $filepath; + + $this->setNestedProperty("{$path}\n{$realpath}", $data, "\n"); + } else { + $this->unsetNestedProperty("{$path}\n{$realpath}", "\n"); + } + } + } + + $this->clearMediaCache(); + + $this->_uploads = $list; + $this->_uploads_original = $list_original; + } + + protected function saveUpdatedMedia(): void + { + $media = $this->getMedia(); + if (!$media instanceof MediaUploadInterface) { + throw new RuntimeException('Internal error UO101'); + } + + // Upload/delete original sized images. + /** + * @var string $filename + * @var UploadedFileInterface|array|null $file + */ + foreach ($this->_uploads_original ?? [] as $filename => $file) { + $filename = 'original/' . $filename; + if (is_array($file)) { + [$file, $settings] = $file; + } else { + $settings = null; + } + if ($file instanceof UploadedFileInterface) { + $media->copyUploadedFile($file, $filename, $settings); + } else { + $media->deleteFile($filename, $settings); + } + } + + // Upload/delete altered files. + /** + * @var string $filename + * @var UploadedFileInterface|array|null $file + */ + foreach ($this->getUpdatedMedia() as $filename => $file) { + if (is_array($file)) { + [$file, $settings] = $file; + } else { + $settings = null; + } + if ($file instanceof UploadedFileInterface) { + $media->copyUploadedFile($file, $filename, $settings); + } else { + $media->deleteFile($filename, $settings); + } + } + + $this->setUpdatedMedia([]); + $this->clearMediaCache(); + } + + /** + * @return array + */ + protected function doSerialize(): array + { + return [ + 'type' => $this->getFlexType(), + 'key' => $this->getKey(), + 'elements' => $this->jsonSerialize(), + 'storage' => $this->getMetaData() + ]; + } + + /** + * @return UserGroupIndex + */ + protected function getUserGroups() + { + $grav = Grav::instance(); + + /** @var Flex $flex */ + $flex = $grav['flex']; + + /** @var UserGroupCollection|null $groups */ + $groups = $flex->getDirectory('user-groups'); + if ($groups) { + /** @var UserGroupIndex $index */ + $index = $groups->getIndex(); + + return $index; + } + + return $grav['user_groups']; + } + + /** + * @return UserGroupIndex + */ + protected function getGroups() + { + if (null === $this->_groups) { + /** @var UserGroupIndex $groups */ + $groups = $this->getUserGroups()->select((array)$this->getProperty('groups')); + $this->_groups = $groups; + } + + return $this->_groups; + } + + /** + * @return Access + */ + protected function getAccess(): Access + { + if (null === $this->_access) { + $this->_access = new Access($this->getProperty('access')); + } + + return $this->_access; + } + + /** + * @param mixed $value + * @return array + */ + protected function offsetLoad_access($value): array + { + if (!$value instanceof Access) { + $value = new Access($value); + } + + return $value->jsonSerialize(); + } + + /** + * @param mixed $value + * @return array + */ + protected function offsetPrepare_access($value): array + { + return $this->offsetLoad_access($value); + } + + /** + * @param array|null $value + * @return array|null + */ + protected function offsetSerialize_access(?array $value): ?array + { + return $value; + } +} diff --git a/system/src/Grav/Common/Form/FormFlash.php b/system/src/Grav/Common/Form/FormFlash.php new file mode 100644 index 0000000..24f9999 --- /dev/null +++ b/system/src/Grav/Common/Form/FormFlash.php @@ -0,0 +1,107 @@ +files as $field => $files) { + if (strpos($field, '/')) { + continue; + } + foreach ($files as $file) { + if (is_array($file)) { + $file['tmp_name'] = $this->getTmpDir() . '/' . $file['tmp_name']; + $fields[$field][$file['path'] ?? $file['name']] = $file; + } + } + } + + return $fields; + } + + /** + * @param string $field + * @param string $filename + * @param array $upload + * @return bool + * @deprecated 1.6 For backwards compatibility only, do not use + */ + public function uploadFile(string $field, string $filename, array $upload): bool + { + if (!$this->uniqueId) { + return false; + } + + $tmp_dir = $this->getTmpDir(); + Folder::create($tmp_dir); + + $tmp_file = $upload['file']['tmp_name']; + $basename = Utils::basename($tmp_file); + + if (!move_uploaded_file($tmp_file, $tmp_dir . '/' . $basename)) { + return false; + } + + $upload['file']['tmp_name'] = $basename; + $upload['file']['name'] = $filename; + + $this->addFileInternal($field, $filename, $upload['file']); + + return true; + } + + /** + * @param string $field + * @param string $filename + * @param array $upload + * @param array $crop + * @return bool + * @deprecated 1.6 For backwards compatibility only, do not use + */ + public function cropFile(string $field, string $filename, array $upload, array $crop): bool + { + if (!$this->uniqueId) { + return false; + } + + $tmp_dir = $this->getTmpDir(); + Folder::create($tmp_dir); + + $tmp_file = $upload['file']['tmp_name']; + $basename = Utils::basename($tmp_file); + + if (!move_uploaded_file($tmp_file, $tmp_dir . '/' . $basename)) { + return false; + } + + $upload['file']['tmp_name'] = $basename; + $upload['file']['name'] = $filename; + + $this->addFileInternal($field, $filename, $upload['file'], $crop); + + return true; + } +} diff --git a/system/src/Grav/Common/GPM/AbstractCollection.php b/system/src/Grav/Common/GPM/AbstractCollection.php new file mode 100644 index 0000000..ab3c2fb --- /dev/null +++ b/system/src/Grav/Common/GPM/AbstractCollection.php @@ -0,0 +1,41 @@ +toArray(), JSON_THROW_ON_ERROR); + } + + /** + * @return array + */ + public function toArray() + { + $items = []; + + foreach ($this->items as $name => $package) { + $items[$name] = $package->toArray(); + } + + return $items; + } +} diff --git a/system/src/Grav/Common/GPM/Common/AbstractPackageCollection.php b/system/src/Grav/Common/GPM/Common/AbstractPackageCollection.php new file mode 100644 index 0000000..5f69d37 --- /dev/null +++ b/system/src/Grav/Common/GPM/Common/AbstractPackageCollection.php @@ -0,0 +1,50 @@ +items as $name => $package) { + $items[$name] = $package->toArray(); + } + + return json_encode($items, JSON_THROW_ON_ERROR); + } + + /** + * @return array + */ + public function toArray() + { + $items = []; + + foreach ($this->items as $name => $package) { + $items[$name] = $package->toArray(); + } + + return $items; + } +} diff --git a/system/src/Grav/Common/GPM/Common/CachedCollection.php b/system/src/Grav/Common/GPM/Common/CachedCollection.php new file mode 100644 index 0000000..f93c76c --- /dev/null +++ b/system/src/Grav/Common/GPM/Common/CachedCollection.php @@ -0,0 +1,43 @@ + $item) { + $this->append([$name => $item]); + } + } +} diff --git a/system/src/Grav/Common/GPM/Common/Package.php b/system/src/Grav/Common/GPM/Common/Package.php new file mode 100644 index 0000000..2b359d1 --- /dev/null +++ b/system/src/Grav/Common/GPM/Common/Package.php @@ -0,0 +1,99 @@ +data = $package; + + if ($type) { + $this->data->set('package_type', $type); + } + } + + /** + * @return Data + */ + public function getData() + { + return $this->data; + } + + /** + * @param string $key + * @return mixed + */ + #[\ReturnTypeWillChange] + public function __get($key) + { + return $this->data->get($key); + } + + /** + * @param string $key + * @param mixed $value + * @return void + */ + #[\ReturnTypeWillChange] + public function __set($key, $value) + { + $this->data->set($key, $value); + } + + /** + * @param string $key + * @return bool + */ + #[\ReturnTypeWillChange] + public function __isset($key) + { + return isset($this->data->{$key}); + } + + /** + * @return string + */ + #[\ReturnTypeWillChange] + public function __toString() + { + return $this->toJson(); + } + + /** + * @return string + */ + public function toJson() + { + return $this->data->toJson(); + } + + /** + * @return array + */ + public function toArray() + { + return $this->data->toArray(); + } +} diff --git a/system/src/Grav/Common/GPM/GPM.php b/system/src/Grav/Common/GPM/GPM.php new file mode 100644 index 0000000..2f05a76 --- /dev/null +++ b/system/src/Grav/Common/GPM/GPM.php @@ -0,0 +1,1270 @@ + 'user/plugins/%name%', + 'themes' => 'user/themes/%name%', + 'skeletons' => 'user/' + ]; + + /** + * Creates a new GPM instance with Local and Remote packages available + * + * @param bool $refresh Applies to Remote Packages only and forces a refetch of data + * @param callable|null $callback Either a function or callback in array notation + */ + public function __construct($refresh = false, $callback = null) + { + parent::__construct(); + + Folder::create(CACHE_DIR . '/gpm'); + + $this->cache = []; + $this->installed = new Local\Packages(); + $this->refresh = $refresh; + $this->callback = $callback; + } + + /** + * Magic getter method + * + * @param string $offset Asset name value + * @return mixed Asset value + */ + #[\ReturnTypeWillChange] + public function __get($offset) + { + switch ($offset) { + case 'grav': + return $this->getGrav(); + } + + return parent::__get($offset); + } + + /** + * Magic method to determine if the attribute is set + * + * @param string $offset Asset name value + * @return bool True if the value is set + */ + #[\ReturnTypeWillChange] + public function __isset($offset) + { + switch ($offset) { + case 'grav': + return $this->getGrav() !== null; + } + + return parent::__isset($offset); + } + + /** + * Return the locally installed packages + * + * @return Local\Packages + */ + public function getInstalled() + { + return $this->installed; + } + + /** + * Returns the Locally installable packages + * + * @param array $list_type_installed + * @return array The installed packages + */ + public function getInstallable($list_type_installed = ['plugins' => true, 'themes' => true]) + { + $items = ['total' => 0]; + foreach ($list_type_installed as $type => $type_installed) { + if ($type_installed === false) { + continue; + } + $methodInstallableType = 'getInstalled' . ucfirst($type); + $to_install = $this->$methodInstallableType(); + $items[$type] = $to_install; + $items['total'] += count($to_install); + } + + return $items; + } + + /** + * Returns the amount of locally installed packages + * + * @return int Amount of installed packages + */ + public function countInstalled() + { + $installed = $this->getInstalled(); + + return count($installed['plugins']) + count($installed['themes']); + } + + /** + * Return the instance of a specific Package + * + * @param string $slug The slug of the Package + * @return Local\Package|null The instance of the Package + */ + public function getInstalledPackage($slug) + { + return $this->getInstalledPlugin($slug) ?? $this->getInstalledTheme($slug); + } + + /** + * Return the instance of a specific Plugin + * + * @param string $slug The slug of the Plugin + * @return Local\Package|null The instance of the Plugin + */ + public function getInstalledPlugin($slug) + { + return $this->installed['plugins'][$slug] ?? null; + } + + /** + * Returns the Locally installed plugins + * @return Iterator The installed plugins + */ + public function getInstalledPlugins() + { + return $this->installed['plugins']; + } + + + /** + * Returns the plugin's enabled state + * + * @param string $slug + * @return bool True if the Plugin is Enabled. False if manually set to enable:false. Null otherwise. + */ + public function isPluginEnabled($slug): bool + { + $grav = Grav::instance(); + + return ($grav['config']['plugins'][$slug]['enabled'] ?? false) === true; + } + + /** + * Checks if a Plugin is installed + * + * @param string $slug The slug of the Plugin + * @return bool True if the Plugin has been installed. False otherwise + */ + public function isPluginInstalled($slug): bool + { + return isset($this->installed['plugins'][$slug]); + } + + /** + * @param string $slug + * @return bool + */ + public function isPluginInstalledAsSymlink($slug) + { + $plugin = $this->getInstalledPlugin($slug); + + return (bool)($plugin->symlink ?? false); + } + + /** + * Return the instance of a specific Theme + * + * @param string $slug The slug of the Theme + * @return Local\Package|null The instance of the Theme + */ + public function getInstalledTheme($slug) + { + return $this->installed['themes'][$slug] ?? null; + } + + /** + * Returns the Locally installed themes + * + * @return Iterator The installed themes + */ + public function getInstalledThemes() + { + return $this->installed['themes']; + } + + /** + * Checks if a Theme is enabled + * + * @param string $slug The slug of the Theme + * @return bool True if the Theme has been set to the default theme. False if installed, but not enabled. Null otherwise. + */ + public function isThemeEnabled($slug): bool + { + $grav = Grav::instance(); + + $current_theme = $grav['config']['system']['pages']['theme'] ?? null; + + return $current_theme === $slug; + } + + /** + * Checks if a Theme is installed + * + * @param string $slug The slug of the Theme + * @return bool True if the Theme has been installed. False otherwise + */ + public function isThemeInstalled($slug): bool + { + return isset($this->installed['themes'][$slug]); + } + + /** + * Returns the amount of updates available + * + * @return int Amount of available updates + */ + public function countUpdates() + { + return count($this->getUpdatablePlugins()) + count($this->getUpdatableThemes()); + } + + /** + * Returns an array of Plugins and Themes that can be updated. + * Plugins and Themes are extended with the `available` property that relies to the remote version + * + * @param array $list_type_update specifies what type of package to update + * @return array Array of updatable Plugins and Themes. + * Format: ['total' => int, 'plugins' => array, 'themes' => array] + */ + public function getUpdatable($list_type_update = ['plugins' => true, 'themes' => true]) + { + $items = ['total' => 0]; + foreach ($list_type_update as $type => $type_updatable) { + if ($type_updatable === false) { + continue; + } + $methodUpdatableType = 'getUpdatable' . ucfirst($type); + $to_update = $this->$methodUpdatableType(); + $items[$type] = $to_update; + $items['total'] += count($to_update); + } + + return $items; + } + + /** + * Returns an array of Plugins that can be updated. + * The Plugins are extended with the `available` property that relies to the remote version + * + * @return array Array of updatable Plugins + */ + public function getUpdatablePlugins() + { + $items = []; + + $repository = $this->getRepository(); + if (null === $repository) { + return $items; + } + + $plugins = $repository['plugins']; + + // local cache to speed things up + if (isset($this->cache[__METHOD__])) { + return $this->cache[__METHOD__]; + } + + foreach ($this->installed['plugins'] as $slug => $plugin) { + if (!isset($plugins[$slug]) || $plugin->symlink || !$plugin->version || $plugin->gpm === false) { + continue; + } + + $local_version = $plugin->version ?? 'Unknown'; + $remote_version = $plugins[$slug]->version; + + if (version_compare($local_version, $remote_version) < 0) { + $plugins[$slug]->available = $remote_version; + $plugins[$slug]->version = $local_version; + $plugins[$slug]->type = $plugins[$slug]->release_type; + $items[$slug] = $plugins[$slug]; + } + } + + $this->cache[__METHOD__] = $items; + + return $items; + } + + /** + * Get the latest release of a package from the GPM + * + * @param string $package_name + * @return string|null + */ + public function getLatestVersionOfPackage($package_name) + { + $repository = $this->getRepository(); + if (null === $repository) { + return null; + } + + $plugins = $repository['plugins']; + if (isset($plugins[$package_name])) { + return $plugins[$package_name]->available ?: $plugins[$package_name]->version; + } + + //Not a plugin, it's a theme? + $themes = $repository['themes']; + if (isset($themes[$package_name])) { + return $themes[$package_name]->available ?: $themes[$package_name]->version; + } + + return null; + } + + /** + * Check if a Plugin or Theme is updatable + * + * @param string $slug The slug of the package + * @return bool True if updatable. False otherwise or if not found + */ + public function isUpdatable($slug) + { + return $this->isPluginUpdatable($slug) || $this->isThemeUpdatable($slug); + } + + /** + * Checks if a Plugin is updatable + * + * @param string $plugin The slug of the Plugin + * @return bool True if the Plugin is updatable. False otherwise + */ + public function isPluginUpdatable($plugin) + { + return array_key_exists($plugin, (array)$this->getUpdatablePlugins()); + } + + /** + * Returns an array of Themes that can be updated. + * The Themes are extended with the `available` property that relies to the remote version + * + * @return array Array of updatable Themes + */ + public function getUpdatableThemes() + { + $items = []; + + $repository = $this->getRepository(); + if (null === $repository) { + return $items; + } + + $themes = $repository['themes']; + + // local cache to speed things up + if (isset($this->cache[__METHOD__])) { + return $this->cache[__METHOD__]; + } + + foreach ($this->installed['themes'] as $slug => $plugin) { + if (!isset($themes[$slug]) || $plugin->symlink || !$plugin->version || $plugin->gpm === false) { + continue; + } + + $local_version = $plugin->version ?? 'Unknown'; + $remote_version = $themes[$slug]->version; + + if (version_compare($local_version, $remote_version) < 0) { + $themes[$slug]->available = $remote_version; + $themes[$slug]->version = $local_version; + $themes[$slug]->type = $themes[$slug]->release_type; + $items[$slug] = $themes[$slug]; + } + } + + $this->cache[__METHOD__] = $items; + + return $items; + } + + /** + * Checks if a Theme is Updatable + * + * @param string $theme The slug of the Theme + * @return bool True if the Theme is updatable. False otherwise + */ + public function isThemeUpdatable($theme) + { + return array_key_exists($theme, (array)$this->getUpdatableThemes()); + } + + /** + * Get the release type of a package (stable / testing) + * + * @param string $package_name + * @return string|null + */ + public function getReleaseType($package_name) + { + $repository = $this->getRepository(); + if (null === $repository) { + return null; + } + + $plugins = $repository['plugins']; + if (isset($plugins[$package_name])) { + return $plugins[$package_name]->release_type; + } + + //Not a plugin, it's a theme? + $themes = $repository['themes']; + if (isset($themes[$package_name])) { + return $themes[$package_name]->release_type; + } + + return null; + } + + /** + * Returns true if the package latest release is stable + * + * @param string $package_name + * @return bool + */ + public function isStableRelease($package_name) + { + return $this->getReleaseType($package_name) === 'stable'; + } + + /** + * Returns true if the package latest release is testing + * + * @param string $package_name + * @return bool + */ + public function isTestingRelease($package_name) + { + $package = $this->getInstalledPackage($package_name); + $testing = $package->testing ?? false; + + return $this->getReleaseType($package_name) === 'testing' || $testing; + } + + /** + * Returns a Plugin from the repository + * + * @param string $slug The slug of the Plugin + * @return Remote\Package|null Package if found, NULL if not + */ + public function getRepositoryPlugin($slug) + { + $packages = $this->getRepositoryPlugins(); + + return $packages ? ($packages[$slug] ?? null) : null; + } + + /** + * Returns the list of Plugins available in the repository + * + * @return Iterator|null The Plugins remotely available + */ + public function getRepositoryPlugins() + { + return $this->getRepository()['plugins'] ?? null; + } + + /** + * Returns a Theme from the repository + * + * @param string $slug The slug of the Theme + * @return Remote\Package|null Package if found, NULL if not + */ + public function getRepositoryTheme($slug) + { + $packages = $this->getRepositoryThemes(); + + return $packages ? ($packages[$slug] ?? null) : null; + } + + /** + * Returns the list of Themes available in the repository + * + * @return Iterator|null The Themes remotely available + */ + public function getRepositoryThemes() + { + return $this->getRepository()['themes'] ?? null; + } + + /** + * Returns the list of Plugins and Themes available in the repository + * + * @return Remote\Packages|null Available Plugins and Themes + * Format: ['plugins' => array, 'themes' => array] + */ + public function getRepository() + { + if (null === $this->repository) { + try { + $this->repository = new Remote\Packages($this->refresh, $this->callback); + } catch (Exception $e) {} + } + + return $this->repository; + } + + /** + * Returns Grav version available in the repository + * + * @return Remote\GravCore|null + */ + public function getGrav() + { + if (null === $this->grav) { + try { + $this->grav = new Remote\GravCore($this->refresh, $this->callback); + } catch (Exception $e) {} + } + + return $this->grav; + } + + /** + * Searches for a Package in the repository + * + * @param string $search Can be either the slug or the name + * @param bool $ignore_exception True if should not fire an exception (for use in Twig) + * @return Remote\Package|false Package if found, FALSE if not + */ + public function findPackage($search, $ignore_exception = false) + { + $search = strtolower($search); + + $found = $this->getRepositoryPlugin($search) ?? $this->getRepositoryTheme($search); + if ($found) { + return $found; + } + + $themes = $this->getRepositoryThemes(); + $plugins = $this->getRepositoryPlugins(); + + if (null === $themes || null === $plugins) { + if (!is_writable(GRAV_ROOT . '/cache/gpm')) { + throw new RuntimeException('The cache/gpm folder is not writable. Please check the folder permissions.'); + } + + if ($ignore_exception) { + return false; + } + + throw new RuntimeException('GPM not reachable. Please check your internet connection or check the Grav site is reachable'); + } + + foreach ($themes as $slug => $theme) { + if ($search === $slug || $search === $theme->name) { + return $theme; + } + } + + foreach ($plugins as $slug => $plugin) { + if ($search === $slug || $search === $plugin->name) { + return $plugin; + } + } + + return false; + } + + /** + * Download the zip package via the URL + * + * @param string $package_file + * @param string $tmp + * @return string|null + */ + public static function downloadPackage($package_file, $tmp) + { + $package = parse_url($package_file); + if (!is_array($package)) { + throw new \RuntimeException("Malformed GPM URL: {$package_file}"); + } + + $filename = Utils::basename($package['path'] ?? ''); + + if (Grav::instance()['config']->get('system.gpm.official_gpm_only') && ($package['host'] ?? null) !== 'getgrav.org') { + throw new RuntimeException('Only official GPM URLs are allowed. You can modify this behavior in the System configuration.'); + } + + $output = Response::get($package_file, []); + + if ($output) { + Folder::create($tmp); + file_put_contents($tmp . DS . $filename, $output); + return $tmp . DS . $filename; + } + + return null; + } + + /** + * Copy the local zip package to tmp + * + * @param string $package_file + * @param string $tmp + * @return string|null + */ + public static function copyPackage($package_file, $tmp) + { + $package_file = realpath($package_file); + + if ($package_file && file_exists($package_file)) { + $filename = Utils::basename($package_file); + Folder::create($tmp); + copy($package_file, $tmp . DS . $filename); + return $tmp . DS . $filename; + } + + return null; + } + + /** + * Try to guess the package type from the source files + * + * @param string $source + * @return string|false + */ + public static function getPackageType($source) + { + $plugin_regex = '/^class\\s{1,}[a-zA-Z0-9]{1,}\\s{1,}extends.+Plugin/m'; + $theme_regex = '/^class\\s{1,}[a-zA-Z0-9]{1,}\\s{1,}extends.+Theme/m'; + + if (file_exists($source . 'system/defines.php') && + file_exists($source . 'system/config/system.yaml') + ) { + return 'grav'; + } + + // must have a blueprint + if (!file_exists($source . 'blueprints.yaml')) { + return false; + } + + // either theme or plugin + $name = Utils::basename($source); + if (Utils::contains($name, 'theme')) { + return 'theme'; + } + if (Utils::contains($name, 'plugin')) { + return 'plugin'; + } + + $glob = glob($source . '*.php') ?: []; + foreach ($glob as $filename) { + $contents = file_get_contents($filename); + if (!$contents) { + continue; + } + if (preg_match($theme_regex, $contents)) { + return 'theme'; + } + if (preg_match($plugin_regex, $contents)) { + return 'plugin'; + } + } + + // Assume it's a theme + return 'theme'; + } + + /** + * Try to guess the package name from the source files + * + * @param string $source + * @return string|false + */ + public static function getPackageName($source) + { + $ignore_yaml_files = ['blueprints', 'languages']; + + $glob = glob($source . '*.yaml') ?: []; + foreach ($glob as $filename) { + $name = strtolower(Utils::basename($filename, '.yaml')); + if (in_array($name, $ignore_yaml_files)) { + continue; + } + + return $name; + } + + return false; + } + + /** + * Find/Parse the blueprint file + * + * @param string $source + * @return array|false + */ + public static function getBlueprints($source) + { + $blueprint_file = $source . 'blueprints.yaml'; + if (!file_exists($blueprint_file)) { + return false; + } + + $file = YamlFile::instance($blueprint_file); + $blueprint = (array)$file->content(); + $file->free(); + + return $blueprint; + } + + /** + * Get the install path for a name and a particular type of package + * + * @param string $type + * @param string $name + * @return string + */ + public static function getInstallPath($type, $name) + { + $locator = Grav::instance()['locator']; + + if ($type === 'theme') { + $install_path = $locator->findResource('themes://', false) . DS . $name; + } else { + $install_path = $locator->findResource('plugins://', false) . DS . $name; + } + + return $install_path; + } + + /** + * Searches for a list of Packages in the repository + * + * @param array $searches An array of either slugs or names + * @return array Array of found Packages + * Format: ['total' => int, 'not_found' => array, ] + */ + public function findPackages($searches = []) + { + $packages = ['total' => 0, 'not_found' => []]; + $inflector = new Inflector(); + + foreach ($searches as $search) { + $repository = ''; + // if this is an object, get the search data from the key + if (is_object($search)) { + $search = (array)$search; + $key = key($search); + $repository = $search[$key]; + $search = $key; + } + + $found = $this->findPackage($search); + if ($found) { + // set override repository if provided + if ($repository) { + $found->override_repository = $repository; + } + if (!isset($packages[$found->package_type])) { + $packages[$found->package_type] = []; + } + + $packages[$found->package_type][$found->slug] = $found; + $packages['total']++; + } else { + // make a best guess at the type based on the repo URL + if (Utils::contains($repository, '-theme')) { + $type = 'themes'; + } else { + $type = 'plugins'; + } + + $not_found = new stdClass(); + $not_found->name = $inflector::camelize($search); + $not_found->slug = $search; + $not_found->package_type = $type; + $not_found->install_path = str_replace('%name%', $search, $this->install_paths[$type]); + $not_found->override_repository = $repository; + $packages['not_found'][$search] = $not_found; + } + } + + return $packages; + } + + /** + * Return the list of packages that have the passed one as dependency + * + * @param string $slug The slug name of the package + * @return array + */ + public function getPackagesThatDependOnPackage($slug) + { + $plugins = $this->getInstalledPlugins(); + $themes = $this->getInstalledThemes(); + $packages = array_merge($plugins->toArray(), $themes->toArray()); + + $list = []; + foreach ($packages as $package_name => $package) { + $dependencies = $package['dependencies'] ?? []; + foreach ($dependencies as $dependency) { + if (is_array($dependency) && isset($dependency['name'])) { + $dependency = $dependency['name']; + } + + if ($dependency === $slug) { + $list[] = $package_name; + } + } + } + + return $list; + } + + + /** + * Get the required version of a dependency of a package + * + * @param string $package_slug + * @param string $dependency_slug + * @return mixed|null + */ + public function getVersionOfDependencyRequiredByPackage($package_slug, $dependency_slug) + { + $dependencies = $this->getInstalledPackage($package_slug)->dependencies ?? []; + foreach ($dependencies as $dependency) { + if (isset($dependency[$dependency_slug])) { + return $dependency[$dependency_slug]; + } + } + + return null; + } + + /** + * Check the package identified by $slug can be updated to the version passed as argument. + * Thrown an exception if it cannot be updated because another package installed requires it to be at an older version. + * + * @param string $slug + * @param string $version_with_operator + * @param array $ignore_packages_list + * @return bool + * @throws RuntimeException + */ + public function checkNoOtherPackageNeedsThisDependencyInALowerVersion($slug, $version_with_operator, $ignore_packages_list) + { + // check if any of the currently installed package need this in a lower version than the one we need. In case, abort and tell which package + $dependent_packages = $this->getPackagesThatDependOnPackage($slug); + $version = $this->calculateVersionNumberFromDependencyVersion($version_with_operator); + + if (count($dependent_packages)) { + foreach ($dependent_packages as $dependent_package) { + $other_dependency_version_with_operator = $this->getVersionOfDependencyRequiredByPackage($dependent_package, $slug); + $other_dependency_version = $this->calculateVersionNumberFromDependencyVersion($other_dependency_version_with_operator); + + // check version is compatible with the one needed by the current package + if ($this->versionFormatIsNextSignificantRelease($other_dependency_version_with_operator)) { + $compatible = $this->checkNextSignificantReleasesAreCompatible($version, $other_dependency_version); + if (!$compatible && !in_array($dependent_package, $ignore_packages_list, true)) { + throw new RuntimeException( + "Package $slug is required in an older version by package $dependent_package. This package needs a newer version, and because of this it cannot be installed. The $dependent_package package must be updated to use a newer release of $slug.", + 2 + ); + } + } + } + } + + return true; + } + + /** + * Check the passed packages list can be updated + * + * @param array $packages_names_list + * @return void + * @throws Exception + */ + public function checkPackagesCanBeInstalled($packages_names_list) + { + foreach ($packages_names_list as $package_name) { + $latest = $this->getLatestVersionOfPackage($package_name); + $this->checkNoOtherPackageNeedsThisDependencyInALowerVersion($package_name, $latest, $packages_names_list); + } + } + + /** + * Fetch the dependencies, check the installed packages and return an array with + * the list of packages with associated an information on what to do: install, update or ignore. + * + * `ignore` means the package is already installed and can be safely left as-is. + * `install` means the package is not installed and must be installed. + * `update` means the package is already installed and must be updated as a dependency needs a higher version. + * + * @param array $packages + * @return array + * @throws RuntimeException + */ + public function getDependencies($packages) + { + $dependencies = $this->calculateMergedDependenciesOfPackages($packages); + foreach ($dependencies as $dependency_slug => $dependencyVersionWithOperator) { + $dependency_slug = (string)$dependency_slug; + if (in_array($dependency_slug, $packages, true)) { + unset($dependencies[$dependency_slug]); + continue; + } + + // Check PHP version + if ($dependency_slug === 'php') { + $testVersion = $this->calculateVersionNumberFromDependencyVersion($dependencyVersionWithOperator); + if (version_compare($testVersion, PHP_VERSION) === 1) { + //Needs a Grav update first + throw new RuntimeException("One of the packages require PHP {$dependencies['php']}. Please update PHP to resolve this"); + } + + unset($dependencies[$dependency_slug]); + continue; + } + + //First, check for Grav dependency. If a dependency requires Grav > the current version, abort and tell. + if ($dependency_slug === 'grav') { + $testVersion = $this->calculateVersionNumberFromDependencyVersion($dependencyVersionWithOperator); + if (version_compare($testVersion, GRAV_VERSION) === 1) { + //Needs a Grav update first + throw new RuntimeException("One of the packages require Grav {$dependencies['grav']}. Please update Grav to the latest release."); + } + + unset($dependencies[$dependency_slug]); + continue; + } + + if ($this->isPluginInstalled($dependency_slug)) { + if ($this->isPluginInstalledAsSymlink($dependency_slug)) { + unset($dependencies[$dependency_slug]); + continue; + } + + $dependencyVersion = $this->calculateVersionNumberFromDependencyVersion($dependencyVersionWithOperator); + + // get currently installed version + $locator = Grav::instance()['locator']; + $blueprints_path = $locator->findResource('plugins://' . $dependency_slug . DS . 'blueprints.yaml'); + $file = YamlFile::instance($blueprints_path); + $package_yaml = $file->content(); + $file->free(); + $currentlyInstalledVersion = $package_yaml['version']; + + // if requirement is next significant release, check is compatible with currently installed version, might not be + if ($this->versionFormatIsNextSignificantRelease($dependencyVersionWithOperator) + && $this->firstVersionIsLower($dependencyVersion, $currentlyInstalledVersion)) { + $compatible = $this->checkNextSignificantReleasesAreCompatible($dependencyVersion, $currentlyInstalledVersion); + + if (!$compatible) { + throw new RuntimeException( + 'Dependency ' . $dependency_slug . ' is required in an older version than the one installed. This package must be updated. Please get in touch with its developer.', + 2 + ); + } + } + + //if I already have the latest release, remove the dependency + $latestRelease = $this->getLatestVersionOfPackage($dependency_slug); + + if ($this->firstVersionIsLower($latestRelease, $dependencyVersion)) { + //throw an exception if a required version cannot be found in the GPM yet + throw new RuntimeException( + 'Dependency ' . $package_yaml['name'] . ' is required in version ' . $dependencyVersion . ' which is higher than the latest release, ' . $latestRelease . '. Try running `bin/gpm -f index` to force a refresh of the GPM cache', + 1 + ); + } + + if ($this->firstVersionIsLower($currentlyInstalledVersion, $dependencyVersion)) { + $dependencies[$dependency_slug] = 'update'; + } elseif ($currentlyInstalledVersion === $latestRelease) { + unset($dependencies[$dependency_slug]); + } else { + // an update is not strictly required mark as 'ignore' + $dependencies[$dependency_slug] = 'ignore'; + } + } else { + $dependencyVersion = $this->calculateVersionNumberFromDependencyVersion($dependencyVersionWithOperator); + + // if requirement is next significant release, check is compatible with latest available version, might not be + if ($this->versionFormatIsNextSignificantRelease($dependencyVersionWithOperator)) { + $latestVersionOfPackage = $this->getLatestVersionOfPackage($dependency_slug); + if ($this->firstVersionIsLower($dependencyVersion, $latestVersionOfPackage)) { + $compatible = $this->checkNextSignificantReleasesAreCompatible( + $dependencyVersion, + $latestVersionOfPackage + ); + + if (!$compatible) { + throw new RuntimeException( + 'Dependency ' . $dependency_slug . ' is required in an older version than the latest release available, and it cannot be installed. This package must be updated. Please get in touch with its developer.', + 2 + ); + } + } + } + + $dependencies[$dependency_slug] = 'install'; + } + } + + $dependencies_slugs = array_keys($dependencies); + $this->checkNoOtherPackageNeedsTheseDependenciesInALowerVersion(array_merge($packages, $dependencies_slugs)); + + return $dependencies; + } + + /** + * @param array $dependencies_slugs + * @return void + */ + public function checkNoOtherPackageNeedsTheseDependenciesInALowerVersion($dependencies_slugs) + { + foreach ($dependencies_slugs as $dependency_slug) { + $this->checkNoOtherPackageNeedsThisDependencyInALowerVersion( + $dependency_slug, + $this->getLatestVersionOfPackage($dependency_slug), + $dependencies_slugs + ); + } + } + + /** + * @param string $firstVersion + * @param string $secondVersion + * @return bool + */ + private function firstVersionIsLower($firstVersion, $secondVersion) + { + return version_compare($firstVersion, $secondVersion) === -1; + } + + /** + * Calculates and merges the dependencies of a package + * + * @param string $packageName The package information + * @param array $dependencies The dependencies array + * @return array + */ + private function calculateMergedDependenciesOfPackage($packageName, $dependencies) + { + $packageData = $this->findPackage($packageName); + + if (empty($packageData->dependencies)) { + return $dependencies; + } + + foreach ($packageData->dependencies as $dependency) { + $dependencyName = $dependency['name'] ?? null; + if (!$dependencyName) { + continue; + } + + $dependencyVersion = $dependency['version'] ?? '*'; + + if (!isset($dependencies[$dependencyName])) { + // Dependency added for the first time + $dependencies[$dependencyName] = $dependencyVersion; + + //Factor in the package dependencies too + $dependencies = $this->calculateMergedDependenciesOfPackage($dependencyName, $dependencies); + } elseif ($dependencyVersion !== '*') { + // Dependency already added by another package + // If this package requires a version higher than the currently stored one, store this requirement instead + $currentDependencyVersion = $dependencies[$dependencyName]; + $currently_stored_version_number = $this->calculateVersionNumberFromDependencyVersion($currentDependencyVersion); + + $currently_stored_version_is_in_next_significant_release_format = false; + if ($this->versionFormatIsNextSignificantRelease($currentDependencyVersion)) { + $currently_stored_version_is_in_next_significant_release_format = true; + } + + if (!$currently_stored_version_number) { + $currently_stored_version_number = '*'; + } + + $current_package_version_number = $this->calculateVersionNumberFromDependencyVersion($dependencyVersion); + if (!$current_package_version_number) { + throw new RuntimeException("Bad format for version of dependency {$dependencyName} for package {$packageName}", 1); + } + + $current_package_version_is_in_next_significant_release_format = false; + if ($this->versionFormatIsNextSignificantRelease($dependencyVersion)) { + $current_package_version_is_in_next_significant_release_format = true; + } + + //If I had stored '*', change right away with the more specific version required + if ($currently_stored_version_number === '*') { + $dependencies[$dependencyName] = $dependencyVersion; + } elseif (!$currently_stored_version_is_in_next_significant_release_format && !$current_package_version_is_in_next_significant_release_format) { + //Comparing versions equals or higher, a simple version_compare is enough + if (version_compare($currently_stored_version_number, $current_package_version_number) === -1) { + //Current package version is higher + $dependencies[$dependencyName] = $dependencyVersion; + } + } else { + $compatible = $this->checkNextSignificantReleasesAreCompatible($currently_stored_version_number, $current_package_version_number); + if (!$compatible) { + throw new RuntimeException("Dependency {$dependencyName} is required in two incompatible versions", 2); + } + } + } + } + + return $dependencies; + } + + /** + * Calculates and merges the dependencies of the passed packages + * + * @param array $packages + * @return array + */ + public function calculateMergedDependenciesOfPackages($packages) + { + $dependencies = []; + + foreach ($packages as $package) { + $dependencies = $this->calculateMergedDependenciesOfPackage($package, $dependencies); + } + + return $dependencies; + } + + /** + * Returns the actual version from a dependency version string. + * Examples: + * $versionInformation == '~2.0' => returns '2.0' + * $versionInformation == '>=2.0.2' => returns '2.0.2' + * $versionInformation == '2.0.2' => returns '2.0.2' + * $versionInformation == '*' => returns null + * $versionInformation == '' => returns null + * + * @param string $version + * @return string|null + */ + public function calculateVersionNumberFromDependencyVersion($version) + { + if ($version === '*') { + return null; + } + if ($version === '') { + return null; + } + if ($this->versionFormatIsNextSignificantRelease($version)) { + return trim(substr($version, 1)); + } + if ($this->versionFormatIsEqualOrHigher($version)) { + return trim(substr($version, 2)); + } + + return $version; + } + + /** + * Check if the passed version information contains next significant release (tilde) operator + * + * Example: returns true for $version: '~2.0' + * + * @param string $version + * @return bool + */ + public function versionFormatIsNextSignificantRelease($version): bool + { + return strpos($version, '~') === 0; + } + + /** + * Check if the passed version information contains equal or higher operator + * + * Example: returns true for $version: '>=2.0' + * + * @param string $version + * @return bool + */ + public function versionFormatIsEqualOrHigher($version): bool + { + return strpos($version, '>=') === 0; + } + + /** + * Check if two releases are compatible by next significant release + * + * ~1.2 is equivalent to >=1.2 <2.0.0 + * ~1.2.3 is equivalent to >=1.2.3 <1.3.0 + * + * In short, allows the last digit specified to go up + * + * @param string $version1 the version string (e.g. '2.0.0' or '1.0') + * @param string $version2 the version string (e.g. '2.0.0' or '1.0') + * @return bool + */ + public function checkNextSignificantReleasesAreCompatible($version1, $version2): bool + { + $version1array = explode('.', $version1); + $version2array = explode('.', $version2); + + if (count($version1array) > count($version2array)) { + [$version1array, $version2array] = [$version2array, $version1array]; + } + + $i = 0; + while ($i < count($version1array) - 1) { + if ($version1array[$i] !== $version2array[$i]) { + return false; + } + $i++; + } + + return true; + } +} diff --git a/system/src/Grav/Common/GPM/Installer.php b/system/src/Grav/Common/GPM/Installer.php new file mode 100644 index 0000000..2987e4a --- /dev/null +++ b/system/src/Grav/Common/GPM/Installer.php @@ -0,0 +1,544 @@ + true, + 'ignore_symlinks' => true, + 'sophisticated' => false, + 'theme' => false, + 'install_path' => '', + 'ignores' => [], + 'exclude_checks' => [self::EXISTS, self::NOT_FOUND, self::IS_LINK] + ]; + + /** + * Installs a given package to a given destination. + * + * @param string $zip the local path to ZIP package + * @param string $destination The local path to the Grav Instance + * @param array $options Options to use for installing. ie, ['install_path' => 'user/themes/antimatter'] + * @param string|null $extracted The local path to the extacted ZIP package + * @param bool $keepExtracted True if you want to keep the original files + * @return bool True if everything went fine, False otherwise. + */ + public static function install($zip, $destination, $options = [], $extracted = null, $keepExtracted = false) + { + $destination = rtrim($destination, DS); + $options = array_merge(self::$options, $options); + $install_path = rtrim($destination . DS . ltrim($options['install_path'], DS), DS); + + if (!self::isGravInstance($destination) || !self::isValidDestination( + $install_path, + $options['exclude_checks'] + ) + ) { + return false; + } + + if ((self::lastErrorCode() === self::IS_LINK && $options['ignore_symlinks']) || + (self::lastErrorCode() === self::EXISTS && !$options['overwrite']) + ) { + return false; + } + + // Create a tmp location + $tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true); + $tmp = $tmp_dir . '/Grav-' . uniqid('', false); + + if (!$extracted) { + $extracted = self::unZip($zip, $tmp); + if (!$extracted) { + Folder::delete($tmp); + return false; + } + } + + if (!file_exists($extracted)) { + self::$error = self::INVALID_SOURCE; + return false; + } + + $is_install = true; + $installer = self::loadInstaller($extracted, $is_install); + + if (isset($options['is_update']) && $options['is_update'] === true) { + $method = 'preUpdate'; + } else { + $method = 'preInstall'; + } + + if ($installer && method_exists($installer, $method)) { + $method_result = $installer::$method(); + if ($method_result !== true) { + self::$error = 'An error occurred'; + if (is_string($method_result)) { + self::$error = $method_result; + } + + return false; + } + } + + if (!$options['sophisticated']) { + $isTheme = $options['theme'] ?? false; + // Make sure that themes are always being copied, even if option was not set! + $isTheme = $isTheme || preg_match('|/themes/[^/]+|ui', $install_path); + if ($isTheme) { + self::copyInstall($extracted, $install_path); + } else { + self::moveInstall($extracted, $install_path); + } + } else { + self::sophisticatedInstall($extracted, $install_path, $options['ignores'], $keepExtracted); + } + + Folder::delete($tmp); + + if (isset($options['is_update']) && $options['is_update'] === true) { + $method = 'postUpdate'; + } else { + $method = 'postInstall'; + } + + self::$message = ''; + if ($installer && method_exists($installer, $method)) { + self::$message = $installer::$method(); + } + + self::$error = self::OK; + + return true; + } + + /** + * Unzip a file to somewhere + * + * @param string $zip_file + * @param string $destination + * @return string|false + */ + public static function unZip($zip_file, $destination) + { + $zip = new ZipArchive(); + $archive = $zip->open($zip_file); + + if ($archive === true) { + Folder::create($destination); + + $unzip = $zip->extractTo($destination); + + + if (!$unzip) { + self::$error = self::ZIP_EXTRACT_ERROR; + Folder::delete($destination); + $zip->close(); + return false; + } + + $package_folder_name = $zip->getNameIndex(0); + if ($package_folder_name === false) { + throw new \RuntimeException('Bad package file: ' . Utils::basename($zip_file)); + } + $package_folder_name = preg_replace('#\./$#', '', $package_folder_name); + $zip->close(); + + return $destination . '/' . $package_folder_name; + } + + self::$error = self::ZIP_EXTRACT_ERROR; + self::$error_zip = $archive; + + return false; + } + + /** + * Instantiates and returns the package installer class + * + * @param string $installer_file_folder The folder path that contains install.php + * @param bool $is_install True if install, false if removal + * @return string|null + */ + private static function loadInstaller($installer_file_folder, $is_install) + { + $installer_file_folder = rtrim($installer_file_folder, DS); + + $install_file = $installer_file_folder . DS . 'install.php'; + + if (!file_exists($install_file)) { + return null; + } + + require_once $install_file; + + if ($is_install) { + $slug = ''; + if (($pos = strpos($installer_file_folder, 'grav-plugin-')) !== false) { + $slug = substr($installer_file_folder, $pos + strlen('grav-plugin-')); + } elseif (($pos = strpos($installer_file_folder, 'grav-theme-')) !== false) { + $slug = substr($installer_file_folder, $pos + strlen('grav-theme-')); + } + } else { + $path_elements = explode('/', $installer_file_folder); + $slug = end($path_elements); + } + + if (!$slug) { + return null; + } + + $class_name = ucfirst($slug) . 'Install'; + + if (class_exists($class_name)) { + return $class_name; + } + + $class_name_alphanumeric = preg_replace('/[^a-zA-Z0-9]+/', '', $class_name) ?? $class_name; + + if (class_exists($class_name_alphanumeric)) { + return $class_name_alphanumeric; + } + + return null; + } + + /** + * @param string $source_path + * @param string $install_path + * @return bool + */ + public static function moveInstall($source_path, $install_path) + { + if (file_exists($install_path)) { + Folder::delete($install_path); + } + + Folder::move($source_path, $install_path); + + return true; + } + + /** + * @param string $source_path + * @param string $install_path + * @return bool + */ + public static function copyInstall($source_path, $install_path) + { + if (empty($source_path)) { + throw new RuntimeException("Directory $source_path is missing"); + } + + Folder::rcopy($source_path, $install_path); + + return true; + } + + /** + * @param string $source_path + * @param string $install_path + * @param array $ignores + * @param bool $keep_source + * @return bool + */ + public static function sophisticatedInstall($source_path, $install_path, $ignores = [], $keep_source = false) + { + foreach (new DirectoryIterator($source_path) as $file) { + if ($file->isLink() || $file->isDot() || in_array($file->getFilename(), $ignores, true)) { + continue; + } + + $path = $install_path . DS . $file->getFilename(); + + if ($file->isDir()) { + Folder::delete($path); + if ($keep_source) { + Folder::copy($file->getPathname(), $path); + } else { + Folder::move($file->getPathname(), $path); + } + + if ($file->getFilename() === 'bin') { + $glob = glob($path . DS . '*') ?: []; + foreach ($glob as $bin_file) { + @chmod($bin_file, 0755); + } + } + } else { + @unlink($path); + @copy($file->getPathname(), $path); + } + } + + return true; + } + + /** + * Uninstalls one or more given package + * + * @param string $path The slug of the package(s) + * @param array $options Options to use for uninstalling + * @return bool True if everything went fine, False otherwise. + */ + public static function uninstall($path, $options = []) + { + $options = array_merge(self::$options, $options); + if (!self::isValidDestination($path, $options['exclude_checks']) + ) { + return false; + } + + $installer_file_folder = $path; + $is_install = false; + $installer = self::loadInstaller($installer_file_folder, $is_install); + + if ($installer && method_exists($installer, 'preUninstall')) { + $method_result = $installer::preUninstall(); + if ($method_result !== true) { + self::$error = 'An error occurred'; + if (is_string($method_result)) { + self::$error = $method_result; + } + + return false; + } + } + + $result = Folder::delete($path); + + self::$message = ''; + if ($result && $installer && method_exists($installer, 'postUninstall')) { + self::$message = $installer::postUninstall(); + } + + return $result; + } + + /** + * Runs a set of checks on the destination and sets the Error if any + * + * @param string $destination The directory to run validations at + * @param array $exclude An array of constants to exclude from the validation + * @return bool True if validation passed. False otherwise + */ + public static function isValidDestination($destination, $exclude = []) + { + self::$error = 0; + self::$target = $destination; + + if (is_link($destination)) { + self::$error = self::IS_LINK; + } elseif (file_exists($destination)) { + self::$error = self::EXISTS; + } elseif (!file_exists($destination)) { + self::$error = self::NOT_FOUND; + } elseif (!is_dir($destination)) { + self::$error = self::NOT_DIRECTORY; + } + + if (count($exclude) && in_array(self::$error, $exclude, true)) { + return true; + } + + return !self::$error; + } + + /** + * Validates if the given path is a Grav Instance + * + * @param string $target The local path to the Grav Instance + * @return bool True if is a Grav Instance. False otherwise + */ + public static function isGravInstance($target) + { + self::$error = 0; + self::$target = $target; + + if (!file_exists($target . DS . 'index.php') || + !file_exists($target . DS . 'bin') || + !file_exists($target . DS . 'user') || + !file_exists($target . DS . 'system' . DS . 'config' . DS . 'system.yaml') + ) { + self::$error = self::NOT_GRAV_ROOT; + } + + return !self::$error; + } + + /** + * Returns the last message added by the installer + * + * @return string The message + */ + public static function getMessage() + { + return self::$message; + } + + /** + * Returns the last error occurred in a string message format + * + * @return string The message of the last error + */ + public static function lastErrorMsg() + { + if (is_string(self::$error)) { + return self::$error; + } + + switch (self::$error) { + case 0: + $msg = 'No Error'; + break; + + case self::EXISTS: + $msg = 'The target path "' . self::$target . '" already exists'; + break; + + case self::IS_LINK: + $msg = 'The target path "' . self::$target . '" is a symbolic link'; + break; + + case self::NOT_FOUND: + $msg = 'The target path "' . self::$target . '" does not appear to exist'; + break; + + case self::NOT_DIRECTORY: + $msg = 'The target path "' . self::$target . '" does not appear to be a folder'; + break; + + case self::NOT_GRAV_ROOT: + $msg = 'The target path "' . self::$target . '" does not appear to be a Grav instance'; + break; + + case self::ZIP_OPEN_ERROR: + $msg = 'Unable to open the package file'; + break; + + case self::ZIP_EXTRACT_ERROR: + $msg = 'Unable to extract the package. '; + if (self::$error_zip) { + switch (self::$error_zip) { + case ZipArchive::ER_EXISTS: + $msg .= 'File already exists.'; + break; + + case ZipArchive::ER_INCONS: + $msg .= 'Zip archive inconsistent.'; + break; + + case ZipArchive::ER_MEMORY: + $msg .= 'Memory allocation failure.'; + break; + + case ZipArchive::ER_NOENT: + $msg .= 'No such file.'; + break; + + case ZipArchive::ER_NOZIP: + $msg .= 'Not a zip archive.'; + break; + + case ZipArchive::ER_OPEN: + $msg .= "Can't open file."; + break; + + case ZipArchive::ER_READ: + $msg .= 'Read error.'; + break; + + case ZipArchive::ER_SEEK: + $msg .= 'Seek error.'; + break; + } + } + break; + + case self::INVALID_SOURCE: + $msg = 'Invalid source file'; + break; + + default: + $msg = 'Unknown Error'; + break; + } + + return $msg; + } + + /** + * Returns the last error code of the occurred error + * + * @return int|string The code of the last error + */ + public static function lastErrorCode() + { + return self::$error; + } + + /** + * Allows to manually set an error + * + * @param int|string $error the Error code + * @return void + */ + public static function setError($error) + { + self::$error = $error; + } +} diff --git a/system/src/Grav/Common/GPM/Licenses.php b/system/src/Grav/Common/GPM/Licenses.php new file mode 100644 index 0000000..6f2cca9 --- /dev/null +++ b/system/src/Grav/Common/GPM/Licenses.php @@ -0,0 +1,116 @@ +content(); + $slug = strtolower($slug); + + if ($license && !self::validate($license)) { + return false; + } + + if (!is_string($license)) { + if (isset($data['licenses'][$slug])) { + unset($data['licenses'][$slug]); + } else { + return false; + } + } else { + $data['licenses'][$slug] = $license; + } + + $licenses->save($data); + $licenses->free(); + + return true; + } + + /** + * Returns the license for a Premium package + * + * @param string|null $slug + * @return string[]|string + */ + public static function get($slug = null) + { + $licenses = self::getLicenseFile(); + $data = (array)$licenses->content(); + $licenses->free(); + + if (null === $slug) { + return $data['licenses'] ?? []; + } + + $slug = strtolower($slug); + + return $data['licenses'][$slug] ?? ''; + } + + + /** + * Validates the License format + * + * @param string|null $license + * @return bool + */ + public static function validate($license = null) + { + if (!is_string($license)) { + return false; + } + + return (bool)preg_match('#' . self::$regex. '#', $license); + } + + /** + * Get the License File object + * + * @return FileInterface + */ + public static function getLicenseFile() + { + if (!isset(self::$file)) { + $path = Grav::instance()['locator']->findResource('user-data://') . '/licenses.yaml'; + if (!file_exists($path)) { + touch($path); + } + self::$file = CompiledYamlFile::instance($path); + } + + return self::$file; + } +} diff --git a/system/src/Grav/Common/GPM/Local/AbstractPackageCollection.php b/system/src/Grav/Common/GPM/Local/AbstractPackageCollection.php new file mode 100644 index 0000000..d5967c0 --- /dev/null +++ b/system/src/Grav/Common/GPM/Local/AbstractPackageCollection.php @@ -0,0 +1,34 @@ + $data) { + $data->set('slug', $name); + $this->items[$name] = new Package($data, $this->type); + } + } +} diff --git a/system/src/Grav/Common/GPM/Local/Package.php b/system/src/Grav/Common/GPM/Local/Package.php new file mode 100644 index 0000000..53b249a --- /dev/null +++ b/system/src/Grav/Common/GPM/Local/Package.php @@ -0,0 +1,51 @@ +blueprints()->toArray()); + parent::__construct($data, $package_type); + + $this->settings = $package->toArray(); + + $html_description = Parsedown::instance()->line($this->__get('description')); + $this->data->set('slug', $package->__get('slug')); + $this->data->set('description_html', $html_description); + $this->data->set('description_plain', strip_tags($html_description)); + $this->data->set('symlink', is_link(USER_DIR . $package_type . DS . $this->__get('slug'))); + } + + /** + * @return bool + */ + public function isEnabled() + { + return (bool)$this->settings['enabled']; + } +} diff --git a/system/src/Grav/Common/GPM/Local/Packages.php b/system/src/Grav/Common/GPM/Local/Packages.php new file mode 100644 index 0000000..fb68977 --- /dev/null +++ b/system/src/Grav/Common/GPM/Local/Packages.php @@ -0,0 +1,29 @@ + new Plugins(), + 'themes' => new Themes() + ]; + + parent::__construct($items); + } +} diff --git a/system/src/Grav/Common/GPM/Local/Plugins.php b/system/src/Grav/Common/GPM/Local/Plugins.php new file mode 100644 index 0000000..3fa7bbd --- /dev/null +++ b/system/src/Grav/Common/GPM/Local/Plugins.php @@ -0,0 +1,33 @@ +all()); + } +} diff --git a/system/src/Grav/Common/GPM/Local/Themes.php b/system/src/Grav/Common/GPM/Local/Themes.php new file mode 100644 index 0000000..7c056a7 --- /dev/null +++ b/system/src/Grav/Common/GPM/Local/Themes.php @@ -0,0 +1,33 @@ +all()); + } +} diff --git a/system/src/Grav/Common/GPM/Remote/AbstractPackageCollection.php b/system/src/Grav/Common/GPM/Remote/AbstractPackageCollection.php new file mode 100644 index 0000000..077fcd2 --- /dev/null +++ b/system/src/Grav/Common/GPM/Remote/AbstractPackageCollection.php @@ -0,0 +1,81 @@ +get('system.gpm.releases', 'stable'); + $cache_dir = Grav::instance()['locator']->findResource('cache://gpm', true, true); + $this->cache = new FilesystemCache($cache_dir); + + $this->repository = $repository . '?v=' . GRAV_VERSION . '&' . $channel . '=1'; + $this->raw = $this->cache->fetch(md5($this->repository)); + + $this->fetch($refresh, $callback); + foreach (json_decode($this->raw, true) as $slug => $data) { + // Temporarily fix for using multi-sites + if (isset($data['install_path'])) { + $path = preg_replace('~^user/~i', 'user://', $data['install_path']); + $data['install_path'] = Grav::instance()['locator']->findResource($path, false, true); + } + $this->items[$slug] = new Package($data, $this->type); + } + } + + /** + * @param bool $refresh + * @param callable|null $callback + * @return string + */ + public function fetch($refresh = false, $callback = null) + { + if (!$this->raw || $refresh) { + $response = Response::get($this->repository, [], $callback); + $this->raw = $response; + $this->cache->save(md5($this->repository), $this->raw, $this->lifetime); + } + + return $this->raw; + } +} diff --git a/system/src/Grav/Common/GPM/Remote/GravCore.php b/system/src/Grav/Common/GPM/Remote/GravCore.php new file mode 100644 index 0000000..d97eb83 --- /dev/null +++ b/system/src/Grav/Common/GPM/Remote/GravCore.php @@ -0,0 +1,151 @@ +get('system.gpm.releases', 'stable'); + $cache_dir = Grav::instance()['locator']->findResource('cache://gpm', true, true); + $this->cache = new FilesystemCache($cache_dir); + $this->repository .= '?v=' . GRAV_VERSION . '&' . $channel . '=1'; + $this->raw = $this->cache->fetch(md5($this->repository)); + + $this->fetch($refresh, $callback); + + $this->data = json_decode($this->raw, true); + $this->version = $this->data['version'] ?? '-'; + $this->date = $this->data['date'] ?? '-'; + $this->min_php = $this->data['min_php'] ?? null; + + if (isset($this->data['assets'])) { + foreach ((array)$this->data['assets'] as $slug => $data) { + $this->items[$slug] = new Package($data); + } + } + } + + /** + * Returns the list of assets associated to the latest version of Grav + * + * @return array list of assets + */ + public function getAssets() + { + return $this->data['assets']; + } + + /** + * Returns the changelog list for each version of Grav + * + * @param string|null $diff the version number to start the diff from + * @return array changelog list for each version + */ + public function getChangelog($diff = null) + { + if (!$diff) { + return $this->data['changelog']; + } + + $diffLog = []; + foreach ((array)$this->data['changelog'] as $version => $changelog) { + preg_match("/[\w\-\.]+/", $version, $cleanVersion); + + if (!$cleanVersion || version_compare($diff, $cleanVersion[0], '>=')) { + continue; + } + + $diffLog[$version] = $changelog; + } + + return $diffLog; + } + + /** + * Return the release date of the latest Grav + * + * @return string + */ + public function getDate() + { + return $this->date; + } + + /** + * Determine if this version of Grav is eligible to be updated + * + * @return mixed + */ + public function isUpdatable() + { + return version_compare(GRAV_VERSION, $this->getVersion(), '<'); + } + + /** + * Returns the latest version of Grav available remotely + * + * @return string + */ + public function getVersion() + { + return $this->version; + } + + /** + * Returns the minimum PHP version + * + * @return string + */ + public function getMinPHPVersion() + { + // If non min set, assume current PHP version + if (null === $this->min_php) { + $this->min_php = PHP_VERSION; + } + + return $this->min_php; + } + + /** + * Is this installation symlinked? + * + * @return bool + */ + public function isSymlink() + { + return is_link(GRAV_ROOT . DS . 'index.php'); + } +} diff --git a/system/src/Grav/Common/GPM/Remote/Package.php b/system/src/Grav/Common/GPM/Remote/Package.php new file mode 100644 index 0000000..bf839b0 --- /dev/null +++ b/system/src/Grav/Common/GPM/Remote/Package.php @@ -0,0 +1,66 @@ +data->toArray(); + } + + /** + * Returns the changelog list for each version of a package + * + * @param string|null $diff the version number to start the diff from + * @return array changelog list for each version + */ + public function getChangelog($diff = null) + { + if (!$diff) { + return $this->data['changelog']; + } + + $diffLog = []; + foreach ((array)$this->data['changelog'] as $version => $changelog) { + preg_match("/[\w\-.]+/", $version, $cleanVersion); + + if (!$cleanVersion || version_compare($diff, $cleanVersion[0], '>=')) { + continue; + } + + $diffLog[$version] = $changelog; + } + + return $diffLog; + } +} diff --git a/system/src/Grav/Common/GPM/Remote/Packages.php b/system/src/Grav/Common/GPM/Remote/Packages.php new file mode 100644 index 0000000..e7457e1 --- /dev/null +++ b/system/src/Grav/Common/GPM/Remote/Packages.php @@ -0,0 +1,34 @@ + new Plugins($refresh, $callback), + 'themes' => new Themes($refresh, $callback) + ]; + + parent::__construct($items); + } +} diff --git a/system/src/Grav/Common/GPM/Remote/Plugins.php b/system/src/Grav/Common/GPM/Remote/Plugins.php new file mode 100644 index 0000000..4d30af9 --- /dev/null +++ b/system/src/Grav/Common/GPM/Remote/Plugins.php @@ -0,0 +1,32 @@ +repository, $refresh, $callback); + } +} diff --git a/system/src/Grav/Common/GPM/Remote/Themes.php b/system/src/Grav/Common/GPM/Remote/Themes.php new file mode 100644 index 0000000..d386e1e --- /dev/null +++ b/system/src/Grav/Common/GPM/Remote/Themes.php @@ -0,0 +1,32 @@ +repository, $refresh, $callback); + } +} diff --git a/system/src/Grav/Common/GPM/Response.php b/system/src/Grav/Common/GPM/Response.php new file mode 100644 index 0000000..98654b6 --- /dev/null +++ b/system/src/Grav/Common/GPM/Response.php @@ -0,0 +1,3 @@ +remote = new Remote\GravCore($refresh, $callback); + } + + /** + * Returns the release date of the latest version of Grav + * + * @return string + */ + public function getReleaseDate() + { + return $this->remote->getDate(); + } + + /** + * Returns the version of the installed Grav + * + * @return string + */ + public function getLocalVersion() + { + return GRAV_VERSION; + } + + /** + * Returns the version of the remotely available Grav + * + * @return string + */ + public function getRemoteVersion() + { + return $this->remote->getVersion(); + } + + /** + * Returns an array of assets available to download remotely + * + * @return array + */ + public function getAssets() + { + return $this->remote->getAssets(); + } + + /** + * Returns the changelog list for each version of Grav + * + * @param string|null $diff the version number to start the diff from + * @return array return the changelog list for each version + */ + public function getChangelog($diff = null) + { + return $this->remote->getChangelog($diff); + } + + /** + * Make sure this meets minimum PHP requirements + * + * @return bool + */ + public function meetsRequirements() + { + if (version_compare(PHP_VERSION, $this->minPHPVersion(), '<')) { + return false; + } + + return true; + } + + /** + * Get minimum PHP version from remote + * + * @return string + */ + public function minPHPVersion() + { + if (null === $this->min_php) { + $this->min_php = $this->remote->getMinPHPVersion(); + } + + return $this->min_php; + } + + /** + * Checks if the currently installed Grav is upgradable to a newer version + * + * @return bool True if it's upgradable, False otherwise. + */ + public function isUpgradable() + { + return version_compare($this->getLocalVersion(), $this->getRemoteVersion(), '<'); + } + + /** + * Checks if Grav is currently symbolically linked + * + * @return bool True if Grav is symlinked, False otherwise. + */ + public function isSymlink() + { + return $this->remote->isSymlink(); + } +} diff --git a/system/src/Grav/Common/Getters.php b/system/src/Grav/Common/Getters.php new file mode 100644 index 0000000..aca39bc --- /dev/null +++ b/system/src/Grav/Common/Getters.php @@ -0,0 +1,170 @@ +offsetSet($offset, $value); + } + + /** + * Magic getter method + * + * @param int|string $offset Medium name value + * @return mixed Medium value + */ + #[\ReturnTypeWillChange] + public function __get($offset) + { + return $this->offsetGet($offset); + } + + /** + * Magic method to determine if the attribute is set + * + * @param int|string $offset Medium name value + * @return boolean True if the value is set + */ + #[\ReturnTypeWillChange] + public function __isset($offset) + { + return $this->offsetExists($offset); + } + + /** + * Magic method to unset the attribute + * + * @param int|string $offset The name value to unset + */ + #[\ReturnTypeWillChange] + public function __unset($offset) + { + $this->offsetUnset($offset); + } + + /** + * @param int|string $offset + * @return bool + */ + #[\ReturnTypeWillChange] + public function offsetExists($offset) + { + if ($this->gettersVariable) { + $var = $this->gettersVariable; + + return isset($this->{$var}[$offset]); + } + + return isset($this->{$offset}); + } + + /** + * @param int|string $offset + * @return mixed + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + if ($this->gettersVariable) { + $var = $this->gettersVariable; + + return $this->{$var}[$offset] ?? null; + } + + return $this->{$offset} ?? null; + } + + /** + * @param int|string $offset + * @param mixed $value + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + if ($this->gettersVariable) { + $var = $this->gettersVariable; + $this->{$var}[$offset] = $value; + } else { + $this->{$offset} = $value; + } + } + + /** + * @param int|string $offset + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + if ($this->gettersVariable) { + $var = $this->gettersVariable; + unset($this->{$var}[$offset]); + } else { + unset($this->{$offset}); + } + } + + /** + * @return int + */ + #[\ReturnTypeWillChange] + public function count() + { + if ($this->gettersVariable) { + $var = $this->gettersVariable; + return count($this->{$var}); + } + + return count($this->toArray()); + } + + /** + * Returns an associative array of object properties. + * + * @return array + */ + public function toArray() + { + if ($this->gettersVariable) { + $var = $this->gettersVariable; + + return $this->{$var}; + } + + $properties = (array)$this; + $list = []; + foreach ($properties as $property => $value) { + if ($property[0] !== "\0") { + $list[$property] = $value; + } + } + + return $list; + } +} diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php new file mode 100644 index 0000000..5f879ca --- /dev/null +++ b/system/src/Grav/Common/Grav.php @@ -0,0 +1,829 @@ + Browser::class, + 'cache' => Cache::class, + 'events' => EventDispatcher::class, + 'exif' => Exif::class, + 'plugins' => Plugins::class, + 'scheduler' => Scheduler::class, + 'taxonomy' => Taxonomy::class, + 'themes' => Themes::class, + 'twig' => Twig::class, + 'uri' => Uri::class, + ]; + + /** + * @var array All middleware processors that are processed in $this->process() + */ + protected $middleware = [ + 'multipartRequestSupport', + 'initializeProcessor', + 'pluginsProcessor', + 'themesProcessor', + 'requestProcessor', + 'tasksProcessor', + 'backupsProcessor', + 'schedulerProcessor', + 'assetsProcessor', + 'twigProcessor', + 'pagesProcessor', + 'debuggerAssetsProcessor', + 'renderProcessor', + ]; + + /** @var array */ + protected $initialized = []; + + /** + * Reset the Grav instance. + * + * @return void + */ + public static function resetInstance(): void + { + if (self::$instance) { + // @phpstan-ignore-next-line + self::$instance = null; + } + } + + /** + * Return the Grav instance. Create it if it's not already instanced + * + * @param array $values + * @return Grav + */ + public static function instance(array $values = []) + { + if (null === self::$instance) { + self::$instance = static::load($values); + + /** @var ClassLoader|null $loader */ + $loader = self::$instance['loader'] ?? null; + if ($loader) { + // Load fix for Deferred Twig Extension + $loader->addPsr4('Phive\\Twig\\Extensions\\Deferred\\', LIB_DIR . 'Phive/Twig/Extensions/Deferred/', true); + } + } elseif ($values) { + $instance = self::$instance; + foreach ($values as $key => $value) { + $instance->offsetSet($key, $value); + } + } + + return self::$instance; + } + + /** + * Get Grav version. + * + * @return string + */ + public function getVersion(): string + { + return GRAV_VERSION; + } + + /** + * @return bool + */ + public function isSetup(): bool + { + return isset($this->initialized['setup']); + } + + /** + * Setup Grav instance using specific environment. + * + * @param string|null $environment + * @return $this + */ + public function setup(string $environment = null) + { + if (isset($this->initialized['setup'])) { + return $this; + } + + $this->initialized['setup'] = true; + + // Force environment if passed to the method. + if ($environment) { + Setup::$environment = $environment; + } + + // Initialize setup and streams. + $this['setup']; + $this['streams']; + + return $this; + } + + /** + * Initialize CLI environment. + * + * Call after `$grav->setup($environment)` + * + * - Load configuration + * - Initialize logger + * - Disable debugger + * - Set timezone, locale + * - Load plugins (call PluginsLoadedEvent) + * - Set Pages and Users type to be used in the site + * + * This method WILL NOT initialize assets, twig or pages. + * + * @return $this + */ + public function initializeCli() + { + InitializeProcessor::initializeCli($this); + + return $this; + } + + /** + * Process a request + * + * @return void + */ + public function process(): void + { + if (isset($this->initialized['process'])) { + return; + } + + // Initialize Grav if needed. + $this->setup(); + + $this->initialized['process'] = true; + + $container = new Container( + [ + 'multipartRequestSupport' => function () { + return new MultipartRequestSupport(); + }, + 'initializeProcessor' => function () { + return new InitializeProcessor($this); + }, + 'backupsProcessor' => function () { + return new BackupsProcessor($this); + }, + 'pluginsProcessor' => function () { + return new PluginsProcessor($this); + }, + 'themesProcessor' => function () { + return new ThemesProcessor($this); + }, + 'schedulerProcessor' => function () { + return new SchedulerProcessor($this); + }, + 'requestProcessor' => function () { + return new RequestProcessor($this); + }, + 'tasksProcessor' => function () { + return new TasksProcessor($this); + }, + 'assetsProcessor' => function () { + return new AssetsProcessor($this); + }, + 'twigProcessor' => function () { + return new TwigProcessor($this); + }, + 'pagesProcessor' => function () { + return new PagesProcessor($this); + }, + 'debuggerAssetsProcessor' => function () { + return new DebuggerAssetsProcessor($this); + }, + 'renderProcessor' => function () { + return new RenderProcessor($this); + }, + ] + ); + + $default = static function () { + return new Response(404, ['Expires' => 0, 'Cache-Control' => 'no-store, max-age=0'], 'Not Found'); + }; + + $collection = new RequestHandler($this->middleware, $default, $container); + + $response = $collection->handle($this['request']); + $body = $response->getBody(); + + /** @var Messages $messages */ + $messages = $this['messages']; + + // Prevent caching if session messages were displayed in the page. + $noCache = $messages->isCleared(); + if ($noCache) { + $response = $response->withHeader('Cache-Control', 'no-store, max-age=0'); + } + + // Handle ETag and If-None-Match headers. + if ($response->getHeaderLine('ETag') === '1') { + $etag = md5($body); + $response = $response->withHeader('ETag', '"' . $etag . '"'); + + $search = trim($this['request']->getHeaderLine('If-None-Match'), '"'); + if ($noCache === false && $search === $etag) { + $response = $response->withStatus(304); + $body = ''; + } + } + + // Echo page content. + $this->header($response); + echo $body; + + $this['debugger']->render(); + + // Response object can turn off all shutdown processing. This can be used for example to speed up AJAX responses. + // Note that using this feature will also turn off response compression. + if ($response->getHeaderLine('Grav-Internal-SkipShutdown') !== '1') { + register_shutdown_function([$this, 'shutdown']); + } + } + + /** + * Clean any output buffers. Useful when exiting from the application. + * + * Please use $grav->close() and $grav->redirect() instead of calling this one! + * + * @return void + */ + public function cleanOutputBuffers(): void + { + // Make sure nothing extra gets written to the response. + while (ob_get_level()) { + ob_end_clean(); + } + // Work around PHP bug #8218 (8.0.17 & 8.1.4). + header_remove('Content-Encoding'); + } + + /** + * Terminates Grav request with a response. + * + * Please use this method instead of calling `die();` or `exit();`. Note that you need to create a response object. + * + * @param ResponseInterface $response + * @return never-return + */ + public function close(ResponseInterface $response): void + { + $this->cleanOutputBuffers(); + + // Close the session. + if (isset($this['session'])) { + $this['session']->close(); + } + + /** @var ServerRequestInterface $request */ + $request = $this['request']; + + /** @var Debugger $debugger */ + $debugger = $this['debugger']; + $response = $debugger->logRequest($request, $response); + + $body = $response->getBody(); + + /** @var Messages $messages */ + $messages = $this['messages']; + + // Prevent caching if session messages were displayed in the page. + $noCache = $messages->isCleared(); + if ($noCache) { + $response = $response->withHeader('Cache-Control', 'no-store, max-age=0'); + } + + // Handle ETag and If-None-Match headers. + if ($response->getHeaderLine('ETag') === '1') { + $etag = md5($body); + $response = $response->withHeader('ETag', '"' . $etag . '"'); + + $search = trim($this['request']->getHeaderLine('If-None-Match'), '"'); + if ($noCache === false && $search === $etag) { + $response = $response->withStatus(304); + $body = ''; + } + } + + // Echo page content. + $this->header($response); + echo $body; + exit(); + } + + /** + * @param ResponseInterface $response + * @return never-return + * @deprecated 1.7 Use $grav->close() instead. + */ + public function exit(ResponseInterface $response): void + { + $this->close($response); + } + + /** + * Terminates Grav request and redirects browser to another location. + * + * Please use this method instead of calling `header("Location: {$url}", true, 302); exit();`. + * + * @param Route|string $route Internal route. + * @param int|null $code Redirection code (30x) + * @return never-return + */ + public function redirect($route, $code = null): void + { + $response = $this->getRedirectResponse($route, $code); + + $this->close($response); + } + + /** + * Returns redirect response object from Grav. + * + * @param Route|string $route Internal route. + * @param int|null $code Redirection code (30x) + * @return ResponseInterface + */ + public function getRedirectResponse($route, $code = null): ResponseInterface + { + /** @var Uri $uri */ + $uri = $this['uri']; + + if (is_string($route)) { + // Clean route for redirect + $route = preg_replace("#^\/[\\\/]+\/#", '/', $route); + + if (null === $code) { + // Check for redirect code in the route: e.g. /new/[301], /new[301]/route or /new[301].html + $regex = '/.*(\[(30[1-7])\])(.\w+|\/.*?)?$/'; + preg_match($regex, $route, $matches); + if ($matches) { + $route = str_replace($matches[1], '', $matches[0]); + $code = $matches[2]; + } + } + + if ($uri::isExternal($route)) { + $url = $route; + } else { + $url = rtrim($uri->rootUrl(), '/') . '/'; + + if ($this['config']->get('system.pages.redirect_trailing_slash', true)) { + $url .= trim($route, '/'); // Remove trailing slash + } else { + $url .= ltrim($route, '/'); // Support trailing slash default routes + } + } + } elseif ($route instanceof Route) { + $url = $route->toString(true); + } else { + throw new InvalidArgumentException('Bad $route'); + } + + if ($code < 300 || $code > 399) { + $code = null; + } + + if ($code === null) { + $code = $this['config']->get('system.pages.redirect_default_code', 302); + } + + if ($uri->extension() === 'json') { + return new Response(200, ['Content-Type' => 'application/json'], json_encode(['code' => $code, 'redirect' => $url], JSON_THROW_ON_ERROR)); + } + + return new Response($code, ['Location' => $url]); + } + + /** + * Redirect browser to another location taking language into account (preferred) + * + * @param string $route Internal route. + * @param int $code Redirection code (30x) + * @return void + */ + public function redirectLangSafe($route, $code = null): void + { + if (!$this['uri']->isExternal($route)) { + $this->redirect($this['pages']->route($route), $code); + } else { + $this->redirect($route, $code); + } + } + + /** + * Set response header. + * + * @param ResponseInterface|null $response + * @return void + */ + public function header(ResponseInterface $response = null): void + { + if (null === $response) { + /** @var PageInterface $page */ + $page = $this['page']; + $response = new Response($page->httpResponseCode(), $page->httpHeaders(), ''); + } + + header("HTTP/{$response->getProtocolVersion()} {$response->getStatusCode()} {$response->getReasonPhrase()}"); + foreach ($response->getHeaders() as $key => $values) { + // Skip internal Grav headers. + if (strpos($key, 'Grav-Internal-') === 0) { + continue; + } + foreach ($values as $i => $value) { + header($key . ': ' . $value, $i === 0); + } + } + } + + /** + * Set the system locale based on the language and configuration + * + * @return void + */ + public function setLocale(): void + { + // Initialize Locale if set and configured. + if ($this['language']->enabled() && $this['config']->get('system.languages.override_locale')) { + $language = $this['language']->getLanguage(); + setlocale(LC_ALL, strlen($language) < 3 ? ($language . '_' . strtoupper($language)) : $language); + } elseif ($this['config']->get('system.default_locale')) { + setlocale(LC_ALL, $this['config']->get('system.default_locale')); + } + } + + /** + * @param object $event + * @return object + */ + public function dispatchEvent($event) + { + /** @var EventDispatcherInterface $events */ + $events = $this['events']; + $eventName = get_class($event); + + $timestamp = microtime(true); + $event = $events->dispatch($event); + + /** @var Debugger $debugger */ + $debugger = $this['debugger']; + $debugger->addEvent($eventName, $event, $events, $timestamp); + + return $event; + } + + /** + * Fires an event with optional parameters. + * + * @param string $eventName + * @param Event|null $event + * @return Event + */ + public function fireEvent($eventName, Event $event = null) + { + /** @var EventDispatcherInterface $events */ + $events = $this['events']; + if (null === $event) { + $event = new Event(); + } + + $timestamp = microtime(true); + $events->dispatch($event, $eventName); + + /** @var Debugger $debugger */ + $debugger = $this['debugger']; + $debugger->addEvent($eventName, $event, $events, $timestamp); + + return $event; + } + + /** + * Set the final content length for the page and flush the buffer + * + * @return void + */ + public function shutdown(): void + { + // Prevent user abort allowing onShutdown event to run without interruptions. + if (function_exists('ignore_user_abort')) { + @ignore_user_abort(true); + } + + // Close the session allowing new requests to be handled. + if (isset($this['session'])) { + $this['session']->close(); + } + + /** @var Config $config */ + $config = $this['config']; + if ($config->get('system.debugger.shutdown.close_connection', true)) { + // Flush the response and close the connection to allow time consuming tasks to be performed without leaving + // the connection to the client open. This will make page loads to feel much faster. + + // FastCGI allows us to flush all response data to the client and finish the request. + $success = function_exists('fastcgi_finish_request') ? @fastcgi_finish_request() : false; + if (!$success) { + // Unfortunately without FastCGI there is no way to force close the connection. + // We need to ask browser to close the connection for us. + + if ($config->get('system.cache.gzip')) { + // Flush gzhandler buffer if gzip setting was enabled to get the size of the compressed output. + ob_end_flush(); + } elseif ($config->get('system.cache.allow_webserver_gzip')) { + // Let web server to do the hard work. + header('Content-Encoding: identity'); + } elseif (function_exists('apache_setenv')) { + // Without gzip we have no other choice than to prevent server from compressing the output. + // This action turns off mod_deflate which would prevent us from closing the connection. + @apache_setenv('no-gzip', '1'); + } else { + // Fall back to unknown content encoding, it prevents most servers from deflating the content. + header('Content-Encoding: none'); + } + + // Get length and close the connection. + header('Content-Length: ' . ob_get_length()); + header('Connection: close'); + + ob_end_flush(); + @ob_flush(); + flush(); + } + } + + // Run any time consuming tasks. + $this->fireEvent('onShutdown'); + } + + /** + * Magic Catch All Function + * + * Used to call closures. + * + * Source: http://stackoverflow.com/questions/419804/closures-as-class-members + * + * @param string $method + * @param array $args + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function __call($method, $args) + { + $closure = $this->{$method} ?? null; + + return is_callable($closure) ? $closure(...$args) : null; + } + + /** + * Measure how long it takes to do an action. + * + * @param string $timerId + * @param string $timerTitle + * @param callable $callback + * @return mixed Returns value returned by the callable. + */ + public function measureTime(string $timerId, string $timerTitle, callable $callback) + { + $debugger = $this['debugger']; + $debugger->startTimer($timerId, $timerTitle); + $result = $callback(); + $debugger->stopTimer($timerId); + + return $result; + } + + /** + * Initialize and return a Grav instance + * + * @param array $values + * @return static + */ + protected static function load(array $values) + { + $container = new static($values); + + $container['debugger'] = new Debugger(); + $container['grav'] = function (Container $container) { + user_error('Calling $grav[\'grav\'] or {{ grav.grav }} is deprecated since Grav 1.6, just use $grav or {{ grav }}', E_USER_DEPRECATED); + + return $container; + }; + + $container->registerServices(); + + return $container; + } + + /** + * Register all services + * Services are defined in the diMap. They can either only the class + * of a Service Provider or a pair of serviceKey => serviceClass that + * gets directly mapped into the container. + * + * @return void + */ + protected function registerServices(): void + { + foreach (self::$diMap as $serviceKey => $serviceClass) { + if (is_int($serviceKey)) { + $this->register(new $serviceClass); + } else { + $this[$serviceKey] = function ($c) use ($serviceClass) { + return new $serviceClass($c); + }; + } + } + } + + /** + * This attempts to find media, other files, and download them + * + * @param string $path + * @return PageInterface|false + */ + public function fallbackUrl($path) + { + $path_parts = Utils::pathinfo($path); + if (!is_array($path_parts)) { + return false; + } + + /** @var Uri $uri */ + $uri = $this['uri']; + + /** @var Config $config */ + $config = $this['config']; + + /** @var Pages $pages */ + $pages = $this['pages']; + $page = $pages->find($path_parts['dirname'], true); + + $uri_extension = strtolower($uri->extension() ?? ''); + $fallback_types = $config->get('system.media.allowed_fallback_types'); + $supported_types = $config->get('media.types'); + + $parsed_url = parse_url(rawurldecode($uri->basename())); + $media_file = $parsed_url['path']; + + $event = new Event([ + 'uri' => $uri, + 'page' => &$page, + 'filename' => &$media_file, + 'extension' => $uri_extension, + 'allowed_fallback_types' => &$fallback_types, + 'media_types' => &$supported_types + ]); + + $this->fireEvent('onPageFallBackUrl', $event); + + // Check whitelist first, then ensure extension is a valid media type + if (!empty($fallback_types) && !in_array($uri_extension, $fallback_types, true)) { + return false; + } + if (!array_key_exists($uri_extension, $supported_types)) { + return false; + } + + if ($page) { + $media = $page->media()->all(); + + // if this is a media object, try actions first + if (isset($media[$media_file])) { + /** @var Medium $medium */ + $medium = $media[$media_file]; + foreach ($uri->query(null, true) as $action => $params) { + if (in_array($action, ImageMedium::$magic_actions, true)) { + call_user_func_array([&$medium, $action], explode(',', $params)); + } + } + Utils::download($medium->path(), false); + } + + // unsupported media type, try to download it... + if ($uri_extension) { + $extension = $uri_extension; + } elseif (isset($path_parts['extension'])) { + $extension = $path_parts['extension']; + } else { + $extension = null; + } + + if ($extension) { + $download = true; + if (in_array(ltrim($extension, '.'), $config->get('system.media.unsupported_inline_types', []), true)) { + $download = false; + } + Utils::download($page->path() . DIRECTORY_SEPARATOR . $uri->basename(), $download); + } + } + + // Nothing found + return false; + } +} diff --git a/system/src/Grav/Common/GravTrait.php b/system/src/Grav/Common/GravTrait.php new file mode 100644 index 0000000..76dacba --- /dev/null +++ b/system/src/Grav/Common/GravTrait.php @@ -0,0 +1,34 @@ + 'Grav CMS' + ]; + + public static function getClient(array $overrides = [], int $connections = 6, callable $callback = null): HttpClientInterface + { + $config = Grav::instance()['config']; + $options = static::getOptions(); + + // Use callback if provided + if ($callback) { + self::$callback = $callback; + $options->setOnProgress([Client::class, 'progress']); + } + + $settings = array_merge($options->toArray(), $overrides); + $preferred_method = $config->get('system.http.method'); + // Try old GPM setting if value is the same as system default + if ($preferred_method === 'auto') { + $preferred_method = $config->get('system.gpm.method', 'auto'); + } + + switch ($preferred_method) { + case 'curl': + $client = new CurlHttpClient($settings, $connections); + break; + case 'fopen': + case 'native': + $client = new NativeHttpClient($settings, $connections); + break; + default: + $client = HttpClient::create($settings, $connections); + } + + return $client; + } + + /** + * Get HTTP Options + * + * @return HttpOptions + */ + public static function getOptions(): HttpOptions + { + $config = Grav::instance()['config']; + $referer = defined('GRAV_CLI') ? 'grav_cli' : Grav::instance()['uri']->rootUrl(true); + + $options = new HttpOptions(); + + // Set default Headers + $options->setHeaders(array_merge([ 'Referer' => $referer ], self::$headers)); + + // Disable verify Peer if required + $verify_peer = $config->get('system.http.verify_peer'); + // Try old GPM setting if value is default + if ($verify_peer === true) { + $verify_peer = $config->get('system.gpm.verify_peer', null) ?? $verify_peer; + } + $options->verifyPeer($verify_peer); + + // Set verify Host + $verify_host = $config->get('system.http.verify_host', true); + $options->verifyHost($verify_host); + + // New setting and must be enabled for Proxy to work + if ($config->get('system.http.enable_proxy', true)) { + // Set proxy url if provided + $proxy_url = $config->get('system.http.proxy_url', $config->get('system.gpm.proxy_url', null)); + if ($proxy_url !== null) { + $options->setProxy($proxy_url); + } + + // Certificate + $proxy_cert = $config->get('system.http.proxy_cert_path', null); + if ($proxy_cert !== null) { + $options->setCaPath($proxy_cert); + } + } + + return $options; + } + + /** + * Progress normalized for cURL and Fopen + * Accepts a variable length of arguments passed in by stream method + * + * @return void + */ + public static function progress(int $bytes_transferred, int $filesize, array $info) + { + + if ($bytes_transferred > 0) { + $percent = $filesize <= 0 ? 0 : (int)(($bytes_transferred * 100) / $filesize); + + $progress = [ + 'code' => $info['http_code'], + 'filesize' => $filesize, + 'transferred' => $bytes_transferred, + 'percent' => $percent < 100 ? $percent : 100 + ]; + + if (self::$callback !== null) { + call_user_func(self::$callback, $progress); + } + } + } +} diff --git a/system/src/Grav/Common/HTTP/Response.php b/system/src/Grav/Common/HTTP/Response.php new file mode 100644 index 0000000..f05af0e --- /dev/null +++ b/system/src/Grav/Common/HTTP/Response.php @@ -0,0 +1,96 @@ +getContent(); + } + + + /** + * Makes a request to the URL by using the preferred method + * + * @param string $method method to call such as GET, PUT, etc + * @param string $uri URL to call + * @param array $overrides An array of parameters for both `curl` and `fopen` + * @param callable|null $callback Either a function or callback in array notation + * @return ResponseInterface + * @throws TransportExceptionInterface + */ + public static function request(string $method, string $uri, array $overrides = [], callable $callback = null): ResponseInterface + { + if (empty($method)) { + throw new TransportException('missing method (GET, PUT, etc.)'); + } + + if (empty($uri)) { + throw new TransportException('missing URI'); + } + + // check if this function is available, if so use it to stop any timeouts + try { + if (Utils::functionExists('set_time_limit')) { + @set_time_limit(0); + } + } catch (Exception $e) {} + + $client = Client::getClient($overrides, 6, $callback); + + return $client->request($method, $uri); + } + + + /** + * Is this a remote file or not + * + * @param string $file + * @return bool + */ + public static function isRemote($file): bool + { + return (bool) filter_var($file, FILTER_VALIDATE_URL); + } + + +} diff --git a/system/src/Grav/Common/Helpers/Base32.php b/system/src/Grav/Common/Helpers/Base32.php new file mode 100644 index 0000000..5aac178 --- /dev/null +++ b/system/src/Grav/Common/Helpers/Base32.php @@ -0,0 +1,141 @@ +', '?' + 0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06, // '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G' + 0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E, // 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O' + 0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16, // 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W' + 0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF, // 'X', 'Y', 'Z', '[', '\', ']', '^', '_' + 0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06, // '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g' + 0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E, // 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o' + 0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16, // 'p', 'q', 'r', 's', 't', 'u', 'v', 'w' + 0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF // 'x', 'y', 'z', '{', '|', '}', '~', 'DEL' + ]; + + /** + * Encode in Base32 + * + * @param string $bytes + * @return string + */ + public static function encode($bytes) + { + $i = 0; + $index = 0; + $base32 = ''; + $bytesLen = strlen($bytes); + + while ($i < $bytesLen) { + $currByte = ord($bytes[$i]); + + /* Is the current digit going to span a byte boundary? */ + if ($index > 3) { + if (($i + 1) < $bytesLen) { + $nextByte = ord($bytes[$i+1]); + } else { + $nextByte = 0; + } + + $digit = $currByte & (0xFF >> $index); + $index = ($index + 5) % 8; + $digit <<= $index; + $digit |= $nextByte >> (8 - $index); + $i++; + } else { + $digit = ($currByte >> (8 - ($index + 5))) & 0x1F; + $index = ($index + 5) % 8; + if ($index === 0) { + $i++; + } + } + + $base32 .= self::$base32Chars[$digit]; + } + return $base32; + } + + /** + * Decode in Base32 + * + * @param string $base32 + * @return string + */ + public static function decode($base32) + { + $bytes = []; + $base32Len = strlen($base32); + $base32LookupLen = count(self::$base32Lookup); + + for ($i = $base32Len * 5 / 8 - 1; $i >= 0; --$i) { + $bytes[] = 0; + } + + for ($i = 0, $index = 0, $offset = 0; $i < $base32Len; $i++) { + $lookup = ord($base32[$i]) - ord('0'); + + /* Skip chars outside the lookup table */ + if ($lookup < 0 || $lookup >= $base32LookupLen) { + continue; + } + + $digit = self::$base32Lookup[$lookup]; + + /* If this digit is not in the table, ignore it */ + if ($digit === 0xFF) { + continue; + } + + if ($index <= 3) { + $index = ($index + 5) % 8; + if ($index === 0) { + $bytes[$offset] |= $digit; + $offset++; + if ($offset >= count($bytes)) { + break; + } + } else { + $bytes[$offset] |= $digit << (8 - $index); + } + } else { + $index = ($index + 5) % 8; + $bytes[$offset] |= ($digit >> $index); + $offset++; + if ($offset >= count($bytes)) { + break; + } + $bytes[$offset] |= $digit << (8 - $index); + } + } + + $bites = ''; + foreach ($bytes as $byte) { + $bites .= chr($byte); + } + + return $bites; + } +} diff --git a/system/src/Grav/Common/Helpers/Excerpts.php b/system/src/Grav/Common/Helpers/Excerpts.php new file mode 100644 index 0000000..254edc4 --- /dev/null +++ b/system/src/Grav/Common/Helpers/Excerpts.php @@ -0,0 +1,196 @@ +` + * @param PageInterface|null $page Page, defaults to the current page object + * @return string Returns final HTML string + */ + public static function processImageHtml($html, PageInterface $page = null) + { + $excerpt = static::getExcerptFromHtml($html, 'img'); + if (null === $excerpt) { + return ''; + } + + $original_src = $excerpt['element']['attributes']['src']; + $excerpt['element']['attributes']['href'] = $original_src; + + $excerpt = static::processLinkExcerpt($excerpt, $page, 'image'); + + $excerpt['element']['attributes']['src'] = $excerpt['element']['attributes']['href']; + unset($excerpt['element']['attributes']['href']); + + $excerpt = static::processImageExcerpt($excerpt, $page); + + $excerpt['element']['attributes']['data-src'] = $original_src; + + $html = static::getHtmlFromExcerpt($excerpt); + + return $html; + } + + /** + * Process Grav page link URL from HTML tag + * + * @param string $html HTML tag e.g. `Page Link` + * @param PageInterface|null $page Page, defaults to the current page object + * @return string Returns final HTML string + */ + public static function processLinkHtml($html, PageInterface $page = null) + { + $excerpt = static::getExcerptFromHtml($html, 'a'); + if (null === $excerpt) { + return ''; + } + + $original_href = $excerpt['element']['attributes']['href']; + $excerpt = static::processLinkExcerpt($excerpt, $page, 'link'); + $excerpt['element']['attributes']['data-href'] = $original_href; + + $html = static::getHtmlFromExcerpt($excerpt); + + return $html; + } + + /** + * Get an Excerpt array from a chunk of HTML + * + * @param string $html Chunk of HTML + * @param string $tag A tag, for example `img` + * @return array|null returns nested array excerpt + */ + public static function getExcerptFromHtml($html, $tag) + { + $doc = new DOMDocument('1.0', 'UTF-8'); + $internalErrors = libxml_use_internal_errors(true); + $doc->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8')); + libxml_use_internal_errors($internalErrors); + + $elements = $doc->getElementsByTagName($tag); + $excerpt = null; + $inner = []; + + foreach ($elements as $element) { + $attributes = []; + foreach ($element->attributes as $name => $value) { + $attributes[$name] = $value->value; + } + $excerpt = [ + 'element' => [ + 'name' => $element->tagName, + 'attributes' => $attributes + ] + ]; + + foreach ($element->childNodes as $node) { + $inner[] = $doc->saveHTML($node); + } + + $excerpt = array_merge_recursive($excerpt, ['element' => ['text' => implode('', $inner)]]); + + + } + + return $excerpt; + } + + /** + * Rebuild HTML tag from an excerpt array + * + * @param array $excerpt + * @return string + */ + public static function getHtmlFromExcerpt($excerpt) + { + $element = $excerpt['element']; + $html = '<'.$element['name']; + + if (isset($element['attributes'])) { + foreach ($element['attributes'] as $name => $value) { + if ($value === null) { + continue; + } + $html .= ' '.$name.'="'.$value.'"'; + } + } + + if (isset($element['text'])) { + $html .= '>'; + $html .= is_array($element['text']) ? static::getHtmlFromExcerpt(['element' => $element['text']]) : $element['text']; + $html .= ''; + } else { + $html .= ' />'; + } + + return $html; + } + + /** + * Process a Link excerpt + * + * @param array $excerpt + * @param PageInterface|null $page Page, defaults to the current page object + * @param string $type + * @return mixed + */ + public static function processLinkExcerpt($excerpt, PageInterface $page = null, $type = 'link') + { + $excerpts = new ExcerptsObject($page); + + return $excerpts->processLinkExcerpt($excerpt, $type); + } + + /** + * Process an image excerpt + * + * @param array $excerpt + * @param PageInterface|null $page Page, defaults to the current page object + * @return array + */ + public static function processImageExcerpt(array $excerpt, PageInterface $page = null) + { + $excerpts = new ExcerptsObject($page); + + return $excerpts->processImageExcerpt($excerpt); + } + + /** + * Process media actions + * + * @param Medium $medium + * @param string|array $url + * @param PageInterface|null $page Page, defaults to the current page object + * @return Medium|Link + */ + public static function processMediaActions($medium, $url, PageInterface $page = null) + { + $excerpts = new ExcerptsObject($page); + + return $excerpts->processMediaActions($medium, $url); + } +} diff --git a/system/src/Grav/Common/Helpers/Exif.php b/system/src/Grav/Common/Helpers/Exif.php new file mode 100644 index 0000000..a8ce8fe --- /dev/null +++ b/system/src/Grav/Common/Helpers/Exif.php @@ -0,0 +1,48 @@ +get('system.media.auto_metadata_exif')) { + if (function_exists('exif_read_data') && class_exists(Reader::class)) { + $this->reader = Reader::factory(Reader::TYPE_NATIVE); + } else { + throw new RuntimeException('Please enable the Exif extension for PHP or disable Exif support in Grav system configuration'); + } + } + } + + /** + * @return Reader + */ + public function getReader() + { + return $this->reader; + } +} diff --git a/system/src/Grav/Common/Helpers/LogViewer.php b/system/src/Grav/Common/Helpers/LogViewer.php new file mode 100644 index 0000000..085cc9e --- /dev/null +++ b/system/src/Grav/Common/Helpers/LogViewer.php @@ -0,0 +1,167 @@ +.*?)\] (?P\w+)\.(?P\w+): (?P.*[^ ]+) (?P[^ ]+) (?P[^ ]+)/'; + + /** + * Get the objects of a tailed file + * + * @param string $filepath + * @param int $lines + * @param bool $desc + * @return array + */ + public function objectTail($filepath, $lines = 1, $desc = true) + { + $data = $this->tail($filepath, $lines); + $tailed_log = $data ? explode(PHP_EOL, $data) : []; + $line_objects = []; + + foreach ($tailed_log as $line) { + $line_objects[] = $this->parse($line); + } + + return $desc ? $line_objects : array_reverse($line_objects); + } + + /** + * Optimized way to get just the last few entries of a log file + * + * @param string $filepath + * @param int $lines + * @return string|false + */ + public function tail($filepath, $lines = 1) + { + $f = $filepath ? @fopen($filepath, 'rb') : false; + if ($f === false) { + return false; + } + + $buffer = ($lines < 2 ? 64 : ($lines < 10 ? 512 : 4096)); + + fseek($f, -1, SEEK_END); + if (fread($f, 1) !== "\n") { + --$lines; + } + + // Start reading + $output = ''; + // While we would like more + while (ftell($f) > 0 && $lines >= 0) { + // Figure out how far back we should jump + $seek = min(ftell($f), $buffer); + // Do the jump (backwards, relative to where we are) + fseek($f, -$seek, SEEK_CUR); + // Read a chunk and prepend it to our output + $chunk = fread($f, $seek); + if ($chunk === false) { + throw new \RuntimeException('Cannot read file'); + } + $output = $chunk . $output; + // Jump back to where we started reading + fseek($f, -mb_strlen($chunk, '8bit'), SEEK_CUR); + // Decrease our line counter + $lines -= substr_count($chunk, "\n"); + } + // While we have too many lines + // (Because of buffer size we might have read too many) + while ($lines++ < 0) { + // Find first newline and remove all text before that + $output = substr($output, strpos($output, "\n") + 1); + } + // Close file and return + fclose($f); + + return trim($output); + } + + /** + * Helper class to get level color + * + * @param string $level + * @return string + */ + public static function levelColor($level) + { + $colors = [ + 'DEBUG' => 'green', + 'INFO' => 'cyan', + 'NOTICE' => 'yellow', + 'WARNING' => 'yellow', + 'ERROR' => 'red', + 'CRITICAL' => 'red', + 'ALERT' => 'red', + 'EMERGENCY' => 'magenta' + ]; + return $colors[$level] ?? 'white'; + } + + /** + * Parse a monolog row into array bits + * + * @param string $line + * @return array + */ + public function parse($line) + { + if (!is_string($line) || $line === '') { + return []; + } + + preg_match($this->pattern, $line, $data); + if (!isset($data['date'])) { + return []; + } + + preg_match('/(.*)- Trace:(.*)/', $data['message'], $matches); + if (is_array($matches) && isset($matches[1])) { + $data['message'] = trim($matches[1]); + $data['trace'] = trim($matches[2]); + } + + return [ + 'date' => DateTime::createFromFormat('Y-m-d H:i:s', $data['date']), + 'logger' => $data['logger'], + 'level' => $data['level'], + 'message' => $data['message'], + 'trace' => isset($data['trace']) ? self::parseTrace($data['trace']) : null, + 'context' => json_decode($data['context'], true), + 'extra' => json_decode($data['extra'], true) + ]; + } + + /** + * Parse text of trace into an array of lines + * + * @param string $trace + * @param int $rows + * @return array + */ + public static function parseTrace($trace, $rows = 10) + { + $lines = array_filter(preg_split('/#\d*/m', $trace)); + + return array_slice($lines, 0, $rows); + } +} diff --git a/system/src/Grav/Common/Helpers/Truncator.php b/system/src/Grav/Common/Helpers/Truncator.php new file mode 100644 index 0000000..d09c52c --- /dev/null +++ b/system/src/Grav/Common/Helpers/Truncator.php @@ -0,0 +1,344 @@ +getElementsByTagName('div')->item(0); + $container = $container->parentNode->removeChild($container); + + // Iterate over words. + $words = new DOMWordsIterator($container); + $truncated = false; + foreach ($words as $word) { + // If we have exceeded the limit, we delete the remainder of the content. + if ($words->key() >= $limit) { + // Grab current position. + $currentWordPosition = $words->currentWordPosition(); + $curNode = $currentWordPosition[0]; + $offset = $currentWordPosition[1]; + $words = $currentWordPosition[2]; + + $curNode->nodeValue = substr( + $curNode->nodeValue, + 0, + $words[$offset][1] + strlen($words[$offset][0]) + ); + + self::removeProceedingNodes($curNode, $container); + + if (!empty($ellipsis)) { + self::insertEllipsis($curNode, $ellipsis); + } + + $truncated = true; + + break; + } + } + + // Return original HTML if not truncated. + if ($truncated) { + $html = self::getCleanedHtml($doc, $container); + } + + return $html; + } + + /** + * Safely truncates HTML by a given number of letters. + * + * @param string $html Input HTML. + * @param int $limit Limit to how many letters we preserve. + * @param string $ellipsis String to use as ellipsis (if any). + * @return string Safe truncated HTML. + */ + public static function truncateLetters($html, $limit = 0, $ellipsis = '') + { + if ($limit <= 0) { + return $html; + } + + $doc = self::htmlToDomDocument($html); + $container = $doc->getElementsByTagName('div')->item(0); + $container = $container->parentNode->removeChild($container); + + // Iterate over letters. + $letters = new DOMLettersIterator($container); + $truncated = false; + foreach ($letters as $letter) { + // If we have exceeded the limit, we want to delete the remainder of this document. + if ($letters->key() >= $limit) { + $currentText = $letters->currentTextPosition(); + $currentText[0]->nodeValue = mb_substr($currentText[0]->nodeValue, 0, $currentText[1] + 1); + self::removeProceedingNodes($currentText[0], $container); + + if (!empty($ellipsis)) { + self::insertEllipsis($currentText[0], $ellipsis); + } + + $truncated = true; + + break; + } + } + + // Return original HTML if not truncated. + if ($truncated) { + $html = self::getCleanedHtml($doc, $container); + } + + return $html; + } + + /** + * Builds a DOMDocument object from a string containing HTML. + * + * @param string $html HTML to load + * @return DOMDocument Returns a DOMDocument object. + */ + public static function htmlToDomDocument($html) + { + if (!$html) { + $html = ''; + } + + // Transform multibyte entities which otherwise display incorrectly. + $html = mb_encode_numericentity($html, [0x80, 0x10FFFF, 0, ~0], 'UTF-8'); + + // Internal errors enabled as HTML5 not fully supported. + libxml_use_internal_errors(true); + + // Instantiate new DOMDocument object, and then load in UTF-8 HTML. + $dom = new DOMDocument(); + $dom->encoding = 'UTF-8'; + $dom->loadHTML("
$html
"); + + return $dom; + } + + /** + * Removes all nodes after the current node. + * + * @param DOMNode|DOMElement $domNode + * @param DOMNode|DOMElement $topNode + * @return void + */ + private static function removeProceedingNodes($domNode, $topNode) + { + /** @var DOMNode|null $nextNode */ + $nextNode = $domNode->nextSibling; + + if ($nextNode !== null) { + self::removeProceedingNodes($nextNode, $topNode); + $domNode->parentNode->removeChild($nextNode); + } else { + //scan upwards till we find a sibling + $curNode = $domNode->parentNode; + while ($curNode !== $topNode) { + if ($curNode->nextSibling !== null) { + $curNode = $curNode->nextSibling; + self::removeProceedingNodes($curNode, $topNode); + $curNode->parentNode->removeChild($curNode); + break; + } + $curNode = $curNode->parentNode; + } + } + } + + /** + * Clean extra code + * + * @param DOMDocument $doc + * @param DOMNode $container + * @return string + */ + private static function getCleanedHTML(DOMDocument $doc, DOMNode $container) + { + while ($doc->firstChild) { + $doc->removeChild($doc->firstChild); + } + + while ($container->firstChild) { + $doc->appendChild($container->firstChild); + } + + return trim($doc->saveHTML()); + } + + /** + * Inserts an ellipsis + * + * @param DOMNode|DOMElement $domNode Element to insert after. + * @param string $ellipsis Text used to suffix our document. + * @return void + */ + private static function insertEllipsis($domNode, $ellipsis) + { + $avoid = array('a', 'strong', 'em', 'h1', 'h2', 'h3', 'h4', 'h5'); //html tags to avoid appending the ellipsis to + + if ($domNode->parentNode->parentNode !== null && in_array($domNode->parentNode->nodeName, $avoid, true)) { + // Append as text node to parent instead + $textNode = new DOMText($ellipsis); + + /** @var DOMNode|null $nextSibling */ + $nextSibling = $domNode->parentNode->parentNode->nextSibling; + if ($nextSibling) { + $domNode->parentNode->parentNode->insertBefore($textNode, $domNode->parentNode->parentNode->nextSibling); + } else { + $domNode->parentNode->parentNode->appendChild($textNode); + } + } else { + // Append to current node + $domNode->nodeValue = rtrim($domNode->nodeValue) . $ellipsis; + } + } + + /** + * @param string $text + * @param int $length + * @param string $ending + * @param bool $exact + * @param bool $considerHtml + * @return string + */ + public function truncate( + $text, + $length = 100, + $ending = '...', + $exact = false, + $considerHtml = true + ) { + if ($considerHtml) { + // if the plain text is shorter than the maximum length, return the whole text + if (strlen(preg_replace('/<.*?>/', '', $text)) <= $length) { + return $text; + } + + // splits all html-tags to scanable lines + preg_match_all('/(<.+?>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER); + $total_length = strlen($ending); + $truncate = ''; + $open_tags = []; + + foreach ($lines as $line_matchings) { + // if there is any html-tag in this line, handle it and add it (uncounted) to the output + if (!empty($line_matchings[1])) { + // if it's an "empty element" with or without xhtml-conform closing slash + if (preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1])) { + // do nothing + // if tag is a closing tag + } elseif (preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) { + // delete tag from $open_tags list + $pos = array_search($tag_matchings[1], $open_tags); + if ($pos !== false) { + unset($open_tags[$pos]); + } + // if tag is an opening tag + } elseif (preg_match('/^<\s*([^\s>!]+).*?>$/s', $line_matchings[1], $tag_matchings)) { + // add tag to the beginning of $open_tags list + array_unshift($open_tags, strtolower($tag_matchings[1])); + } + // add html-tag to $truncate'd text + $truncate .= $line_matchings[1]; + } + // calculate the length of the plain text part of the line; handle entities as one character + $content_length = strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $line_matchings[2])); + if ($total_length+$content_length> $length) { + // the number of characters which are left + $left = $length - $total_length; + $entities_length = 0; + // search for html entities + if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', $line_matchings[2], $entities, PREG_OFFSET_CAPTURE)) { + // calculate the real length of all entities in the legal range + foreach ($entities[0] as $entity) { + if ($entity[1]+1-$entities_length <= $left) { + $left--; + $entities_length += strlen($entity[0]); + } else { + // no more characters left + break; + } + } + } + $truncate .= substr($line_matchings[2], 0, $left+$entities_length); + // maximum lenght is reached, so get off the loop + break; + } else { + $truncate .= $line_matchings[2]; + $total_length += $content_length; + } + // if the maximum length is reached, get off the loop + if ($total_length>= $length) { + break; + } + } + } else { + if (strlen($text) <= $length) { + return $text; + } + + $truncate = substr($text, 0, $length - strlen($ending)); + } + // if the words shouldn't be cut in the middle... + if (!$exact) { + // ...search the last occurance of a space... + $spacepos = strrpos($truncate, ' '); + if (false !== $spacepos) { + // ...and cut the text in this position + $truncate = substr($truncate, 0, $spacepos); + } + } + // add the defined ending to the text + $truncate .= $ending; + if (isset($open_tags)) { + // close all unclosed html-tags + foreach ($open_tags as $tag) { + $truncate .= ''; + } + } + + return $truncate; + } +} diff --git a/system/src/Grav/Common/Helpers/YamlLinter.php b/system/src/Grav/Common/Helpers/YamlLinter.php new file mode 100644 index 0000000..1dee495 --- /dev/null +++ b/system/src/Grav/Common/Helpers/YamlLinter.php @@ -0,0 +1,122 @@ +get('system.pages.theme'); + $theme_path = 'themes://' . $current_theme . '/blueprints'; + + $locator->addPath('blueprints', '', [$theme_path]); + return static::recurseFolder('blueprints://'); + } + + /** + * @param string $path + * @param string $extensions + * @return array + */ + public static function recurseFolder($path, $extensions = '(md|yaml)') + { + $lint_errors = []; + + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $flags = RecursiveDirectoryIterator::SKIP_DOTS | RecursiveDirectoryIterator::FOLLOW_SYMLINKS; + if ($locator->isStream($path)) { + $directory = $locator->getRecursiveIterator($path, $flags); + } else { + $directory = new RecursiveDirectoryIterator($path, $flags); + } + $recursive = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST); + $iterator = new RegexIterator($recursive, '/^.+\.'.$extensions.'$/ui'); + + /** @var RecursiveDirectoryIterator $file */ + foreach ($iterator as $filepath => $file) { + try { + Yaml::parse(static::extractYaml($filepath)); + } catch (Exception $e) { + $lint_errors[str_replace(GRAV_ROOT, '', $filepath)] = $e->getMessage(); + } + } + + return $lint_errors; + } + + /** + * @param string $path + * @return string + */ + protected static function extractYaml($path) + { + $extension = Utils::pathinfo($path, PATHINFO_EXTENSION); + if ($extension === 'md') { + $file = MarkdownFile::instance($path); + $contents = $file->frontmatter(); + $file->free(); + } else { + $contents = file_get_contents($path); + } + return $contents; + } +} diff --git a/system/src/Grav/Common/Inflector.php b/system/src/Grav/Common/Inflector.php new file mode 100644 index 0000000..284b8dd --- /dev/null +++ b/system/src/Grav/Common/Inflector.php @@ -0,0 +1,363 @@ +isDebug()) { + static::$plural = $language->translate('GRAV.INFLECTOR_PLURALS', null, true); + static::$singular = $language->translate('GRAV.INFLECTOR_SINGULAR', null, true); + static::$uncountable = $language->translate('GRAV.INFLECTOR_UNCOUNTABLE', null, true); + static::$irregular = $language->translate('GRAV.INFLECTOR_IRREGULAR', null, true); + static::$ordinals = $language->translate('GRAV.INFLECTOR_ORDINALS', null, true); + } + } + } + + /** + * Pluralizes English nouns. + * + * @param string $word English noun to pluralize + * @param int $count The count + * @return string|false Plural noun + */ + public static function pluralize($word, $count = 2) + { + static::init(); + + if ((int)$count === 1) { + return $word; + } + + $lowercased_word = strtolower($word); + + if (is_array(static::$uncountable)) { + foreach (static::$uncountable as $_uncountable) { + if (substr($lowercased_word, -1 * strlen($_uncountable)) === $_uncountable) { + return $word; + } + } + } + + if (is_array(static::$irregular)) { + foreach (static::$irregular as $_plural => $_singular) { + if (preg_match('/(' . $_plural . ')$/i', $word, $arr)) { + return preg_replace('/(' . $_plural . ')$/i', substr($arr[0], 0, 1) . substr($_singular, 1), $word); + } + } + } + + if (is_array(static::$plural)) { + foreach (static::$plural as $rule => $replacement) { + if (preg_match($rule, $word)) { + return preg_replace($rule, $replacement, $word); + } + } + } + + return false; + } + + /** + * Singularizes English nouns. + * + * @param string $word English noun to singularize + * @param int $count + * + * @return string Singular noun. + */ + public static function singularize($word, $count = 1) + { + static::init(); + + if ((int)$count !== 1) { + return $word; + } + + $lowercased_word = strtolower($word); + + if (is_array(static::$uncountable)) { + foreach (static::$uncountable as $_uncountable) { + if (substr($lowercased_word, -1 * strlen($_uncountable)) === $_uncountable) { + return $word; + } + } + } + + if (is_array(static::$irregular)) { + foreach (static::$irregular as $_plural => $_singular) { + if (preg_match('/(' . $_singular . ')$/i', $word, $arr)) { + return preg_replace('/(' . $_singular . ')$/i', substr($arr[0], 0, 1) . substr($_plural, 1), $word); + } + } + } + + if (is_array(static::$singular)) { + foreach (static::$singular as $rule => $replacement) { + if (preg_match($rule, $word)) { + return preg_replace($rule, $replacement, $word); + } + } + } + + return $word; + } + + /** + * Converts an underscored or CamelCase word into a English + * sentence. + * + * The titleize public function converts text like "WelcomePage", + * "welcome_page" or "welcome page" to this "Welcome + * Page". + * If second parameter is set to 'first' it will only + * capitalize the first character of the title. + * + * @param string $word Word to format as tile + * @param string $uppercase If set to 'first' it will only uppercase the + * first character. Otherwise it will uppercase all + * the words in the title. + * + * @return string Text formatted as title + */ + public static function titleize($word, $uppercase = '') + { + $humanize_underscorize = static::humanize(static::underscorize($word)); + + if ($uppercase === 'first') { + $firstLetter = mb_strtoupper(mb_substr($humanize_underscorize, 0, 1, "UTF-8"), "UTF-8"); + return $firstLetter . mb_substr($humanize_underscorize, 1, mb_strlen($humanize_underscorize, "UTF-8"), "UTF-8"); + } else { + return mb_convert_case($humanize_underscorize, MB_CASE_TITLE, 'UTF-8'); + } + + } + + /** + * Returns given word as CamelCased + * + * Converts a word like "send_email" to "SendEmail". It + * will remove non alphanumeric character from the word, so + * "who's online" will be converted to "WhoSOnline" + * + * @see variablize + * + * @param string $word Word to convert to camel case + * @return string UpperCamelCasedWord + */ + public static function camelize($word) + { + return str_replace(' ', '', ucwords(preg_replace('/[^\p{L}^0-9]+/', ' ', $word))); + } + + /** + * Converts a word "into_it_s_underscored_version" + * + * Convert any "CamelCased" or "ordinary Word" into an + * "underscored_word". + * + * This can be really useful for creating friendly URLs. + * + * @param string $word Word to underscore + * @return string Underscored word + */ + public static function underscorize($word) + { + $regex1 = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1_\2', $word); + $regex2 = preg_replace('/([a-zd])([A-Z])/', '\1_\2', $regex1); + $regex3 = preg_replace('/[^\p{L}^0-9]+/u', '_', $regex2); + + return strtolower($regex3); + } + + /** + * Converts a word "into-it-s-hyphenated-version" + * + * Convert any "CamelCased" or "ordinary Word" into an + * "hyphenated-word". + * + * This can be really useful for creating friendly URLs. + * + * @param string $word Word to hyphenate + * @return string hyphenized word + */ + public static function hyphenize($word) + { + $regex1 = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1-\2', $word); + $regex2 = preg_replace('/([a-z])([A-Z])/', '\1-\2', $regex1); + $regex3 = preg_replace('/([0-9])([A-Z])/', '\1-\2', $regex2); + $regex4 = preg_replace('/[^\p{L}^0-9]+/', '-', $regex3); + + $regex4 = trim($regex4, '-'); + + return strtolower($regex4); + } + + /** + * Returns a human-readable string from $word + * + * Returns a human-readable string from $word, by replacing + * underscores with a space, and by upper-casing the initial + * character by default. + * + * If you need to uppercase all the words you just have to + * pass 'all' as a second parameter. + * + * @param string $word String to "humanize" + * @param string $uppercase If set to 'all' it will uppercase all the words + * instead of just the first one. + * + * @return string Human-readable word + */ + public static function humanize($word, $uppercase = '') + { + $uppercase = $uppercase === 'all' ? 'ucwords' : 'ucfirst'; + + return $uppercase(str_replace('_', ' ', preg_replace('/_id$/', '', $word))); + } + + /** + * Same as camelize but first char is underscored + * + * Converts a word like "send_email" to "sendEmail". It + * will remove non alphanumeric character from the word, so + * "who's online" will be converted to "whoSOnline" + * + * @see camelize + * + * @param string $word Word to lowerCamelCase + * @return string Returns a lowerCamelCasedWord + */ + public static function variablize($word) + { + $word = static::camelize($word); + + return strtolower($word[0]) . substr($word, 1); + } + + /** + * Converts a class name to its table name according to rails + * naming conventions. + * + * Converts "Person" to "people" + * + * @see classify + * + * @param string $class_name Class name for getting related table_name. + * @return string plural_table_name + */ + public static function tableize($class_name) + { + return static::pluralize(static::underscorize($class_name)); + } + + /** + * Converts a table name to its class name according to rails + * naming conventions. + * + * Converts "people" to "Person" + * + * @see tableize + * + * @param string $table_name Table name for getting related ClassName. + * @return string SingularClassName + */ + public static function classify($table_name) + { + return static::camelize(static::singularize($table_name)); + } + + /** + * Converts number to its ordinal English form. + * + * This method converts 13 to 13th, 2 to 2nd ... + * + * @param int $number Number to get its ordinal value + * @return string Ordinal representation of given string. + */ + public static function ordinalize($number) + { + static::init(); + + if (!is_array(static::$ordinals)) { + return (string)$number; + } + + if (in_array($number % 100, range(11, 13), true)) { + return $number . static::$ordinals['default']; + } + + switch ($number % 10) { + case 1: + return $number . static::$ordinals['first']; + case 2: + return $number . static::$ordinals['second']; + case 3: + return $number . static::$ordinals['third']; + default: + return $number . static::$ordinals['default']; + } + } + + /** + * Converts a number of days to a number of months + * + * @param int $days + * @return int + */ + public static function monthize($days) + { + $now = new DateTime(); + $end = new DateTime(); + + $duration = new DateInterval("P{$days}D"); + + $diff = $end->add($duration)->diff($now); + + // handle years + if ($diff->y > 0) { + $diff->m += 12 * $diff->y; + } + + return $diff->m; + } +} diff --git a/system/src/Grav/Common/Iterator.php b/system/src/Grav/Common/Iterator.php new file mode 100644 index 0000000..a60c74f --- /dev/null +++ b/system/src/Grav/Common/Iterator.php @@ -0,0 +1,264 @@ +items[$key] ?? null; + } + + /** + * Clone the iterator. + */ + #[\ReturnTypeWillChange] + public function __clone() + { + foreach ($this as $key => $value) { + if (is_object($value)) { + $this->{$key} = clone $this->{$key}; + } + } + } + + /** + * Convents iterator to a comma separated list. + * + * @return string + */ + #[\ReturnTypeWillChange] + public function __toString() + { + return implode(',', $this->items); + } + + /** + * Remove item from the list. + * + * @param string $key + * @return void + */ + public function remove($key) + { + $this->offsetUnset($key); + } + + /** + * Return previous item. + * + * @return mixed + */ + public function prev() + { + return prev($this->items); + } + + /** + * Return nth item. + * + * @param int $key + * @return mixed|bool + */ + public function nth($key) + { + $items = array_keys($this->items); + + return isset($items[$key]) ? $this->offsetGet($items[$key]) : false; + } + + /** + * Get the first item + * + * @return mixed + */ + public function first() + { + $items = array_keys($this->items); + + return $this->offsetGet(array_shift($items)); + } + + /** + * Get the last item + * + * @return mixed + */ + public function last() + { + $items = array_keys($this->items); + + return $this->offsetGet(array_pop($items)); + } + + /** + * Reverse the Iterator + * + * @return $this + */ + public function reverse() + { + $this->items = array_reverse($this->items); + + return $this; + } + + /** + * @param mixed $needle Searched value. + * + * @return string|int|false Key if found, otherwise false. + */ + public function indexOf($needle) + { + foreach (array_values($this->items) as $key => $value) { + if ($value === $needle) { + return $key; + } + } + + return false; + } + + /** + * Shuffle items. + * + * @return $this + */ + public function shuffle() + { + $keys = array_keys($this->items); + shuffle($keys); + + $new = []; + foreach ($keys as $key) { + $new[$key] = $this->items[$key]; + } + + $this->items = $new; + + return $this; + } + + /** + * Slice the list. + * + * @param int $offset + * @param int|null $length + * @return $this + */ + public function slice($offset, $length = null) + { + $this->items = array_slice($this->items, $offset, $length); + + return $this; + } + + /** + * Pick one or more random entries. + * + * @param int $num Specifies how many entries should be picked. + * @return $this + */ + public function random($num = 1) + { + $count = count($this->items); + if ($num > $count) { + $num = $count; + } + + $this->items = array_intersect_key($this->items, array_flip((array)array_rand($this->items, $num))); + + return $this; + } + + /** + * Append new elements to the list. + * + * @param array|Iterator $items Items to be appended. Existing keys will be overridden with the new values. + * @return $this + */ + public function append($items) + { + if ($items instanceof static) { + $items = $items->toArray(); + } + $this->items = array_merge($this->items, (array)$items); + + return $this; + } + + /** + * Filter elements from the list + * + * @param callable|null $callback A function the receives ($value, $key) and must return a boolean to indicate + * filter status + * + * @return $this + */ + public function filter(callable $callback = null) + { + foreach ($this->items as $key => $value) { + if ((!$callback && !(bool)$value) || ($callback && !$callback($value, $key))) { + unset($this->items[$key]); + } + } + + return $this; + } + + + /** + * Sorts elements from the list and returns a copy of the list in the proper order + * + * @param callable|null $callback + * @param bool $desc + * @return $this|array + * + */ + public function sort(callable $callback = null, $desc = false) + { + if (!$callback || !is_callable($callback)) { + return $this; + } + + $items = $this->items; + uasort($items, $callback); + + return !$desc ? $items : array_reverse($items, true); + } +} diff --git a/system/src/Grav/Common/Language/Language.php b/system/src/Grav/Common/Language/Language.php new file mode 100644 index 0000000..f2f3c1b --- /dev/null +++ b/system/src/Grav/Common/Language/Language.php @@ -0,0 +1,663 @@ +grav = $grav; + $this->config = $grav['config']; + + $languages = $this->config->get('system.languages.supported', []); + foreach ($languages as &$language) { + $language = (string)$language; + } + unset($language); + + $this->languages = $languages; + + $this->init(); + } + + /** + * Initialize the default and enabled languages + * + * @return void + */ + public function init() + { + $default = $this->config->get('system.languages.default_lang'); + if (null !== $default) { + $default = (string)$default; + } + + // Note that reset returns false on empty languages. + $this->default = $default ?? reset($this->languages); + + $this->resetFallbackPageExtensions(); + + if (empty($this->languages)) { + // If no languages are set, turn of multi-language support. + $this->enabled = false; + } elseif ($default && !in_array($default, $this->languages, true)) { + // If default language isn't in the language list, we need to add it. + array_unshift($this->languages, $default); + } + } + + /** + * Ensure that languages are enabled + * + * @return bool + */ + public function enabled() + { + return $this->enabled; + } + + /** + * Returns true if language debugging is turned on. + * + * @return bool + */ + public function isDebug(): bool + { + return !$this->config->get('system.languages.translations', true); + } + + /** + * Gets the array of supported languages + * + * @return array + */ + public function getLanguages() + { + return $this->languages; + } + + /** + * Sets the current supported languages manually + * + * @param array $langs + * @return void + */ + public function setLanguages($langs) + { + $this->languages = $langs; + + $this->init(); + } + + /** + * Gets a pipe-separated string of available languages + * + * @param string|null $delimiter Delimiter to be quoted. + * @return string + */ + public function getAvailable($delimiter = null) + { + $languagesArray = $this->languages; //Make local copy + + $languagesArray = array_map(static function ($value) use ($delimiter) { + return preg_quote($value, $delimiter); + }, $languagesArray); + + sort($languagesArray); + + return implode('|', array_reverse($languagesArray)); + } + + /** + * Gets language, active if set, else default + * + * @return string|false + */ + public function getLanguage() + { + return $this->active ?: $this->default; + } + + /** + * Gets current default language + * + * @return string|false + */ + public function getDefault() + { + return $this->default; + } + + /** + * Sets default language manually + * + * @param string $lang + * @return string|bool + */ + public function setDefault($lang) + { + $lang = (string)$lang; + if ($this->validate($lang)) { + $this->default = $lang; + + return $lang; + } + + return false; + } + + /** + * Gets current active language + * + * @return string|false + */ + public function getActive() + { + return $this->active; + } + + /** + * Sets active language manually + * + * @param string|false $lang + * @return string|false + */ + public function setActive($lang) + { + $lang = (string)$lang; + if ($this->validate($lang)) { + /** @var Debugger $debugger */ + $debugger = $this->grav['debugger']; + $debugger->addMessage('Active language set to ' . $lang, 'debug'); + + $this->active = $lang; + + return $lang; + } + + return false; + } + + /** + * Sets the active language based on the first part of the URL + * + * @param string $uri + * @return string + */ + public function setActiveFromUri($uri) + { + $regex = '/(^\/(' . $this->getAvailable() . '))(?:\/|\?|$)/i'; + + // if languages set + if ($this->enabled()) { + // Try setting language from prefix of URL (/en/blah/blah). + if (preg_match($regex, $uri, $matches)) { + $this->lang_in_url = true; + $this->setActive($matches[2]); + $uri = preg_replace("/\\" . $matches[1] . '/', '', $uri, 1); + + // Store in session if language is different. + if (isset($this->grav['session']) && $this->grav['session']->isStarted() + && $this->config->get('system.languages.session_store_active', true) + && $this->grav['session']->active_language != $this->active + ) { + $this->grav['session']->active_language = $this->active; + } + } else { + // Try getting language from the session, else no active. + if (isset($this->grav['session']) && $this->grav['session']->isStarted() && + $this->config->get('system.languages.session_store_active', true)) { + $this->setActive($this->grav['session']->active_language ?: null); + } + // if still null, try from http_accept_language header + if ($this->active === null && + $this->config->get('system.languages.http_accept_language') && + $accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? false) { + $negotiator = new LanguageNegotiator(); + $best_language = $negotiator->getBest($accept, $this->languages); + + if ($best_language instanceof AcceptLanguage) { + $this->setActive($best_language->getType()); + } else { + $this->setActive($this->getDefault()); + } + } + } + } + + return $uri; + } + + /** + * Get a URL prefix based on configuration + * + * @param string|null $lang + * @return string + */ + public function getLanguageURLPrefix($lang = null) + { + if (!$this->enabled()) { + return ''; + } + + // if active lang is not passed in, use current active + if (!$lang) { + $lang = $this->getLanguage(); + } + + return $this->isIncludeDefaultLanguage($lang) ? '/' . $lang : ''; + } + + /** + * Test to see if language is default and language should be included in the URL + * + * @param string|null $lang + * @return bool + */ + public function isIncludeDefaultLanguage($lang = null) + { + if (!$this->enabled()) { + return false; + } + + // if active lang is not passed in, use current active + if (!$lang) { + $lang = $this->getLanguage(); + } + + return !($this->default === $lang && $this->config->get('system.languages.include_default_lang') === false); + } + + /** + * Simple getter to tell if a language was found in the URL + * + * @return bool + */ + public function isLanguageInUrl() + { + return (bool) $this->lang_in_url; + } + + /** + * Get full list of used language page extensions: [''=>'.md', 'en'=>'.en.md', ...] + * + * @param string|null $fileExtension + * @return array + */ + public function getPageExtensions($fileExtension = null) + { + $fileExtension = $fileExtension ?: CONTENT_EXT; + + if (!isset($this->fallback_extensions[$fileExtension])) { + $extensions[''] = $fileExtension; + foreach ($this->languages as $code) { + $extensions[$code] = ".{$code}{$fileExtension}"; + } + + $this->fallback_extensions[$fileExtension] = $extensions; + } + + return $this->fallback_extensions[$fileExtension]; + } + + /** + * Gets an array of valid extensions with active first, then fallback extensions + * + * @param string|null $fileExtension + * @param string|null $languageCode + * @param bool $assoc Return values in ['en' => '.en.md', ...] format. + * @return array Key is the language code, value is the file extension to be used. + */ + public function getFallbackPageExtensions(string $fileExtension = null, string $languageCode = null, bool $assoc = false) + { + $fileExtension = $fileExtension ?: CONTENT_EXT; + $key = $fileExtension . '-' . ($languageCode ?? 'default') . '-' . (int)$assoc; + + if (!isset($this->fallback_extensions[$key])) { + $all = $this->getPageExtensions($fileExtension); + $list = []; + $fallback = $this->getFallbackLanguages($languageCode, true); + foreach ($fallback as $code) { + $ext = $all[$code] ?? null; + if (null !== $ext) { + $list[$code] = $ext; + } + } + if (!$assoc) { + $list = array_values($list); + } + + $this->fallback_extensions[$key] = $list; + } + + return $this->fallback_extensions[$key]; + } + + /** + * Resets the fallback_languages value. + * + * Useful to re-initialize the pages and change site language at runtime, example: + * + * ``` + * $this->grav['language']->setActive('it'); + * $this->grav['language']->resetFallbackPageExtensions(); + * $this->grav['pages']->init(); + * ``` + * + * @return void + */ + public function resetFallbackPageExtensions() + { + $this->fallback_languages = []; + $this->fallback_extensions = []; + $this->page_extensions = []; + } + + /** + * Gets an array of languages with active first, then fallback languages. + * + * + * @param string|null $languageCode + * @param bool $includeDefault If true, list contains '', which can be used for default + * @return array + */ + public function getFallbackLanguages(string $languageCode = null, bool $includeDefault = false) + { + // Handle default. + if ($languageCode === '' || !$this->enabled()) { + return ['']; + } + + $default = $this->getDefault() ?? 'en'; + $active = $languageCode ?? $this->getActive() ?? $default; + $key = $active . '-' . (int)$includeDefault; + + if (!isset($this->fallback_languages[$key])) { + $fallback = $this->config->get('system.languages.content_fallback.' . $active); + $fallback_languages = []; + + if (null === $fallback && $this->config->get('system.languages.pages_fallback_only', false)) { + user_error('Configuration option `system.languages.pages_fallback_only` is deprecated since Grav 1.7, use `system.languages.content_fallback` instead', E_USER_DEPRECATED); + + // Special fallback list returns itself and all the previous items in reverse order: + // active: 'v2', languages: ['v1', 'v2', 'v3', 'v4'] => ['v2', 'v1', ''] + if ($includeDefault) { + $fallback_languages[''] = ''; + } + foreach ($this->languages as $code) { + $fallback_languages[$code] = $code; + if ($code === $active) { + break; + } + } + $fallback_languages = array_reverse($fallback_languages); + } else { + if (null === $fallback) { + $fallback = [$default]; + } elseif (!is_array($fallback)) { + $fallback = is_string($fallback) && $fallback !== '' ? explode(',', $fallback) : []; + } + array_unshift($fallback, $active); + $fallback = array_unique($fallback); + + foreach ($fallback as $code) { + // Default fallback list has active language followed by default language and extensionless file: + // active: 'fi', default: 'en', languages: ['sv', 'en', 'de', 'fi'] => ['fi', 'en', ''] + $fallback_languages[$code] = $code; + if ($includeDefault && $code === $default) { + $fallback_languages[''] = ''; + } + } + } + + $fallback_languages = array_values($fallback_languages); + + $this->fallback_languages[$key] = $fallback_languages; + } + + return $this->fallback_languages[$key]; + } + + /** + * Ensures the language is valid and supported + * + * @param string $lang + * @return bool + */ + public function validate($lang) + { + return in_array($lang, $this->languages, true); + } + + /** + * Translate a key and possibly arguments into a string using current lang and fallbacks + * + * @param string|array $args The first argument is the lookup key value + * Other arguments can be passed and replaced in the translation with sprintf syntax + * @param array|null $languages + * @param bool $array_support + * @param bool $html_out + * @return string|string[] + */ + public function translate($args, array $languages = null, $array_support = false, $html_out = false) + { + if (is_array($args)) { + $lookup = array_shift($args); + } else { + $lookup = $args; + $args = []; + } + + if (!$this->isDebug()) { + if ($lookup && $this->enabled() && empty($languages)) { + $languages = $this->getTranslatedLanguages(); + } + + $languages = $languages ?: ['en']; + + foreach ((array)$languages as $lang) { + $translation = $this->getTranslation($lang, $lookup, $array_support); + + if ($translation) { + if (is_string($translation) && count($args) >= 1) { + return vsprintf($translation, $args); + } + + return $translation; + } + } + } elseif ($array_support) { + return [$lookup]; + } + + if ($html_out) { + return '' . $lookup . ''; + } + + return $lookup; + } + + /** + * Translate Array + * + * @param string $key + * @param string $index + * @param array|null $languages + * @param bool $html_out + * @return string + */ + public function translateArray($key, $index, $languages = null, $html_out = false) + { + if ($this->isDebug()) { + return $key . '[' . $index . ']'; + } + + if ($key && empty($languages) && $this->enabled()) { + $languages = $this->getTranslatedLanguages(); + } + + $languages = $languages ?: ['en']; + + foreach ((array)$languages as $lang) { + $translation_array = (array)Grav::instance()['languages']->get($lang . '.' . $key, null); + if ($translation_array && array_key_exists($index, $translation_array)) { + return $translation_array[$index]; + } + } + + if ($html_out) { + return '' . $key . '[' . $index . ']'; + } + + return $key . '[' . $index . ']'; + } + + /** + * Lookup the translation text for a given lang and key + * + * @param string $lang lang code + * @param string $key key to lookup with + * @param bool $array_support + * @return string|string[] + */ + public function getTranslation($lang, $key, $array_support = false) + { + if ($this->isDebug()) { + return $key; + } + + $translation = Grav::instance()['languages']->get($lang . '.' . $key, null); + if (!$array_support && is_array($translation)) { + return (string)array_shift($translation); + } + + return $translation; + } + + /** + * Get the browser accepted languages + * + * @param array $accept_langs + * @return array + * @deprecated 1.6 No longer used - using content negotiation. + */ + public function getBrowserLanguages($accept_langs = []) + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, no longer used', E_USER_DEPRECATED); + + if (empty($this->http_accept_language)) { + if (empty($accept_langs) && isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { + $accept_langs = $_SERVER['HTTP_ACCEPT_LANGUAGE']; + } else { + return $accept_langs; + } + + $langs = []; + + foreach (explode(',', $accept_langs) as $k => $pref) { + // split $pref again by ';q=' + // and decorate the language entries by inverted position + if (false !== ($i = strpos($pref, ';q='))) { + $langs[substr($pref, 0, $i)] = [(float)substr($pref, $i + 3), -$k]; + } else { + $langs[$pref] = [1, -$k]; + } + } + arsort($langs); + + // no need to undecorate, because we're only interested in the keys + $this->http_accept_language = array_keys($langs); + } + return $this->http_accept_language; + } + + /** + * Accessible wrapper to LanguageCodes + * + * @param string $code + * @param string $type + * @return string|false + */ + public function getLanguageCode($code, $type = 'name') + { + return LanguageCodes::get($code, $type); + } + + /** + * @return array + */ + #[\ReturnTypeWillChange] + public function __debugInfo() + { + $vars = get_object_vars($this); + unset($vars['grav'], $vars['config']); + + return $vars; + } + + /** + * @return array + */ + protected function getTranslatedLanguages(): array + { + if ($this->config->get('system.languages.translations_fallback', true)) { + $languages = $this->getFallbackLanguages(); + } else { + $languages = [$this->getLanguage()]; + } + + $languages[] = 'en'; + + return array_values(array_unique($languages)); + } +} diff --git a/system/src/Grav/Common/Language/LanguageCodes.php b/system/src/Grav/Common/Language/LanguageCodes.php new file mode 100644 index 0000000..86efd89 --- /dev/null +++ b/system/src/Grav/Common/Language/LanguageCodes.php @@ -0,0 +1,246 @@ + [ 'name' => 'Afrikaans', 'nativeName' => 'Afrikaans' ], + 'ak' => [ 'name' => 'Akan', 'nativeName' => 'Akan' ], // unverified native name + 'ast' => [ 'name' => 'Asturian', 'nativeName' => 'Asturianu' ], + 'ar' => [ 'name' => 'Arabic', 'nativeName' => 'عربي', 'orientation' => 'rtl'], + 'as' => [ 'name' => 'Assamese', 'nativeName' => 'অসমীয়া' ], + 'be' => [ 'name' => 'Belarusian', 'nativeName' => 'Беларуская' ], + 'bg' => [ 'name' => 'Bulgarian', 'nativeName' => 'Български' ], + 'bn' => [ 'name' => 'Bengali', 'nativeName' => 'বাংলা' ], + 'bn-BD' => [ 'name' => 'Bengali (Bangladesh)', 'nativeName' => 'বাংলা (বাংলাদেশ)' ], + 'bn-IN' => [ 'name' => 'Bengali (India)', 'nativeName' => 'বাংলা (ভারত)' ], + 'br' => [ 'name' => 'Breton', 'nativeName' => 'Brezhoneg' ], + 'bs' => [ 'name' => 'Bosnian', 'nativeName' => 'Bosanski' ], + 'ca' => [ 'name' => 'Catalan', 'nativeName' => 'Català' ], + 'ca-valencia'=> [ 'name' => 'Catalan (Valencian)', 'nativeName' => 'Català (valencià)' ], // not iso-639-1. a=l10n-drivers + 'cs' => [ 'name' => 'Czech', 'nativeName' => 'Čeština' ], + 'cy' => [ 'name' => 'Welsh', 'nativeName' => 'Cymraeg' ], + 'da' => [ 'name' => 'Danish', 'nativeName' => 'Dansk' ], + 'de' => [ 'name' => 'German', 'nativeName' => 'Deutsch' ], + 'de-AT' => [ 'name' => 'German (Austria)', 'nativeName' => 'Deutsch (Österreich)' ], + 'de-CH' => [ 'name' => 'German (Switzerland)', 'nativeName' => 'Deutsch (Schweiz)' ], + 'de-DE' => [ 'name' => 'German (Germany)', 'nativeName' => 'Deutsch (Deutschland)' ], + 'dsb' => [ 'name' => 'Lower Sorbian', 'nativeName' => 'Dolnoserbšćina' ], // iso-639-2 + 'el' => [ 'name' => 'Greek', 'nativeName' => 'Ελληνικά' ], + 'en' => [ 'name' => 'English', 'nativeName' => 'English' ], + 'en-AU' => [ 'name' => 'English (Australian)', 'nativeName' => 'English (Australian)' ], + 'en-CA' => [ 'name' => 'English (Canadian)', 'nativeName' => 'English (Canadian)' ], + 'en-GB' => [ 'name' => 'English (British)', 'nativeName' => 'English (British)' ], + 'en-NZ' => [ 'name' => 'English (New Zealand)', 'nativeName' => 'English (New Zealand)' ], + 'en-US' => [ 'name' => 'English (US)', 'nativeName' => 'English (US)' ], + 'en-ZA' => [ 'name' => 'English (South African)', 'nativeName' => 'English (South African)' ], + 'eo' => [ 'name' => 'Esperanto', 'nativeName' => 'Esperanto' ], + 'es' => [ 'name' => 'Spanish', 'nativeName' => 'Español' ], + 'es-AR' => [ 'name' => 'Spanish (Argentina)', 'nativeName' => 'Español (de Argentina)' ], + 'es-CL' => [ 'name' => 'Spanish (Chile)', 'nativeName' => 'Español (de Chile)' ], + 'es-ES' => [ 'name' => 'Spanish (Spain)', 'nativeName' => 'Español (de España)' ], + 'es-MX' => [ 'name' => 'Spanish (Mexico)', 'nativeName' => 'Español (de México)' ], + 'et' => [ 'name' => 'Estonian', 'nativeName' => 'Eesti keel' ], + 'eu' => [ 'name' => 'Basque', 'nativeName' => 'Euskara' ], + 'fa' => [ 'name' => 'Persian', 'nativeName' => 'فارسی' , 'orientation' => 'rtl' ], + 'fi' => [ 'name' => 'Finnish', 'nativeName' => 'Suomi' ], + 'fj-FJ' => [ 'name' => 'Fijian', 'nativeName' => 'Vosa vaka-Viti' ], + 'fr' => [ 'name' => 'French', 'nativeName' => 'Français' ], + 'fr-CA' => [ 'name' => 'French (Canada)', 'nativeName' => 'Français (Canada)' ], + 'fr-FR' => [ 'name' => 'French (France)', 'nativeName' => 'Français (France)' ], + 'fur' => [ 'name' => 'Friulian', 'nativeName' => 'Furlan' ], + 'fur-IT' => [ 'name' => 'Friulian', 'nativeName' => 'Furlan' ], + 'fy' => [ 'name' => 'Frisian', 'nativeName' => 'Frysk' ], + 'fy-NL' => [ 'name' => 'Frisian', 'nativeName' => 'Frysk' ], + 'ga' => [ 'name' => 'Irish', 'nativeName' => 'Gaeilge' ], + 'ga-IE' => [ 'name' => 'Irish (Ireland)', 'nativeName' => 'Gaeilge (Éire)' ], + 'gd' => [ 'name' => 'Gaelic (Scotland)', 'nativeName' => 'Gàidhlig' ], + 'gl' => [ 'name' => 'Galician', 'nativeName' => 'Galego' ], + 'gu' => [ 'name' => 'Gujarati', 'nativeName' => 'ગુજરાતી' ], + 'gu-IN' => [ 'name' => 'Gujarati', 'nativeName' => 'ગુજરાતી' ], + 'he' => [ 'name' => 'Hebrew', 'nativeName' => 'עברית', 'orientation' => 'rtl' ], + 'hi' => [ 'name' => 'Hindi', 'nativeName' => 'हिन्दी' ], + 'hi-IN' => [ 'name' => 'Hindi (India)', 'nativeName' => 'हिन्दी (भारत)' ], + 'hr' => [ 'name' => 'Croatian', 'nativeName' => 'Hrvatski' ], + 'hsb' => [ 'name' => 'Upper Sorbian', 'nativeName' => 'Hornjoserbsce' ], + 'hu' => [ 'name' => 'Hungarian', 'nativeName' => 'Magyar' ], + 'hy' => [ 'name' => 'Armenian', 'nativeName' => 'Հայերեն' ], + 'hy-AM' => [ 'name' => 'Armenian', 'nativeName' => 'Հայերեն' ], + 'id' => [ 'name' => 'Indonesian', 'nativeName' => 'Bahasa Indonesia' ], + 'is' => [ 'name' => 'Icelandic', 'nativeName' => 'íslenska' ], + 'it' => [ 'name' => 'Italian', 'nativeName' => 'Italiano' ], + 'ja' => [ 'name' => 'Japanese', 'nativeName' => '日本語' ], + 'ja-JP' => [ 'name' => 'Japanese', 'nativeName' => '日本語' ], // not iso-639-1 + 'ka' => [ 'name' => 'Georgian', 'nativeName' => 'ქართული' ], + 'kk' => [ 'name' => 'Kazakh', 'nativeName' => 'Қазақ' ], + 'km' => [ 'name' => 'Khmer', 'nativeName' => 'Khmer' ], + 'kn' => [ 'name' => 'Kannada', 'nativeName' => 'ಕನ್ನಡ' ], + 'ko' => [ 'name' => 'Korean', 'nativeName' => '한국어' ], + 'ku' => [ 'name' => 'Kurdish', 'nativeName' => 'Kurdî' ], + 'la' => [ 'name' => 'Latin', 'nativeName' => 'Latina' ], + 'lb' => [ 'name' => 'Luxembourgish', 'nativeName' => 'Lëtzebuergesch' ], + 'lg' => [ 'name' => 'Luganda', 'nativeName' => 'Luganda' ], + 'lo' => [ 'name' => 'Lao', 'nativeName' => 'Lao' ], + 'lt' => [ 'name' => 'Lithuanian', 'nativeName' => 'Lietuvių' ], + 'lv' => [ 'name' => 'Latvian', 'nativeName' => 'Latviešu' ], + 'mai' => [ 'name' => 'Maithili', 'nativeName' => 'मैथिली মৈথিলী' ], + 'mg' => [ 'name' => 'Malagasy', 'nativeName' => 'Malagasy' ], + 'mi' => [ 'name' => 'Maori (Aotearoa)', 'nativeName' => 'Māori (Aotearoa)' ], + 'mk' => [ 'name' => 'Macedonian', 'nativeName' => 'Македонски' ], + 'ml' => [ 'name' => 'Malayalam', 'nativeName' => 'മലയാളം' ], + 'mn' => [ 'name' => 'Mongolian', 'nativeName' => 'Монгол' ], + 'mr' => [ 'name' => 'Marathi', 'nativeName' => 'मराठी' ], + 'my' => [ 'name' => 'Myanmar (Burmese)', 'nativeName' => 'ဗမာी' ], + 'no' => [ 'name' => 'Norwegian', 'nativeName' => 'Norsk' ], + 'nb' => [ 'name' => 'Norwegian', 'nativeName' => 'Norsk' ], + 'nb-NO' => [ 'name' => 'Norwegian (Bokmål)', 'nativeName' => 'Norsk bokmål' ], + 'ne-NP' => [ 'name' => 'Nepali', 'nativeName' => 'नेपाली' ], + 'nn-NO' => [ 'name' => 'Norwegian (Nynorsk)', 'nativeName' => 'Norsk nynorsk' ], + 'nl' => [ 'name' => 'Dutch', 'nativeName' => 'Nederlands' ], + 'nr' => [ 'name' => 'Ndebele, South', 'nativeName' => 'IsiNdebele' ], + 'nso' => [ 'name' => 'Northern Sotho', 'nativeName' => 'Sepedi' ], + 'oc' => [ 'name' => 'Occitan (Lengadocian)', 'nativeName' => 'Occitan (lengadocian)' ], + 'or' => [ 'name' => 'Oriya', 'nativeName' => 'ଓଡ଼ିଆ' ], + 'pa' => [ 'name' => 'Punjabi', 'nativeName' => 'ਪੰਜਾਬੀ' ], + 'pa-IN' => [ 'name' => 'Punjabi', 'nativeName' => 'ਪੰਜਾਬੀ' ], + 'pl' => [ 'name' => 'Polish', 'nativeName' => 'Polski' ], + 'pt' => [ 'name' => 'Portuguese', 'nativeName' => 'Português' ], + 'pt-BR' => [ 'name' => 'Portuguese (Brazilian)', 'nativeName' => 'Português (do Brasil)' ], + 'pt-PT' => [ 'name' => 'Portuguese (Portugal)', 'nativeName' => 'Português (Europeu)' ], + 'ro' => [ 'name' => 'Romanian', 'nativeName' => 'Română' ], + 'rm' => [ 'name' => 'Romansh', 'nativeName' => 'Rumantsch' ], + 'ru' => [ 'name' => 'Russian', 'nativeName' => 'Русский' ], + 'rw' => [ 'name' => 'Kinyarwanda', 'nativeName' => 'Ikinyarwanda' ], + 'si' => [ 'name' => 'Sinhala', 'nativeName' => 'සිංහල' ], + 'sk' => [ 'name' => 'Slovak', 'nativeName' => 'Slovenčina' ], + 'sl' => [ 'name' => 'Slovenian', 'nativeName' => 'Slovensko' ], + 'son' => [ 'name' => 'Songhai', 'nativeName' => 'Soŋay' ], + 'sq' => [ 'name' => 'Albanian', 'nativeName' => 'Shqip' ], + 'sr' => [ 'name' => 'Serbian', 'nativeName' => 'Српски' ], + 'sr-Latn' => [ 'name' => 'Serbian', 'nativeName' => 'Srpski' ], // follows RFC 4646 + 'ss' => [ 'name' => 'Siswati', 'nativeName' => 'siSwati' ], + 'st' => [ 'name' => 'Southern Sotho', 'nativeName' => 'Sesotho' ], + 'sv' => [ 'name' => 'Swedish', 'nativeName' => 'Svenska' ], + 'sv-SE' => [ 'name' => 'Swedish', 'nativeName' => 'Svenska' ], + 'sw' => [ 'name' => 'Swahili', 'nativeName' => 'Swahili' ], + 'ta' => [ 'name' => 'Tamil', 'nativeName' => 'தமிழ்' ], + 'ta-IN' => [ 'name' => 'Tamil (India)', 'nativeName' => 'தமிழ் (இந்தியா)' ], + 'ta-LK' => [ 'name' => 'Tamil (Sri Lanka)', 'nativeName' => 'தமிழ் (இலங்கை)' ], + 'te' => [ 'name' => 'Telugu', 'nativeName' => 'తెలుగు' ], + 'th' => [ 'name' => 'Thai', 'nativeName' => 'ไทย' ], + 'tlh' => [ 'name' => 'Klingon', 'nativeName' => 'Klingon' ], + 'tn' => [ 'name' => 'Tswana', 'nativeName' => 'Setswana' ], + 'tr' => [ 'name' => 'Turkish', 'nativeName' => 'Türkçe' ], + 'ts' => [ 'name' => 'Tsonga', 'nativeName' => 'Xitsonga' ], + 'tt' => [ 'name' => 'Tatar', 'nativeName' => 'Tatarça' ], + 'tt-RU' => [ 'name' => 'Tatar', 'nativeName' => 'Tatarça' ], + 'uk' => [ 'name' => 'Ukrainian', 'nativeName' => 'Українська' ], + 'ur' => [ 'name' => 'Urdu', 'nativeName' => 'اُردو', 'orientation' => 'rtl' ], + 've' => [ 'name' => 'Venda', 'nativeName' => 'Tshivenḓa' ], + 'vi' => [ 'name' => 'Vietnamese', 'nativeName' => 'Tiếng Việt' ], + 'wo' => [ 'name' => 'Wolof', 'nativeName' => 'Wolof' ], + 'xh' => [ 'name' => 'Xhosa', 'nativeName' => 'isiXhosa' ], + 'yi' => [ 'name' => 'Yiddish', 'nativeName' => 'ייִדיש', 'orientation' => 'rtl' ], + 'ydd' => [ 'name' => 'Yiddish', 'nativeName' => 'ייִדיש', 'orientation' => 'rtl' ], + 'zh' => [ 'name' => 'Chinese (Simplified)', 'nativeName' => '中文 (简体)' ], + 'zh-CN' => [ 'name' => 'Chinese (Simplified)', 'nativeName' => '中文 (简体)' ], + 'zh-TW' => [ 'name' => 'Chinese (Traditional)', 'nativeName' => '正體中文 (繁體)' ], + 'zu' => [ 'name' => 'Zulu', 'nativeName' => 'isiZulu' ] + ]; + + /** + * @param string $code + * @return string|false + */ + public static function getName($code) + { + return static::get($code, 'name'); + } + + /** + * @param string $code + * @return string|false + */ + public static function getNativeName($code) + { + if (isset(static::$codes[$code])) { + return static::get($code, 'nativeName'); + } + + if (preg_match('/[a-zA-Z]{2}-[a-zA-Z]{2}/', $code)) { + return static::get(substr($code, 0, 2), 'nativeName') . ' (' . substr($code, -2) . ')'; + } + + return $code; + } + + /** + * @param string $code + * @return string + */ + public static function getOrientation($code) + { + return static::$codes[$code]['orientation'] ?? 'ltr'; + } + + /** + * @param string $code + * @return bool + */ + public static function isRtl($code) + { + return static::getOrientation($code) === 'rtl'; + } + + /** + * @param array $keys + * @return array + */ + public static function getNames(array $keys) + { + $results = []; + foreach ($keys as $key) { + if (isset(static::$codes[$key])) { + $results[$key] = static::$codes[$key]; + } + } + return $results; + } + + /** + * @param string $code + * @param string $type + * @return string|false + */ + public static function get($code, $type) + { + return static::$codes[$code][$type] ?? false; + } + + /** + * @param bool $native + * @return array + */ + public static function getList($native = true) + { + $list = []; + foreach (static::$codes as $key => $names) { + $list[$key] = $native ? $names['nativeName'] : $names['name']; + } + + return $list; + } +} diff --git a/system/src/Grav/Common/Markdown/Parsedown.php b/system/src/Grav/Common/Markdown/Parsedown.php new file mode 100644 index 0000000..bd2ab90 --- /dev/null +++ b/system/src/Grav/Common/Markdown/Parsedown.php @@ -0,0 +1,43 @@ + $defaults]; + } + $excerpts = new Excerpts($excerpts, $defaults); + user_error(__CLASS__ . '::' . __FUNCTION__ . '($page, $defaults) is deprecated since Grav 1.6.10, use new ' . __CLASS__ . '(new ' . Excerpts::class . '($page, [\'markdown\' => $defaults])) instead.', E_USER_DEPRECATED); + } + + $this->init($excerpts, $defaults); + } +} diff --git a/system/src/Grav/Common/Markdown/ParsedownExtra.php b/system/src/Grav/Common/Markdown/ParsedownExtra.php new file mode 100644 index 0000000..3ec8080 --- /dev/null +++ b/system/src/Grav/Common/Markdown/ParsedownExtra.php @@ -0,0 +1,46 @@ + $defaults]; + } + $excerpts = new Excerpts($excerpts, $defaults); + user_error(__CLASS__ . '::' . __FUNCTION__ . '($page, $defaults) is deprecated since Grav 1.6.10, use new ' . __CLASS__ . '(new ' . Excerpts::class . '($page, [\'markdown\' => $defaults])) instead.', E_USER_DEPRECATED); + } + + parent::__construct(); + + $this->init($excerpts, $defaults); + } +} diff --git a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php new file mode 100644 index 0000000..3a6ceb4 --- /dev/null +++ b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php @@ -0,0 +1,319 @@ + $defaults]; + } + $this->excerpts = new Excerpts($excerpts, $defaults); + user_error(__CLASS__ . '::' . __FUNCTION__ . '($page, $defaults) is deprecated since Grav 1.6.10, use ->init(new ' . Excerpts::class . '($page, [\'markdown\' => $defaults])) instead.', E_USER_DEPRECATED); + } else { + $this->excerpts = $excerpts; + } + + $this->BlockTypes['{'][] = 'TwigTag'; + $this->special_chars = ['>' => 'gt', '<' => 'lt', '"' => 'quot']; + + $defaults = $this->excerpts->getConfig(); + + if (isset($defaults['markdown']['auto_line_breaks'])) { + $this->setBreaksEnabled($defaults['markdown']['auto_line_breaks']); + } + if (isset($defaults['markdown']['auto_url_links'])) { + $this->setUrlsLinked($defaults['markdown']['auto_url_links']); + } + if (isset($defaults['markdown']['escape_markup'])) { + $this->setMarkupEscaped($defaults['markdown']['escape_markup']); + } + if (isset($defaults['markdown']['special_chars'])) { + $this->setSpecialChars($defaults['markdown']['special_chars']); + } + + $this->excerpts->fireInitializedEvent($this); + } + + /** + * @return Excerpts + */ + public function getExcerpts() + { + return $this->excerpts; + } + + /** + * Be able to define a new Block type or override an existing one + * + * @param string $type + * @param string $tag + * @param bool $continuable + * @param bool $completable + * @param int|null $index + * @return void + */ + public function addBlockType($type, $tag, $continuable = false, $completable = false, $index = null) + { + $block = &$this->unmarkedBlockTypes; + if ($type) { + if (!isset($this->BlockTypes[$type])) { + $this->BlockTypes[$type] = []; + } + $block = &$this->BlockTypes[$type]; + } + + if (null === $index) { + $block[] = $tag; + } else { + array_splice($block, $index, 0, [$tag]); + } + + if ($continuable) { + $this->continuable_blocks[] = $tag; + } + if ($completable) { + $this->completable_blocks[] = $tag; + } + } + + /** + * Be able to define a new Inline type or override an existing one + * + * @param string $type + * @param string $tag + * @param int|null $index + * @return void + */ + public function addInlineType($type, $tag, $index = null) + { + if (null === $index || !isset($this->InlineTypes[$type])) { + $this->InlineTypes[$type] [] = $tag; + } else { + array_splice($this->InlineTypes[$type], $index, 0, [$tag]); + } + + if (strpos($this->inlineMarkerList, $type) === false) { + $this->inlineMarkerList .= $type; + } + } + + /** + * Overrides the default behavior to allow for plugin-provided blocks to be continuable + * + * @param string $Type + * @return bool + */ + protected function isBlockContinuable($Type) + { + $continuable = in_array($Type, $this->continuable_blocks, true) + || method_exists($this, 'block' . $Type . 'Continue'); + + return $continuable; + } + + /** + * Overrides the default behavior to allow for plugin-provided blocks to be completable + * + * @param string $Type + * @return bool + */ + protected function isBlockCompletable($Type) + { + $completable = in_array($Type, $this->completable_blocks, true) + || method_exists($this, 'block' . $Type . 'Complete'); + + return $completable; + } + + + /** + * Make the element function publicly accessible, Medium uses this to render from Twig + * + * @param array $Element + * @return string markup + */ + public function elementToHtml(array $Element) + { + return $this->element($Element); + } + + /** + * Setter for special chars + * + * @param array $special_chars + * @return $this + */ + public function setSpecialChars($special_chars) + { + $this->special_chars = $special_chars; + + return $this; + } + + /** + * Ensure Twig tags are treated as block level items with no

tags + * + * @param array $line + * @return array|null + */ + protected function blockTwigTag($line) + { + if (preg_match('/(?:{{|{%|{#)(.*)(?:}}|%}|#})/', $line['body'], $matches)) { + return ['markup' => $line['body']]; + } + + return null; + } + + /** + * @param array $excerpt + * @return array|null + */ + protected function inlineSpecialCharacter($excerpt) + { + if ($excerpt['text'][0] === '&' && !preg_match('/^&#?\w+;/', $excerpt['text'])) { + return [ + 'markup' => '&', + 'extent' => 1, + ]; + } + + if (isset($this->special_chars[$excerpt['text'][0]])) { + return [ + 'markup' => '&' . $this->special_chars[$excerpt['text'][0]] . ';', + 'extent' => 1, + ]; + } + + return null; + } + + /** + * @param array $excerpt + * @return array + */ + protected function inlineImage($excerpt) + { + if (preg_match($this->twig_link_regex, $excerpt['text'], $matches)) { + $excerpt['text'] = str_replace($matches[1], '/', $excerpt['text']); + $excerpt = parent::inlineImage($excerpt); + $excerpt['element']['attributes']['src'] = $matches[1]; + $excerpt['extent'] = $excerpt['extent'] + strlen($matches[1]) - 1; + + return $excerpt; + } + + $excerpt['type'] = 'image'; + $excerpt = parent::inlineImage($excerpt); + + // if this is an image process it + if (isset($excerpt['element']['attributes']['src'])) { + $excerpt = $this->excerpts->processImageExcerpt($excerpt); + } + + return $excerpt; + } + + /** + * @param array $excerpt + * @return array + */ + protected function inlineLink($excerpt) + { + $type = $excerpt['type'] ?? 'link'; + + // do some trickery to get around Parsedown requirement for valid URL if its Twig in there + if (preg_match($this->twig_link_regex, $excerpt['text'], $matches)) { + $excerpt['text'] = str_replace($matches[1], '/', $excerpt['text']); + $excerpt = parent::inlineLink($excerpt); + $excerpt['element']['attributes']['href'] = $matches[1]; + $excerpt['extent'] = $excerpt['extent'] + strlen($matches[1]) - 1; + + return $excerpt; + } + + $excerpt = parent::inlineLink($excerpt); + + // if this is a link + if (isset($excerpt['element']['attributes']['href'])) { + $excerpt = $this->excerpts->processLinkExcerpt($excerpt, $type); + } + + return $excerpt; + } + + /** + * For extending this class via plugins + * + * @param string $method + * @param array $args + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function __call($method, $args) + { + + if (isset($this->plugins[$method]) === true) { + $func = $this->plugins[$method]; + + return call_user_func_array($func, $args); + } elseif (isset($this->{$method}) === true) { + $func = $this->{$method}; + + return call_user_func_array($func, $args); + } + + return null; + } + + public function __set($name, $value) + { + if (is_callable($value)) { + $this->plugins[$name] = $value; + } + + } + + +} diff --git a/system/src/Grav/Common/Media/Interfaces/AudioMediaInterface.php b/system/src/Grav/Common/Media/Interfaces/AudioMediaInterface.php new file mode 100644 index 0000000..0a68615 --- /dev/null +++ b/system/src/Grav/Common/Media/Interfaces/AudioMediaInterface.php @@ -0,0 +1,25 @@ +set('this.is.my.nested.variable', $value); + * + * @param string $name Dot separated path to the requested value. + * @param mixed $value New value. + * @param string|null $separator Separator, defaults to '.' + * @return $this + */ + public function set($name, $value, $separator = null); +} diff --git a/system/src/Grav/Common/Media/Interfaces/MediaPlayerInterface.php b/system/src/Grav/Common/Media/Interfaces/MediaPlayerInterface.php new file mode 100644 index 0000000..1f14080 --- /dev/null +++ b/system/src/Grav/Common/Media/Interfaces/MediaPlayerInterface.php @@ -0,0 +1,56 @@ + 'user://pages/media']; // Settings from the form field. + * $filename = $media->checkUploadedFile($uploadedFile, $filename, $settings); + * $media->copyUploadedFile($uploadedFile, $filename); + + * @param UploadedFileInterface $uploadedFile + * @param string|null $filename + * @param array|null $settings + * @return string + * @throws RuntimeException + */ + public function checkUploadedFile(UploadedFileInterface $uploadedFile, string $filename = null, array $settings = null): string; + + /** + * Copy uploaded file to the media collection. + * + * WARNING: Always check uploaded file before copying it! + * + * @example + * $filename = null; // Override filename if needed (ignored if randomizing filenames). + * $settings = ['destination' => 'user://pages/media']; // Settings from the form field. + * $filename = $media->checkUploadedFile($uploadedFile, $filename, $settings); + * $media->copyUploadedFile($uploadedFile, $filename); + * + * @param UploadedFileInterface $uploadedFile + * @param string $filename + * @param array|null $settings + * @return void + * @throws RuntimeException + */ + public function copyUploadedFile(UploadedFileInterface $uploadedFile, string $filename, array $settings = null): void; + + /** + * Delete real file from the media collection. + * + * @param string $filename + * @param array|null $settings + * @return void + */ + public function deleteFile(string $filename, array $settings = null): void; + + /** + * Rename file inside the media collection. + * + * @param string $from + * @param string $to + * @param array|null $settings + */ + public function renameFile(string $from, string $to, array $settings = null): void; +} diff --git a/system/src/Grav/Common/Media/Interfaces/VideoMediaInterface.php b/system/src/Grav/Common/Media/Interfaces/VideoMediaInterface.php new file mode 100644 index 0000000..03df0e0 --- /dev/null +++ b/system/src/Grav/Common/Media/Interfaces/VideoMediaInterface.php @@ -0,0 +1,32 @@ +attributes['controlsList'] = $controlsList; + + return $this; + } + + /** + * Parsedown element for source display mode + * + * @param array $attributes + * @param bool $reset + * @return array + */ + protected function sourceParsedownElement(array $attributes, $reset = true) + { + $location = $this->url($reset); + + return [ + 'name' => 'audio', + 'rawHtml' => 'Your browser does not support the audio tag.', + 'attributes' => $attributes + ]; + } +} diff --git a/system/src/Grav/Common/Media/Traits/ImageDecodingTrait.php b/system/src/Grav/Common/Media/Traits/ImageDecodingTrait.php new file mode 100644 index 0000000..7ea01e9 --- /dev/null +++ b/system/src/Grav/Common/Media/Traits/ImageDecodingTrait.php @@ -0,0 +1,40 @@ +get('system.images.defaults.decoding', 'auto'); + } + + // Validate the provided value (similar to loading) + if ($value !== null && $value !== 'auto') { + $this->attributes['decoding'] = $value; + } + + return $this; + } + +} \ No newline at end of file diff --git a/system/src/Grav/Common/Media/Traits/ImageFetchPriorityTrait.php b/system/src/Grav/Common/Media/Traits/ImageFetchPriorityTrait.php new file mode 100644 index 0000000..af20a97 --- /dev/null +++ b/system/src/Grav/Common/Media/Traits/ImageFetchPriorityTrait.php @@ -0,0 +1,40 @@ +get('system.images.defaults.fetchpriority', 'auto'); + } + + // Validate the provided value (similar to loading and decoding attributes) + if ($value !== null && $value !== 'auto') { + $this->attributes['fetchpriority'] = $value; + } + + return $this; + } + +} \ No newline at end of file diff --git a/system/src/Grav/Common/Media/Traits/ImageLoadingTrait.php b/system/src/Grav/Common/Media/Traits/ImageLoadingTrait.php new file mode 100644 index 0000000..ffcbd5f --- /dev/null +++ b/system/src/Grav/Common/Media/Traits/ImageLoadingTrait.php @@ -0,0 +1,37 @@ +get('system.images.defaults.loading', 'auto'); + } + if ($value && $value !== 'auto') { + $this->attributes['loading'] = $value; + } + + return $this; + } +} diff --git a/system/src/Grav/Common/Media/Traits/ImageMediaTrait.php b/system/src/Grav/Common/Media/Traits/ImageMediaTrait.php new file mode 100644 index 0000000..83b2d26 --- /dev/null +++ b/system/src/Grav/Common/Media/Traits/ImageMediaTrait.php @@ -0,0 +1,428 @@ + [0, 1], + 'forceResize' => [0, 1], + 'cropResize' => [0, 1], + 'crop' => [0, 1, 2, 3], + 'zoomCrop' => [0, 1] + ]; + + /** @var string */ + protected $sizes = '100vw'; + + + /** + * Allows the ability to override the image's pretty name stored in cache + * + * @param string $name + */ + public function setImagePrettyName($name) + { + $this->set('prettyname', $name); + if ($this->image) { + $this->image->setPrettyName($name); + } + } + + /** + * @return string + */ + public function getImagePrettyName() + { + if ($this->get('prettyname')) { + return $this->get('prettyname'); + } + + $basename = $this->get('basename'); + if (preg_match('/[a-z0-9]{40}-(.*)/', $basename, $matches)) { + $basename = $matches[1]; + } + return $basename; + } + + /** + * Simply processes with no extra methods. Useful for triggering events. + * + * @return $this + */ + public function cache() + { + if (!$this->image) { + $this->image(); + } + + return $this; + } + + /** + * Generate alternative image widths, using either an array of integers, or + * a min width, a max width, and a step parameter to fill out the necessary + * widths. Existing image alternatives won't be overwritten. + * + * @param int|int[] $min_width + * @param int $max_width + * @param int $step + * @return $this + */ + public function derivatives($min_width, $max_width = 2500, $step = 200) + { + if (!empty($this->alternatives)) { + $max = max(array_keys($this->alternatives)); + $base = $this->alternatives[$max]; + } else { + $base = $this; + } + + $widths = []; + + if (func_num_args() === 1) { + foreach ((array) func_get_arg(0) as $width) { + if ($width < $base->get('width')) { + $widths[] = $width; + } + } + } else { + $max_width = min($max_width, $base->get('width')); + + for ($width = $min_width; $width < $max_width; $width += $step) { + $widths[] = $width; + } + } + + foreach ($widths as $width) { + // Only generate image alternatives that don't already exist + if (array_key_exists((int) $width, $this->alternatives)) { + continue; + } + + $derivative = MediumFactory::fromFile($base->get('filepath')); + + // It's possible that MediumFactory::fromFile returns null if the + // original image file no longer exists and this class instance was + // retrieved from the page cache + if (null !== $derivative) { + $index = 2; + $alt_widths = array_keys($this->alternatives); + sort($alt_widths); + + foreach ($alt_widths as $i => $key) { + if ($width > $key) { + $index += max($i, 1); + } + } + + $basename = preg_replace('/(@\d+x)?$/', "@{$width}w", $base->get('basename'), 1); + $derivative->setImagePrettyName($basename); + + $ratio = $base->get('width') / $width; + $height = $derivative->get('height') / $ratio; + + $derivative->resize($width, $height); + $derivative->set('width', $width); + $derivative->set('height', $height); + + $this->addAlternative($ratio, $derivative); + } + } + + return $this; + } + + /** + * Clear out the alternatives. + */ + public function clearAlternatives() + { + $this->alternatives = []; + } + + /** + * Sets or gets the quality of the image + * + * @param int|null $quality 0-100 quality + * @return int|$this + */ + public function quality($quality = null) + { + if ($quality) { + if (!$this->image) { + $this->image(); + } + + $this->quality = $quality; + + return $this; + } + + return $this->quality; + } + + /** + * Sets image output format. + * + * @param string $format + * @return $this + */ + public function format($format) + { + if (!$this->image) { + $this->image(); + } + + $this->format = $format; + + return $this; + } + + /** + * Set or get sizes parameter for srcset media action + * + * @param string|null $sizes + * @return string + */ + public function sizes($sizes = null) + { + if ($sizes) { + $this->sizes = $sizes; + + return $this; + } + + return empty($this->sizes) ? '100vw' : $this->sizes; + } + + /** + * Allows to set the width attribute from Markdown or Twig + * Examples: ![Example](myimg.png?width=200&height=400) + * ![Example](myimg.png?resize=100,200&width=100&height=200) + * ![Example](myimg.png?width=auto&height=auto) + * ![Example](myimg.png?width&height) + * {{ page.media['myimg.png'].width().height().html }} + * {{ page.media['myimg.png'].resize(100,200).width(100).height(200).html }} + * + * @param string|int $value A value or 'auto' or empty to use the width of the image + * @return $this + */ + public function width($value = 'auto') + { + if (!$value || $value === 'auto') { + $this->attributes['width'] = $this->get('width'); + } else { + $this->attributes['width'] = $value; + } + + return $this; + } + + /** + * Allows to set the height attribute from Markdown or Twig + * Examples: ![Example](myimg.png?width=200&height=400) + * ![Example](myimg.png?resize=100,200&width=100&height=200) + * ![Example](myimg.png?width=auto&height=auto) + * ![Example](myimg.png?width&height) + * {{ page.media['myimg.png'].width().height().html }} + * {{ page.media['myimg.png'].resize(100,200).width(100).height(200).html }} + * + * @param string|int $value A value or 'auto' or empty to use the height of the image + * @return $this + */ + public function height($value = 'auto') + { + if (!$value || $value === 'auto') { + $this->attributes['height'] = $this->get('height'); + } else { + $this->attributes['height'] = $value; + } + + return $this; + } + + /** + * Filter image by using user defined filter parameters. + * + * @param string $filter Filter to be used. + * @return $this + */ + public function filter($filter = 'image.filters.default') + { + $filters = (array) $this->get($filter, []); + foreach ($filters as $params) { + $params = (array) $params; + $method = array_shift($params); + $this->__call($method, $params); + } + + return $this; + } + + /** + * Return the image higher quality version + * + * @return ImageMediaInterface|$this the alternative version with higher quality + */ + public function higherQualityAlternative() + { + if ($this->alternatives) { + /** @var ImageMedium $max */ + $max = reset($this->alternatives); + /** @var ImageMedium $alternative */ + foreach ($this->alternatives as $alternative) { + if ($alternative->quality() > $max->quality()) { + $max = $alternative; + } + } + + return $max; + } + + return $this; + } + + /** + * Gets medium image, resets image manipulation operations. + * + * @return $this + */ + protected function image() + { + $locator = Grav::instance()['locator']; + + // Use existing cache folder or if it doesn't exist, create it. + $cacheDir = $locator->findResource('cache://images', true) ?: $locator->findResource('cache://images', true, true); + + // Make sure we free previous image. + unset($this->image); + + /** @var MediaCollectionInterface $media */ + $media = $this->get('media'); + if ($media && method_exists($media, 'getImageFileObject')) { + $this->image = $media->getImageFileObject($this); + } else { + $this->image = ImageFile::open($this->get('filepath')); + } + + $this->image + ->setCacheDir($cacheDir) + ->setActualCacheDir($cacheDir) + ->setPrettyName($this->getImagePrettyName()); + + // Fix orientation if enabled + $config = Grav::instance()['config']; + if ($config->get('system.images.auto_fix_orientation', false) && + extension_loaded('exif') && function_exists('exif_read_data')) { + $this->image->fixOrientation(); + } + + // Set CLS configuration + $this->auto_sizes = $config->get('system.images.cls.auto_sizes', false); + $this->aspect_ratio = $config->get('system.images.cls.aspect_ratio', false); + $this->retina_scale = $config->get('system.images.cls.retina_scale', 1); + + $this->watermark = $config->get('system.images.watermark.watermark_all', false); + + return $this; + } + + /** + * Save the image with cache. + * + * @return string + */ + protected function saveImage() + { + if (!$this->image) { + return parent::path(false); + } + + $this->filter(); + + if (isset($this->result)) { + return $this->result; + } + + if ($this->format === 'guess') { + $extension = strtolower($this->get('extension')); + $this->format($extension); + } + + if (!$this->debug_watermarked && $this->get('debug')) { + $ratio = $this->get('ratio'); + if (!$ratio) { + $ratio = 1; + } + + $locator = Grav::instance()['locator']; + $overlay = $locator->findResource("system://assets/responsive-overlays/{$ratio}x.png") ?: $locator->findResource('system://assets/responsive-overlays/unknown.png'); + $this->image->merge(ImageFile::open($overlay)); + } + + if ($this->watermark) { + $this->watermark(); + } + + return $this->image->cacheFile($this->format, $this->quality, false, [$this->get('width'), $this->get('height'), $this->get('modified')]); + } +} diff --git a/system/src/Grav/Common/Media/Traits/MediaFileTrait.php b/system/src/Grav/Common/Media/Traits/MediaFileTrait.php new file mode 100644 index 0000000..9e3f870 --- /dev/null +++ b/system/src/Grav/Common/Media/Traits/MediaFileTrait.php @@ -0,0 +1,139 @@ +path(false); + + return file_exists($path); + } + + /** + * Get file modification time for the medium. + * + * @return int|null + */ + public function modified() + { + $path = $this->path(false); + if (!file_exists($path)) { + return null; + } + + return filemtime($path) ?: null; + } + + /** + * Get size of the medium. + * + * @return int + */ + public function size() + { + $path = $this->path(false); + if (!file_exists($path)) { + return 0; + } + + return filesize($path) ?: 0; + } + + /** + * Return PATH to file. + * + * @param bool $reset + * @return string path to file + */ + public function path($reset = true) + { + if ($reset) { + $this->reset(); + } + + return $this->get('url') ?? $this->get('filepath'); + } + + /** + * Return the relative path to file + * + * @param bool $reset + * @return string + */ + public function relativePath($reset = true) + { + if ($reset) { + $this->reset(); + } + + $path = $this->path(false); + $output = preg_replace('|^' . preg_quote(GRAV_ROOT, '|') . '|', '', $path) ?: $path; + + /** @var UniformResourceLocator $locator */ + $locator = $this->getGrav()['locator']; + if ($locator->isStream($output)) { + $output = (string)($locator->findResource($output, false) ?: $locator->findResource($output, false, true)); + } + + return $output; + } + + /** + * Return URL to file. + * + * @param bool $reset + * @return string + */ + public function url($reset = true) + { + $url = $this->get('url'); + if ($url) { + return $url; + } + + $path = $this->relativePath($reset); + + return trim($this->getGrav()['base_url'] . '/' . $this->urlQuerystring($path), '\\'); + } + + /** + * Get the URL with full querystring + * + * @param string $url + * @return string + */ + abstract public function urlQuerystring($url); + + /** + * Reset medium. + * + * @return $this + */ + abstract public function reset(); + + /** + * @return Grav + */ + abstract protected function getGrav(): Grav; +} diff --git a/system/src/Grav/Common/Media/Traits/MediaObjectTrait.php b/system/src/Grav/Common/Media/Traits/MediaObjectTrait.php new file mode 100644 index 0000000..f872dd1 --- /dev/null +++ b/system/src/Grav/Common/Media/Traits/MediaObjectTrait.php @@ -0,0 +1,630 @@ +getItems()); + } + + /** + * Set querystring to file modification timestamp (or value provided as a parameter). + * + * @param string|int|null $timestamp + * @return $this + */ + public function setTimestamp($timestamp = null) + { + if (null !== $timestamp) { + $this->timestamp = (string)($timestamp); + } elseif ($this instanceof MediaFileInterface) { + $this->timestamp = (string)$this->modified(); + } else { + $this->timestamp = ''; + } + + return $this; + } + + /** + * Returns an array containing just the metadata + * + * @return array + */ + public function metadata() + { + return $this->metadata; + } + + /** + * Add meta file for the medium. + * + * @param string $filepath + */ + abstract public function addMetaFile($filepath); + + /** + * Add alternative Medium to this Medium. + * + * @param int|float $ratio + * @param MediaObjectInterface $alternative + */ + public function addAlternative($ratio, MediaObjectInterface $alternative) + { + if (!is_numeric($ratio) || $ratio === 0) { + return; + } + + $alternative->set('ratio', $ratio); + $width = $alternative->get('width', 0); + + $this->alternatives[$width] = $alternative; + } + + /** + * @param bool $withDerived + * @return array + */ + public function getAlternatives(bool $withDerived = true): array + { + $alternatives = []; + foreach ($this->alternatives + [$this->get('width', 0) => $this] as $size => $alternative) { + if ($withDerived || $alternative->filename === Utils::basename($alternative->filepath)) { + $alternatives[$size] = $alternative; + } + } + + ksort($alternatives, SORT_NUMERIC); + + return $alternatives; + } + + /** + * Return string representation of the object (html). + * + * @return string + */ + #[\ReturnTypeWillChange] + abstract public function __toString(); + + /** + * Get/set querystring for the file's url + * + * @param string|null $querystring + * @param bool $withQuestionmark + * @return string + */ + public function querystring($querystring = null, $withQuestionmark = true) + { + if (null !== $querystring) { + $this->medium_querystring[] = ltrim($querystring, '?&'); + foreach ($this->alternatives as $alt) { + $alt->querystring($querystring, $withQuestionmark); + } + } + + if (empty($this->medium_querystring)) { + return ''; + } + + // join the strings + $querystring = implode('&', $this->medium_querystring); + // explode all strings + $query_parts = explode('&', $querystring); + // Join them again now ensure the elements are unique + $querystring = implode('&', array_unique($query_parts)); + + return $withQuestionmark ? ('?' . $querystring) : $querystring; + } + + /** + * Get the URL with full querystring + * + * @param string $url + * @return string + */ + public function urlQuerystring($url) + { + $querystring = $this->querystring(); + if (isset($this->timestamp) && !Utils::contains($querystring, $this->timestamp)) { + $querystring = empty($querystring) ? ('?' . $this->timestamp) : ($querystring . '&' . $this->timestamp); + } + + return ltrim($url . $querystring . $this->urlHash(), '/'); + } + + /** + * Get/set hash for the file's url + * + * @param string|null $hash + * @param bool $withHash + * @return string + */ + public function urlHash($hash = null, $withHash = true) + { + if ($hash) { + $this->set('urlHash', ltrim($hash, '#')); + } + + $hash = $this->get('urlHash', ''); + + return $withHash && !empty($hash) ? '#' . $hash : $hash; + } + + /** + * Get an element (is array) that can be rendered by the Parsedown engine + * + * @param string|null $title + * @param string|null $alt + * @param string|null $class + * @param string|null $id + * @param bool $reset + * @return array + */ + public function parsedownElement($title = null, $alt = null, $class = null, $id = null, $reset = true) + { + $attributes = $this->attributes; + $items = $this->getItems(); + + $style = ''; + foreach ($this->styleAttributes as $key => $value) { + if (is_numeric($key)) { // Special case for inline style attributes, refer to style() method + $style .= $value; + } else { + $style .= $key . ': ' . $value . ';'; + } + } + if ($style) { + $attributes['style'] = $style; + } + + if (empty($attributes['title'])) { + if (!empty($title)) { + $attributes['title'] = $title; + } elseif (!empty($items['title'])) { + $attributes['title'] = $items['title']; + } + } + + if (empty($attributes['alt'])) { + if (!empty($alt)) { + $attributes['alt'] = $alt; + } elseif (!empty($items['alt'])) { + $attributes['alt'] = $items['alt']; + } elseif (!empty($items['alt_text'])) { + $attributes['alt'] = $items['alt_text']; + } else { + $attributes['alt'] = ''; + } + } + + if (empty($attributes['class'])) { + if (!empty($class)) { + $attributes['class'] = $class; + } elseif (!empty($items['class'])) { + $attributes['class'] = $items['class']; + } + } + + if (empty($attributes['id'])) { + if (!empty($id)) { + $attributes['id'] = $id; + } elseif (!empty($items['id'])) { + $attributes['id'] = $items['id']; + } + } + + switch ($this->mode) { + case 'text': + $element = $this->textParsedownElement($attributes, false); + break; + case 'thumbnail': + $thumbnail = $this->getThumbnail(); + $element = $thumbnail ? $thumbnail->sourceParsedownElement($attributes, false) : []; + break; + case 'source': + $element = $this->sourceParsedownElement($attributes, false); + break; + default: + $element = []; + } + + if ($reset) { + $this->reset(); + } + + $this->display('source'); + + return $element; + } + + /** + * Reset medium. + * + * @return $this + */ + public function reset() + { + $this->attributes = []; + + return $this; + } + + /** + * Add custom attribute to medium. + * + * @param string $attribute + * @param string $value + * @return $this + */ + public function attribute($attribute = null, $value = '') + { + if (!empty($attribute)) { + $this->attributes[$attribute] = $value; + } + return $this; + } + + /** + * Switch display mode. + * + * @param string $mode + * + * @return MediaObjectInterface|null + */ + public function display($mode = 'source') + { + if ($this->mode === $mode) { + return $this; + } + + $this->mode = $mode; + if ($mode === 'thumbnail') { + $thumbnail = $this->getThumbnail(); + + return $thumbnail ? $thumbnail->reset() : null; + } + + return $this->reset(); + } + + /** + * Helper method to determine if this media item has a thumbnail or not + * + * @param string $type; + * @return bool + */ + public function thumbnailExists($type = 'page') + { + $thumbs = $this->get('thumbnails'); + + return isset($thumbs[$type]); + } + + /** + * Switch thumbnail. + * + * @param string $type + * @return $this + */ + public function thumbnail($type = 'auto') + { + if ($type !== 'auto' && !in_array($type, $this->thumbnailTypes, true)) { + return $this; + } + + if ($this->thumbnailType !== $type) { + $this->_thumbnail = null; + } + + $this->thumbnailType = $type; + + return $this; + } + + /** + * Return URL to file. + * + * @param bool $reset + * @return string + */ + abstract public function url($reset = true); + + /** + * Turn the current Medium into a Link + * + * @param bool $reset + * @param array $attributes + * @return MediaLinkInterface + */ + public function link($reset = true, array $attributes = []) + { + if ($this->mode !== 'source') { + $this->display('source'); + } + + foreach ($this->attributes as $key => $value) { + empty($attributes['data-' . $key]) && $attributes['data-' . $key] = $value; + } + + empty($attributes['href']) && $attributes['href'] = $this->url(); + + return $this->createLink($attributes); + } + + /** + * Turn the current Medium into a Link with lightbox enabled + * + * @param int|null $width + * @param int|null $height + * @param bool $reset + * @return MediaLinkInterface + */ + public function lightbox($width = null, $height = null, $reset = true) + { + $attributes = ['rel' => 'lightbox']; + + if ($width && $height) { + $attributes['data-width'] = $width; + $attributes['data-height'] = $height; + } + + return $this->link($reset, $attributes); + } + + /** + * Add a class to the element from Markdown or Twig + * Example: ![Example](myimg.png?classes=float-left) or ![Example](myimg.png?classes=myclass1,myclass2) + * + * @return $this + */ + public function classes() + { + $classes = func_get_args(); + if (!empty($classes)) { + $this->attributes['class'] = implode(',', $classes); + } + + return $this; + } + + /** + * Add an id to the element from Markdown or Twig + * Example: ![Example](myimg.png?id=primary-img) + * + * @param string $id + * @return $this + */ + public function id($id) + { + if (is_string($id)) { + $this->attributes['id'] = trim($id); + } + + return $this; + } + + /** + * Allows to add an inline style attribute from Markdown or Twig + * Example: ![Example](myimg.png?style=float:left) + * + * @param string $style + * @return $this + */ + public function style($style) + { + $this->styleAttributes[] = rtrim($style, ';') . ';'; + + return $this; + } + + /** + * Allow any action to be called on this medium from twig or markdown + * + * @param string $method + * @param array $args + * @return $this + */ + #[\ReturnTypeWillChange] + public function __call($method, $args) + { + $count = count($args); + if ($count > 1 || ($count === 1 && !empty($args[0]))) { + $method .= '=' . implode(',', array_map(static function ($a) { + if (is_array($a)) { + $a = '[' . implode(',', $a) . ']'; + } + + return rawurlencode($a); + }, $args)); + } + + if (!empty($method)) { + $this->querystring($this->querystring(null, false) . '&' . $method); + } + + return $this; + } + + /** + * Parsedown element for source display mode + * + * @param array $attributes + * @param bool $reset + * @return array + */ + protected function sourceParsedownElement(array $attributes, $reset = true) + { + return $this->textParsedownElement($attributes, $reset); + } + + /** + * Parsedown element for text display mode + * + * @param array $attributes + * @param bool $reset + * @return array + */ + protected function textParsedownElement(array $attributes, $reset = true) + { + if ($reset) { + $this->reset(); + } + + $text = $attributes['title'] ?? ''; + if ($text === '') { + $text = $attributes['alt'] ?? ''; + if ($text === '') { + $text = $this->get('filename'); + } + } + + return [ + 'name' => 'p', + 'attributes' => $attributes, + 'text' => $text + ]; + } + + /** + * Get the thumbnail Medium object + * + * @return ThumbnailImageMedium|null + */ + protected function getThumbnail() + { + if (null === $this->_thumbnail) { + $types = $this->thumbnailTypes; + + if ($this->thumbnailType !== 'auto') { + array_unshift($types, $this->thumbnailType); + } + + foreach ($types as $type) { + $thumb = $this->get("thumbnails.{$type}", false); + if ($thumb) { + $image = $thumb instanceof ThumbnailImageMedium ? $thumb : $this->createThumbnail($thumb); + if($image) { + $image->parent = $this; + $this->_thumbnail = $image; + } + break; + } + } + } + + return $this->_thumbnail; + } + + /** + * Get value by using dot notation for nested arrays/objects. + * + * @example $value = $this->get('this.is.my.nested.variable'); + * + * @param string $name Dot separated path to the requested value. + * @param mixed $default Default value (or null). + * @param string|null $separator Separator, defaults to '.' + * @return mixed Value. + */ + abstract public function get($name, $default = null, $separator = null); + + /** + * Set value by using dot notation for nested arrays/objects. + * + * @example $data->set('this.is.my.nested.variable', $value); + * + * @param string $name Dot separated path to the requested value. + * @param mixed $value New value. + * @param string|null $separator Separator, defaults to '.' + * @return $this + */ + abstract public function set($name, $value, $separator = null); + + /** + * @param string $thumb + */ + abstract protected function createThumbnail($thumb); + + /** + * @param array $attributes + * @return MediaLinkInterface + */ + abstract protected function createLink(array $attributes); + + /** + * @return array + */ + abstract protected function getItems(): array; +} diff --git a/system/src/Grav/Common/Media/Traits/MediaPlayerTrait.php b/system/src/Grav/Common/Media/Traits/MediaPlayerTrait.php new file mode 100644 index 0000000..97d79ef --- /dev/null +++ b/system/src/Grav/Common/Media/Traits/MediaPlayerTrait.php @@ -0,0 +1,113 @@ +attributes['controls'] = 'controls'; + } else { + unset($this->attributes['controls']); + } + + return $this; + } + + /** + * Allows to set the loop attribute + * + * @param bool $status + * @return $this + */ + public function loop($status = false) + { + if ($status) { + $this->attributes['loop'] = 'loop'; + } else { + unset($this->attributes['loop']); + } + + return $this; + } + + /** + * Allows to set the autoplay attribute + * + * @param bool $status + * @return $this + */ + public function autoplay($status = false) + { + if ($status) { + $this->attributes['autoplay'] = 'autoplay'; + } else { + unset($this->attributes['autoplay']); + } + + return $this; + } + + /** + * Allows to set the muted attribute + * + * @param bool $status + * @return $this + */ + public function muted($status = false) + { + if ($status) { + $this->attributes['muted'] = 'muted'; + } else { + unset($this->attributes['muted']); + } + + return $this; + } + + /** + * Allows to set the preload behaviour + * + * @param string|null $preload + * @return $this + */ + public function preload($preload = null) + { + $validPreloadAttrs = ['auto', 'metadata', 'none']; + + if (null === $preload) { + unset($this->attributes['preload']); + } elseif (in_array($preload, $validPreloadAttrs, true)) { + $this->attributes['preload'] = $preload; + } + + return $this; + } + + /** + * Reset player. + */ + public function resetPlayer() + { + $this->attributes['controls'] = 'controls'; + } +} diff --git a/system/src/Grav/Common/Media/Traits/MediaTrait.php b/system/src/Grav/Common/Media/Traits/MediaTrait.php new file mode 100644 index 0000000..93c4fdb --- /dev/null +++ b/system/src/Grav/Common/Media/Traits/MediaTrait.php @@ -0,0 +1,153 @@ +getMediaFolder(); + if (!$folder) { + return null; + } + + if (strpos($folder, '://')) { + return $folder; + } + + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $user = $locator->findResource('user://'); + if (strpos($folder, $user) === 0) { + return 'user://' . substr($folder, strlen($user)+1); + } + + return null; + } + + /** + * Gets the associated media collection. + * + * @return MediaCollectionInterface|Media Representation of associated media. + */ + public function getMedia() + { + $media = $this->media; + if (null === $media) { + $cache = $this->getMediaCache(); + $cacheKey = md5('media' . $this->getCacheKey()); + + // Use cached media if possible. + $media = $cache->get($cacheKey); + if (!$media instanceof MediaCollectionInterface) { + $media = new Media($this->getMediaFolder(), $this->getMediaOrder(), $this->_loadMedia); + $cache->set($cacheKey, $media); + } + + $this->media = $media; + } + + return $media; + } + + /** + * Sets the associated media collection. + * + * @param MediaCollectionInterface|Media $media Representation of associated media. + * @return $this + */ + protected function setMedia(MediaCollectionInterface $media) + { + $cache = $this->getMediaCache(); + $cacheKey = md5('media' . $this->getCacheKey()); + $cache->set($cacheKey, $media); + + $this->media = $media; + + return $this; + } + + /** + * @return void + */ + protected function freeMedia() + { + $this->media = null; + } + + /** + * Clear media cache. + * + * @return void + */ + protected function clearMediaCache() + { + $cache = $this->getMediaCache(); + $cacheKey = md5('media' . $this->getCacheKey()); + $cache->delete($cacheKey); + + $this->freeMedia(); + } + + /** + * @return CacheInterface + */ + protected function getMediaCache() + { + /** @var Cache $cache */ + $cache = Grav::instance()['cache']; + + return $cache->getSimpleCache(); + } + + /** + * @return string + */ + abstract protected function getCacheKey(): string; +} diff --git a/system/src/Grav/Common/Media/Traits/MediaUploadTrait.php b/system/src/Grav/Common/Media/Traits/MediaUploadTrait.php new file mode 100644 index 0000000..2b1c3bb --- /dev/null +++ b/system/src/Grav/Common/Media/Traits/MediaUploadTrait.php @@ -0,0 +1,680 @@ + true, // Whether path is in the media collection path itself. + 'avoid_overwriting' => false, // Do not override existing files (adds datetime postfix if conflict). + 'random_name' => false, // True if name needs to be randomized. + 'accept' => ['image/*'], // Accepted mime types or file extensions. + 'limit' => 10, // Maximum number of files. + 'filesize' => null, // Maximum filesize in MB. + 'destination' => null // Destination path, if empty, exception is thrown. + ]; + + /** + * Create Medium from an uploaded file. + * + * @param UploadedFileInterface $uploadedFile + * @param array $params + * @return Medium|null + */ + public function createFromUploadedFile(UploadedFileInterface $uploadedFile, array $params = []) + { + return MediumFactory::fromUploadedFile($uploadedFile, $params); + } + + /** + * Checks that uploaded file meets the requirements. Returns new filename. + * + * @example + * $filename = null; // Override filename if needed (ignored if randomizing filenames). + * $settings = ['destination' => 'user://pages/media']; // Settings from the form field. + * $filename = $media->checkUploadedFile($uploadedFile, $filename, $settings); + * $media->copyUploadedFile($uploadedFile, $filename); + * + * @param UploadedFileInterface $uploadedFile + * @param string|null $filename + * @param array|null $settings + * @return string + * @throws RuntimeException + */ + public function checkUploadedFile(UploadedFileInterface $uploadedFile, string $filename = null, array $settings = null): string + { + // Check if there is an upload error. + switch ($uploadedFile->getError()) { + case UPLOAD_ERR_OK: + break; + case UPLOAD_ERR_INI_SIZE: + case UPLOAD_ERR_FORM_SIZE: + throw new RuntimeException($this->translate('PLUGIN_ADMIN.EXCEEDED_FILESIZE_LIMIT'), 400); + case UPLOAD_ERR_PARTIAL: + case UPLOAD_ERR_NO_FILE: + if (!$uploadedFile instanceof FormFlashFile) { + throw new RuntimeException($this->translate('PLUGIN_ADMIN.NO_FILES_SENT'), 400); + } + break; + case UPLOAD_ERR_NO_TMP_DIR: + throw new RuntimeException($this->translate('PLUGIN_ADMIN.UPLOAD_ERR_NO_TMP_DIR'), 400); + case UPLOAD_ERR_CANT_WRITE: + case UPLOAD_ERR_EXTENSION: + default: + throw new RuntimeException($this->translate('PLUGIN_ADMIN.UNKNOWN_ERRORS'), 400); + } + + $metadata = [ + 'filename' => $uploadedFile->getClientFilename(), + 'mime' => $uploadedFile->getClientMediaType(), + 'size' => $uploadedFile->getSize(), + ]; + + if ($uploadedFile instanceof FormFlashFile) { + $uploadedFile->checkXss(); + } + + return $this->checkFileMetadata($metadata, $filename, $settings); + } + + /** + * Checks that file metadata meets the requirements. Returns new filename. + * + * @param array $metadata + * @param array|null $settings + * @return string + * @throws RuntimeException + */ + public function checkFileMetadata(array $metadata, string $filename = null, array $settings = null): string + { + // Add the defaults to the settings. + $settings = $this->getUploadSettings($settings); + + // Destination is always needed (but it can be set in defaults). + $self = $settings['self'] ?? false; + if (!isset($settings['destination']) && $self === false) { + throw new RuntimeException($this->translate('PLUGIN_ADMIN.DESTINATION_NOT_SPECIFIED'), 400); + } + + if (null === $filename) { + // If no filename is given, use the filename from the uploaded file (path is not allowed). + $folder = ''; + $filename = $metadata['filename'] ?? ''; + } else { + // If caller sets the filename, we will accept any custom path. + $folder = dirname($filename); + if ($folder === '.') { + $folder = ''; + } + $filename = Utils::basename($filename); + } + $extension = Utils::pathinfo($filename, PATHINFO_EXTENSION); + + // Decide which filename to use. + if ($settings['random_name']) { + // Generate random filename if asked for. + $filename = mb_strtolower(Utils::generateRandomString(15) . '.' . $extension); + } + + // Handle conflicting filename if needed. + if ($settings['avoid_overwriting']) { + $destination = $settings['destination']; + if ($destination && $this->fileExists($filename, $destination)) { + $filename = date('YmdHis') . '-' . $filename; + } + } + $filepath = $folder . $filename; + + // Check if the filename is allowed. + if (!Utils::checkFilename($filepath)) { + throw new RuntimeException( + sprintf($this->translate('PLUGIN_ADMIN.FILEUPLOAD_UNABLE_TO_UPLOAD'), $filepath, $this->translate('PLUGIN_ADMIN.BAD_FILENAME')) + ); + } + + // Check if the file extension is allowed. + $extension = mb_strtolower($extension); + if (!$extension || !$this->getConfig()->get("media.types.{$extension}")) { + // Not a supported type. + throw new RuntimeException($this->translate('PLUGIN_ADMIN.UNSUPPORTED_FILE_TYPE') . ': ' . $extension, 400); + } + + // Calculate maximum file size (from MB). + $filesize = $settings['filesize']; + if ($filesize) { + $max_filesize = $filesize * 1048576; + if ($metadata['size'] > $max_filesize) { + // TODO: use own language string + throw new RuntimeException($this->translate('PLUGIN_ADMIN.EXCEEDED_GRAV_FILESIZE_LIMIT'), 400); + } + } elseif (null === $filesize) { + // Check size against the Grav upload limit. + $grav_limit = Utils::getUploadLimit(); + if ($grav_limit > 0 && $metadata['size'] > $grav_limit) { + throw new RuntimeException($this->translate('PLUGIN_ADMIN.EXCEEDED_GRAV_FILESIZE_LIMIT'), 400); + } + } + + $grav = Grav::instance(); + /** @var MimeTypes $mimeChecker */ + $mimeChecker = $grav['mime']; + + // Handle Accepted file types. Accept can only be mime types (image/png | image/*) or file extensions (.pdf | .jpg) + // Do not trust mime type sent by the browser. + $mime = $metadata['mime'] ?? $mimeChecker->getMimeType($extension); + $validExtensions = $mimeChecker->getExtensions($mime); + if (!in_array($extension, $validExtensions, true)) { + throw new RuntimeException('The mime type does not match to file extension', 400); + } + + $accepted = false; + $errors = []; + foreach ((array)$settings['accept'] as $type) { + // Force acceptance of any file when star notation + if ($type === '*') { + $accepted = true; + break; + } + + $isMime = strstr($type, '/'); + $find = str_replace(['.', '*', '+'], ['\.', '.*', '\+'], $type); + + if ($isMime) { + $match = preg_match('#' . $find . '$#', $mime); + if (!$match) { + // TODO: translate + $errors[] = 'The MIME type "' . $mime . '" for the file "' . $filepath . '" is not an accepted.'; + } else { + $accepted = true; + break; + } + } else { + $match = preg_match('#' . $find . '$#', $filename); + if (!$match) { + // TODO: translate + $errors[] = 'The File Extension for the file "' . $filepath . '" is not an accepted.'; + } else { + $accepted = true; + break; + } + } + } + if (!$accepted) { + throw new RuntimeException(implode('
', $errors), 400); + } + + return $filepath; + } + + /** + * Copy uploaded file to the media collection. + * + * WARNING: Always check uploaded file before copying it! + * + * @example + * $settings = ['destination' => 'user://pages/media']; // Settings from the form field. + * $filename = $media->checkUploadedFile($uploadedFile, $filename, $settings); + * $media->copyUploadedFile($uploadedFile, $filename, $settings); + * + * @param UploadedFileInterface $uploadedFile + * @param string $filename + * @param array|null $settings + * @return void + * @throws RuntimeException + */ + public function copyUploadedFile(UploadedFileInterface $uploadedFile, string $filename, array $settings = null): void + { + // Add the defaults to the settings. + $settings = $this->getUploadSettings($settings); + + $path = $settings['destination'] ?? $this->getPath(); + if (!$path || !$filename) { + throw new RuntimeException($this->translate('PLUGIN_ADMIN.FAILED_TO_MOVE_UPLOADED_FILE'), 400); + } + + /** @var UniformResourceLocator $locator */ + $locator = $this->getGrav()['locator']; + + try { + // Clear locator cache to make sure we have up to date information from the filesystem. + $locator->clearCache(); + $this->clearCache(); + + $filesystem = Filesystem::getInstance(false); + + // Calculate path without the retina scaling factor. + $basename = $filesystem->basename($filename); + $pathname = $filesystem->pathname($filename); + + // Get name for the uploaded file. + [$base, $ext,,] = $this->getFileParts($basename); + $name = "{$pathname}{$base}.{$ext}"; + + // Upload file. + if ($uploadedFile instanceof FormFlashFile) { + // FormFlashFile needs some additional logic. + if ($uploadedFile->getError() === \UPLOAD_ERR_OK) { + // Move uploaded file. + $this->doMoveUploadedFile($uploadedFile, $filename, $path); + } elseif (strpos($filename, 'original/') === 0 && !$this->fileExists($filename, $path) && $this->fileExists($basename, $path)) { + // Original image support: override original image if it's the same as the uploaded image. + $this->doCopy($basename, $filename, $path); + } + + // FormFlashFile may also contain metadata. + $metadata = $uploadedFile->getMetaData(); + if ($metadata) { + // TODO: This overrides metadata if used with multiple retina image sizes. + $this->doSaveMetadata(['upload' => $metadata], $name, $path); + } + } else { + // Not a FormFlashFile. + $this->doMoveUploadedFile($uploadedFile, $filename, $path); + } + + // Post-processing: Special content sanitization for SVG. + $mime = Utils::getMimeByFilename($filename); + if (Utils::contains($mime, 'svg', false)) { + $this->doSanitizeSvg($filename, $path); + } + + // Add the new file into the media. + // TODO: This overrides existing media sizes if used with multiple retina image sizes. + $this->doAddUploadedMedium($name, $filename, $path); + + } catch (Exception $e) { + throw new RuntimeException($this->translate('PLUGIN_ADMIN.FAILED_TO_MOVE_UPLOADED_FILE') . $e->getMessage(), 400); + } finally { + // Finally clear media cache. + $locator->clearCache(); + $this->clearCache(); + } + } + + /** + * Delete real file from the media collection. + * + * @param string $filename + * @param array|null $settings + * @return void + * @throws RuntimeException + */ + public function deleteFile(string $filename, array $settings = null): void + { + // Add the defaults to the settings. + $settings = $this->getUploadSettings($settings); + $filesystem = Filesystem::getInstance(false); + + // First check for allowed filename. + $basename = $filesystem->basename($filename); + if (!Utils::checkFilename($basename)) { + throw new RuntimeException($this->translate('PLUGIN_ADMIN.FILE_COULD_NOT_BE_DELETED') . ": {$this->translate('PLUGIN_ADMIN.BAD_FILENAME')}: " . $filename, 400); + } + + $path = $settings['destination'] ?? $this->getPath(); + if (!$path) { + return; + } + + /** @var UniformResourceLocator $locator */ + $locator = $this->getGrav()['locator']; + $locator->clearCache(); + + $pathname = $filesystem->pathname($filename); + + // Get base name of the file. + [$base, $ext,,] = $this->getFileParts($basename); + $name = "{$pathname}{$base}.{$ext}"; + + // Remove file and all all the associated metadata. + $this->doRemove($name, $path); + + // Finally clear media cache. + $locator->clearCache(); + $this->clearCache(); + } + + /** + * Rename file inside the media collection. + * + * @param string $from + * @param string $to + * @param array|null $settings + */ + public function renameFile(string $from, string $to, array $settings = null): void + { + // Add the defaults to the settings. + $settings = $this->getUploadSettings($settings); + $filesystem = Filesystem::getInstance(false); + + $path = $settings['destination'] ?? $this->getPath(); + if (!$path) { + // TODO: translate error message + throw new RuntimeException('Failed to rename file: Bad destination', 400); + } + + /** @var UniformResourceLocator $locator */ + $locator = $this->getGrav()['locator']; + $locator->clearCache(); + + // Get base name of the file. + $pathname = $filesystem->pathname($from); + + // Remove @2x, @3x and .meta.yaml + [$base, $ext,,] = $this->getFileParts($filesystem->basename($from)); + $from = "{$pathname}{$base}.{$ext}"; + + [$base, $ext,,] = $this->getFileParts($filesystem->basename($to)); + $to = "{$pathname}{$base}.{$ext}"; + + $this->doRename($from, $to, $path); + + // Finally clear media cache. + $locator->clearCache(); + $this->clearCache(); + } + + /** + * Internal logic to move uploaded file. + * + * @param UploadedFileInterface $uploadedFile + * @param string $filename + * @param string $path + */ + protected function doMoveUploadedFile(UploadedFileInterface $uploadedFile, string $filename, string $path): void + { + $filepath = sprintf('%s/%s', $path, $filename); + + /** @var UniformResourceLocator $locator */ + $locator = $this->getGrav()['locator']; + + // Do not use streams internally. + if ($locator->isStream($filepath)) { + $filepath = (string)$locator->findResource($filepath, true, true); + } + + Folder::create(dirname($filepath)); + + $uploadedFile->moveTo($filepath); + } + + /** + * Get upload settings. + * + * @param array|null $settings Form field specific settings (override). + * @return array + */ + public function getUploadSettings(?array $settings = null): array + { + return null !== $settings ? $settings + $this->_upload_defaults : $this->_upload_defaults; + } + + /** + * Internal logic to copy file. + * + * @param string $src + * @param string $dst + * @param string $path + */ + protected function doCopy(string $src, string $dst, string $path): void + { + $src = sprintf('%s/%s', $path, $src); + $dst = sprintf('%s/%s', $path, $dst); + + /** @var UniformResourceLocator $locator */ + $locator = $this->getGrav()['locator']; + + // Do not use streams internally. + if ($locator->isStream($dst)) { + $dst = (string)$locator->findResource($dst, true, true); + } + + Folder::create(dirname($dst)); + + copy($src, $dst); + } + + /** + * Internal logic to rename file. + * + * @param string $from + * @param string $to + * @param string $path + */ + protected function doRename(string $from, string $to, string $path): void + { + /** @var UniformResourceLocator $locator */ + $locator = $this->getGrav()['locator']; + + $fromPath = $path . '/' . $from; + if ($locator->isStream($fromPath)) { + $fromPath = $locator->findResource($fromPath, true, true); + } + + if (!is_file($fromPath)) { + return; + } + + $mediaPath = dirname($fromPath); + $toPath = $mediaPath . '/' . $to; + if ($locator->isStream($toPath)) { + $toPath = $locator->findResource($toPath, true, true); + } + + if (is_file($toPath)) { + // TODO: translate error message + throw new RuntimeException(sprintf('File could not be renamed: %s already exists (%s)', $to, $mediaPath), 500); + } + + $result = rename($fromPath, $toPath); + if (!$result) { + // TODO: translate error message + throw new RuntimeException(sprintf('File could not be renamed: %s -> %s (%s)', $from, $to, $mediaPath), 500); + } + + // TODO: Add missing logic to handle retina files. + if (is_file($fromPath . '.meta.yaml')) { + $result = rename($fromPath . '.meta.yaml', $toPath . '.meta.yaml'); + if (!$result) { + // TODO: translate error message + throw new RuntimeException(sprintf('Meta could not be renamed: %s -> %s (%s)', $from, $to, $mediaPath), 500); + } + } + } + + /** + * Internal logic to remove file. + * + * @param string $filename + * @param string $path + */ + protected function doRemove(string $filename, string $path): void + { + $filesystem = Filesystem::getInstance(false); + + /** @var UniformResourceLocator $locator */ + $locator = $this->getGrav()['locator']; + + // If path doesn't exist, there's nothing to do. + $pathname = $filesystem->pathname($filename); + if (!$this->fileExists($pathname, $path)) { + return; + } + + $folder = $locator->isStream($path) ? (string)$locator->findResource($path, true, true) : $path; + + // Remove requested media file. + if ($this->fileExists($filename, $path)) { + $result = unlink("{$folder}/{$filename}"); + if (!$result) { + throw new RuntimeException($this->translate('PLUGIN_ADMIN.FILE_COULD_NOT_BE_DELETED') . ': ' . $filename, 500); + } + } + + // Remove associated metadata. + $this->doRemoveMetadata($filename, $path); + + // Remove associated 2x, 3x and their .meta.yaml files. + $targetPath = rtrim(sprintf('%s/%s', $folder, $pathname), '/'); + $dir = scandir($targetPath, SCANDIR_SORT_NONE); + if (false === $dir) { + throw new RuntimeException($this->translate('PLUGIN_ADMIN.FILE_COULD_NOT_BE_DELETED') . ': ' . $filename, 500); + } + + /** @var UniformResourceLocator $locator */ + $locator = $this->getGrav()['locator']; + + $basename = $filesystem->basename($filename); + $fileParts = (array)$filesystem->pathinfo($filename); + + foreach ($dir as $file) { + $preg_name = preg_quote($fileParts['filename'], '`'); + $preg_ext = preg_quote($fileParts['extension'] ?? '.', '`'); + $preg_filename = preg_quote($basename, '`'); + + if (preg_match("`({$preg_name}@\d+x\.{$preg_ext}(?:\.meta\.yaml)?$|{$preg_filename}\.meta\.yaml)$`", $file)) { + $testPath = $targetPath . '/' . $file; + if ($locator->isStream($testPath)) { + $testPath = (string)$locator->findResource($testPath, true, true); + $locator->clearCache($testPath); + } + + if (is_file($testPath)) { + $result = unlink($testPath); + if (!$result) { + throw new RuntimeException($this->translate('PLUGIN_ADMIN.FILE_COULD_NOT_BE_DELETED') . ': ' . $filename, 500); + } + } + } + } + + $this->hide($filename); + } + + /** + * @param array $metadata + * @param string $filename + * @param string $path + */ + protected function doSaveMetadata(array $metadata, string $filename, string $path): void + { + $filepath = sprintf('%s/%s', $path, $filename); + + /** @var UniformResourceLocator $locator */ + $locator = $this->getGrav()['locator']; + + // Do not use streams internally. + if ($locator->isStream($filepath)) { + $filepath = (string)$locator->findResource($filepath, true, true); + } + + $file = YamlFile::instance($filepath . '.meta.yaml'); + $file->save($metadata); + } + + /** + * @param string $filename + * @param string $path + */ + protected function doRemoveMetadata(string $filename, string $path): void + { + $filepath = sprintf('%s/%s', $path, $filename); + + /** @var UniformResourceLocator $locator */ + $locator = $this->getGrav()['locator']; + + // Do not use streams internally. + if ($locator->isStream($filepath)) { + $filepath = (string)$locator->findResource($filepath, true); + if (!$filepath) { + return; + } + } + + $file = YamlFile::instance($filepath . '.meta.yaml'); + if ($file->exists()) { + $file->delete(); + } + } + + /** + * @param string $filename + * @param string $path + */ + protected function doSanitizeSvg(string $filename, string $path): void + { + $filepath = sprintf('%s/%s', $path, $filename); + + /** @var UniformResourceLocator $locator */ + $locator = $this->getGrav()['locator']; + + // Do not use streams internally. + if ($locator->isStream($filepath)) { + $filepath = (string)$locator->findResource($filepath, true, true); + } + + Security::sanitizeSVG($filepath); + } + + /** + * @param string $name + * @param string $filename + * @param string $path + */ + protected function doAddUploadedMedium(string $name, string $filename, string $path): void + { + $filepath = sprintf('%s/%s', $path, $filename); + $medium = $this->createFromFile($filepath); + $realpath = $path . '/' . $name; + $this->add($realpath, $medium); + } + + /** + * @param string $string + * @return string + */ + protected function translate(string $string): string + { + return $this->getLanguage()->translate($string); + } + + abstract protected function getPath(): ?string; + + abstract protected function getGrav(): Grav; + + abstract protected function getConfig(): Config; + + abstract protected function getLanguage(): Language; + + abstract protected function clearCache(): void; +} diff --git a/system/src/Grav/Common/Media/Traits/StaticResizeTrait.php b/system/src/Grav/Common/Media/Traits/StaticResizeTrait.php new file mode 100644 index 0000000..617b600 --- /dev/null +++ b/system/src/Grav/Common/Media/Traits/StaticResizeTrait.php @@ -0,0 +1,40 @@ +styleAttributes['width'] = $width . 'px'; + } else { + unset($this->styleAttributes['width']); + } + if ($height) { + $this->styleAttributes['height'] = $height . 'px'; + } else { + unset($this->styleAttributes['height']); + } + + return $this; + } +} diff --git a/system/src/Grav/Common/Media/Traits/ThumbnailMediaTrait.php b/system/src/Grav/Common/Media/Traits/ThumbnailMediaTrait.php new file mode 100644 index 0000000..e0c5d81 --- /dev/null +++ b/system/src/Grav/Common/Media/Traits/ThumbnailMediaTrait.php @@ -0,0 +1,149 @@ +bubble('parsedownElement', [$title, $alt, $class, $id, $reset]); + } + + /** + * Return HTML markup from the medium. + * + * @param string|null $title + * @param string|null $alt + * @param string|null $class + * @param string|null $id + * @param bool $reset + * @return string + */ + public function html($title = null, $alt = null, $class = null, $id = null, $reset = true) + { + return $this->bubble('html', [$title, $alt, $class, $id, $reset]); + } + + /** + * Switch display mode. + * + * @param string $mode + * + * @return MediaLinkInterface|MediaObjectInterface|null + */ + public function display($mode = 'source') + { + return $this->bubble('display', [$mode], false); + } + + /** + * Switch thumbnail. + * + * @param string $type + * + * @return MediaLinkInterface|MediaObjectInterface + */ + public function thumbnail($type = 'auto') + { + $this->bubble('thumbnail', [$type], false); + + return $this->bubble('getThumbnail', [], false); + } + + /** + * Turn the current Medium into a Link + * + * @param bool $reset + * @param array $attributes + * @return MediaLinkInterface + */ + public function link($reset = true, array $attributes = []) + { + return $this->bubble('link', [$reset, $attributes], false); + } + + /** + * Turn the current Medium into a Link with lightbox enabled + * + * @param int|null $width + * @param int|null $height + * @param bool $reset + * @return MediaLinkInterface + */ + public function lightbox($width = null, $height = null, $reset = true) + { + return $this->bubble('lightbox', [$width, $height, $reset], false); + } + + /** + * Bubble a function call up to either the superclass function or the parent Medium instance + * + * @param string $method + * @param array $arguments + * @param bool $testLinked + * @return mixed + */ + protected function bubble($method, array $arguments = [], $testLinked = true) + { + if (!$testLinked || $this->linked) { + $parent = $this->parent; + if (null === $parent) { + return $this; + } + + $closure = [$parent, $method]; + + if (!is_callable($closure)) { + throw new BadMethodCallException(get_class($parent) . '::' . $method . '() not found.'); + } + + return $closure(...$arguments); + } + + return parent::{$method}(...$arguments); + } +} diff --git a/system/src/Grav/Common/Media/Traits/VideoMediaTrait.php b/system/src/Grav/Common/Media/Traits/VideoMediaTrait.php new file mode 100644 index 0000000..1da313c --- /dev/null +++ b/system/src/Grav/Common/Media/Traits/VideoMediaTrait.php @@ -0,0 +1,68 @@ +attributes['poster'] = $urlImage; + + return $this; + } + + /** + * Allows to set the playsinline attribute + * + * @param bool $status + * @return $this + */ + public function playsinline($status = false) + { + if ($status) { + $this->attributes['playsinline'] = 'playsinline'; + } else { + unset($this->attributes['playsinline']); + } + + return $this; + } + + /** + * Parsedown element for source display mode + * + * @param array $attributes + * @param bool $reset + * @return array + */ + protected function sourceParsedownElement(array $attributes, $reset = true) + { + $location = $this->url($reset); + + return [ + 'name' => 'video', + 'rawHtml' => 'Your browser does not support the video tag.', + 'attributes' => $attributes + ]; + } +} diff --git a/system/src/Grav/Common/Page/Collection.php b/system/src/Grav/Common/Page/Collection.php new file mode 100644 index 0000000..8a62555 --- /dev/null +++ b/system/src/Grav/Common/Page/Collection.php @@ -0,0 +1,710 @@ + + */ +class Collection extends Iterator implements PageCollectionInterface +{ + /** @var Pages */ + protected $pages; + /** @var array */ + protected $params; + + /** + * Collection constructor. + * + * @param array $items + * @param array $params + * @param Pages|null $pages + */ + public function __construct($items = [], array $params = [], Pages $pages = null) + { + parent::__construct($items); + + $this->params = $params; + $this->pages = $pages ?: Grav::instance()->offsetGet('pages'); + } + + /** + * Get the collection params + * + * @return array + */ + public function params() + { + return $this->params; + } + + /** + * Set parameters to the Collection + * + * @param array $params + * @return $this + */ + public function setParams(array $params) + { + $this->params = array_merge($this->params, $params); + + return $this; + } + + /** + * Add a single page to a collection + * + * @param PageInterface $page + * @return $this + */ + public function addPage(PageInterface $page) + { + $this->items[$page->path()] = ['slug' => $page->slug()]; + + return $this; + } + + /** + * Add a page with path and slug + * + * @param string $path + * @param string $slug + * @return $this + */ + public function add($path, $slug) + { + $this->items[$path] = ['slug' => $slug]; + + return $this; + } + + /** + * + * Create a copy of this collection + * + * @return static + */ + public function copy() + { + return new static($this->items, $this->params, $this->pages); + } + + /** + * + * Merge another collection with the current collection + * + * @param PageCollectionInterface $collection + * @return $this + */ + public function merge(PageCollectionInterface $collection) + { + foreach ($collection as $page) { + $this->addPage($page); + } + + return $this; + } + + /** + * Intersect another collection with the current collection + * + * @param PageCollectionInterface $collection + * @return $this + */ + public function intersect(PageCollectionInterface $collection) + { + $array1 = $this->items; + $array2 = $collection->toArray(); + + $this->items = array_uintersect($array1, $array2, function ($val1, $val2) { + return strcmp($val1['slug'], $val2['slug']); + }); + + return $this; + } + + /** + * Set current page. + */ + public function setCurrent(string $path): void + { + reset($this->items); + + while (($key = key($this->items)) !== null && $key !== $path) { + next($this->items); + } + } + + /** + * Returns current page. + * + * @return PageInterface + */ + #[\ReturnTypeWillChange] + public function current() + { + $current = parent::key(); + + return $this->pages->get($current); + } + + /** + * Returns current slug. + * + * @return mixed + */ + #[\ReturnTypeWillChange] + public function key() + { + $current = parent::current(); + + return $current['slug']; + } + + /** + * Returns the value at specified offset. + * + * @param string $offset + * @return PageInterface|null + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->pages->get($offset) ?: null; + } + + /** + * Split collection into array of smaller collections. + * + * @param int $size + * @return Collection[] + */ + public function batch($size) + { + $chunks = array_chunk($this->items, $size, true); + + $list = []; + foreach ($chunks as $chunk) { + $list[] = new static($chunk, $this->params, $this->pages); + } + + return $list; + } + + /** + * Remove item from the list. + * + * @param PageInterface|string|null $key + * @return $this + * @throws InvalidArgumentException + */ + public function remove($key = null) + { + if ($key instanceof PageInterface) { + $key = $key->path(); + } elseif (null === $key) { + $key = (string)key($this->items); + } + if (!is_string($key)) { + throw new InvalidArgumentException('Invalid argument $key.'); + } + + parent::remove($key); + + return $this; + } + + /** + * Reorder collection. + * + * @param string $by + * @param string $dir + * @param array|null $manual + * @param string|null $sort_flags + * @return $this + */ + public function order($by, $dir = 'asc', $manual = null, $sort_flags = null) + { + $this->items = $this->pages->sortCollection($this, $by, $dir, $manual, $sort_flags); + + return $this; + } + + /** + * Check to see if this item is the first in the collection. + * + * @param string $path + * @return bool True if item is first. + */ + public function isFirst($path): bool + { + return $this->items && $path === array_keys($this->items)[0]; + } + + /** + * Check to see if this item is the last in the collection. + * + * @param string $path + * @return bool True if item is last. + */ + public function isLast($path): bool + { + return $this->items && $path === array_keys($this->items)[count($this->items) - 1]; + } + + /** + * Gets the previous sibling based on current position. + * + * @param string $path + * + * @return PageInterface The previous item. + */ + public function prevSibling($path) + { + return $this->adjacentSibling($path, -1); + } + + /** + * Gets the next sibling based on current position. + * + * @param string $path + * + * @return PageInterface The next item. + */ + public function nextSibling($path) + { + return $this->adjacentSibling($path, 1); + } + + /** + * Returns the adjacent sibling based on a direction. + * + * @param string $path + * @param int $direction either -1 or +1 + * @return PageInterface|Collection The sibling item. + */ + public function adjacentSibling($path, $direction = 1) + { + $values = array_keys($this->items); + $keys = array_flip($values); + + if (array_key_exists($path, $keys)) { + $index = $keys[$path] - $direction; + + return isset($values[$index]) ? $this->offsetGet($values[$index]) : $this; + } + + return $this; + } + + /** + * Returns the item in the current position. + * + * @param string $path the path the item + * @return int|null The index of the current page, null if not found. + */ + public function currentPosition($path): ?int + { + $pos = array_search($path, array_keys($this->items), true); + + return $pos !== false ? $pos : null; + } + + /** + * Returns the items between a set of date ranges of either the page date field (default) or + * an arbitrary datetime page field where start date and end date are optional + * Dates must be passed in as text that strtotime() can process + * http://php.net/manual/en/function.strtotime.php + * + * @param string|null $startDate + * @param string|null $endDate + * @param string|null $field + * @return $this + * @throws Exception + */ + public function dateRange($startDate = null, $endDate = null, $field = null) + { + $start = $startDate ? Utils::date2timestamp($startDate) : null; + $end = $endDate ? Utils::date2timestamp($endDate) : null; + + $date_range = []; + foreach ($this->items as $path => $slug) { + $page = $this->pages->get($path); + if (!$page) { + continue; + } + + $date = $field ? strtotime($page->value($field)) : $page->date(); + + if ((!$start || $date >= $start) && (!$end || $date <= $end)) { + $date_range[$path] = $slug; + } + } + + $this->items = $date_range; + + return $this; + } + + /** + * Creates new collection with only visible pages + * + * @return Collection The collection with only visible pages + */ + public function visible() + { + $visible = []; + + foreach ($this->items as $path => $slug) { + $page = $this->pages->get($path); + if ($page !== null && $page->visible()) { + $visible[$path] = $slug; + } + } + $this->items = $visible; + + return $this; + } + + /** + * Creates new collection with only non-visible pages + * + * @return Collection The collection with only non-visible pages + */ + public function nonVisible() + { + $visible = []; + + foreach ($this->items as $path => $slug) { + $page = $this->pages->get($path); + if ($page !== null && !$page->visible()) { + $visible[$path] = $slug; + } + } + $this->items = $visible; + + return $this; + } + + /** + * Creates new collection with only pages + * + * @return Collection The collection with only pages + */ + public function pages() + { + $modular = []; + + foreach ($this->items as $path => $slug) { + $page = $this->pages->get($path); + if ($page !== null && !$page->isModule()) { + $modular[$path] = $slug; + } + } + $this->items = $modular; + + return $this; + } + + /** + * Creates new collection with only modules + * + * @return Collection The collection with only modules + */ + public function modules() + { + $modular = []; + + foreach ($this->items as $path => $slug) { + $page = $this->pages->get($path); + if ($page !== null && $page->isModule()) { + $modular[$path] = $slug; + } + } + $this->items = $modular; + + return $this; + } + + /** + * Alias of pages() + * + * @return Collection The collection with only non-module pages + */ + public function nonModular() + { + $this->pages(); + + return $this; + } + + /** + * Alias of modules() + * + * @return Collection The collection with only modules + */ + public function modular() + { + $this->modules(); + + return $this; + } + + /** + * Creates new collection with only translated pages + * + * @return Collection The collection with only published pages + * @internal + */ + public function translated() + { + $published = []; + + foreach ($this->items as $path => $slug) { + $page = $this->pages->get($path); + if ($page !== null && $page->translated()) { + $published[$path] = $slug; + } + } + $this->items = $published; + + return $this; + } + + /** + * Creates new collection with only untranslated pages + * + * @return Collection The collection with only non-published pages + * @internal + */ + public function nonTranslated() + { + $published = []; + + foreach ($this->items as $path => $slug) { + $page = $this->pages->get($path); + if ($page !== null && !$page->translated()) { + $published[$path] = $slug; + } + } + $this->items = $published; + + return $this; + } + + /** + * Creates new collection with only published pages + * + * @return Collection The collection with only published pages + */ + public function published() + { + $published = []; + + foreach ($this->items as $path => $slug) { + $page = $this->pages->get($path); + if ($page !== null && $page->published()) { + $published[$path] = $slug; + } + } + $this->items = $published; + + return $this; + } + + /** + * Creates new collection with only non-published pages + * + * @return Collection The collection with only non-published pages + */ + public function nonPublished() + { + $published = []; + + foreach ($this->items as $path => $slug) { + $page = $this->pages->get($path); + if ($page !== null && !$page->published()) { + $published[$path] = $slug; + } + } + $this->items = $published; + + return $this; + } + + /** + * Creates new collection with only routable pages + * + * @return Collection The collection with only routable pages + */ + public function routable() + { + $routable = []; + + foreach ($this->items as $path => $slug) { + $page = $this->pages->get($path); + + if ($page !== null && $page->routable()) { + $routable[$path] = $slug; + } + } + + $this->items = $routable; + + return $this; + } + + /** + * Creates new collection with only non-routable pages + * + * @return Collection The collection with only non-routable pages + */ + public function nonRoutable() + { + $routable = []; + + foreach ($this->items as $path => $slug) { + $page = $this->pages->get($path); + if ($page !== null && !$page->routable()) { + $routable[$path] = $slug; + } + } + $this->items = $routable; + + return $this; + } + + /** + * Creates new collection with only pages of the specified type + * + * @param string $type + * @return Collection The collection + */ + public function ofType($type) + { + $items = []; + + foreach ($this->items as $path => $slug) { + $page = $this->pages->get($path); + if ($page !== null && $page->template() === $type) { + $items[$path] = $slug; + } + } + + $this->items = $items; + + return $this; + } + + /** + * Creates new collection with only pages of one of the specified types + * + * @param string[] $types + * @return Collection The collection + */ + public function ofOneOfTheseTypes($types) + { + $items = []; + + foreach ($this->items as $path => $slug) { + $page = $this->pages->get($path); + if ($page !== null && in_array($page->template(), $types, true)) { + $items[$path] = $slug; + } + } + + $this->items = $items; + + return $this; + } + + /** + * Creates new collection with only pages of one of the specified access levels + * + * @param array $accessLevels + * @return Collection The collection + */ + public function ofOneOfTheseAccessLevels($accessLevels) + { + $items = []; + + foreach ($this->items as $path => $slug) { + $page = $this->pages->get($path); + + if ($page !== null && isset($page->header()->access)) { + if (is_array($page->header()->access)) { + //Multiple values for access + $valid = false; + + foreach ($page->header()->access as $index => $accessLevel) { + if (is_array($accessLevel)) { + foreach ($accessLevel as $innerIndex => $innerAccessLevel) { + if (in_array($innerAccessLevel, $accessLevels, false)) { + $valid = true; + } + } + } else { + if (in_array($index, $accessLevels, false)) { + $valid = true; + } + } + } + if ($valid) { + $items[$path] = $slug; + } + } else { + //Single value for access + if (in_array($page->header()->access, $accessLevels, false)) { + $items[$path] = $slug; + } + } + } + } + + $this->items = $items; + + return $this; + } + + /** + * Get the extended version of this Collection with each page keyed by route + * + * @return array + * @throws Exception + */ + public function toExtendedArray() + { + $items = []; + foreach ($this->items as $path => $slug) { + $page = $this->pages->get($path); + + if ($page !== null) { + $items[$page->route()] = $page->toArray(); + } + } + return $items; + } +} diff --git a/system/src/Grav/Common/Page/Header.php b/system/src/Grav/Common/Page/Header.php new file mode 100644 index 0000000..a562b17 --- /dev/null +++ b/system/src/Grav/Common/Page/Header.php @@ -0,0 +1,38 @@ +toArray(); + } +} diff --git a/system/src/Grav/Common/Page/Interfaces/PageCollectionInterface.php b/system/src/Grav/Common/Page/Interfaces/PageCollectionInterface.php new file mode 100644 index 0000000..9f5588c --- /dev/null +++ b/system/src/Grav/Common/Page/Interfaces/PageCollectionInterface.php @@ -0,0 +1,310 @@ + + * @extends ArrayAccess + */ +interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, Serializable +{ + /** + * Get the collection params + * + * @return array + */ + public function params(); + + /** + * Set parameters to the Collection + * + * @param array $params + * @return $this + */ + public function setParams(array $params); + + /** + * Add a single page to a collection + * + * @param PageInterface $page + * @return $this + */ + public function addPage(PageInterface $page); + + /** + * Add a page with path and slug + * + * @param string $path + * @param string $slug + * @return $this + */ + //public function add($path, $slug); + + /** + * + * Create a copy of this collection + * + * @return static + */ + public function copy(); + + /** + * + * Merge another collection with the current collection + * + * @param PageCollectionInterface $collection + * @return PageCollectionInterface + * @phpstan-return PageCollectionInterface + */ + public function merge(PageCollectionInterface $collection); + + /** + * Intersect another collection with the current collection + * + * @param PageCollectionInterface $collection + * @return PageCollectionInterface + * @phpstan-return PageCollectionInterface + */ + public function intersect(PageCollectionInterface $collection); + + /** + * Split collection into array of smaller collections. + * + * @param int $size + * @return PageCollectionInterface[] + * @phpstan-return array> + */ + public function batch($size); + + /** + * Remove item from the list. + * + * @param PageInterface|string|null $key + * @return PageCollectionInterface + * @phpstan-return PageCollectionInterface + * @throws InvalidArgumentException + */ + //public function remove($key = null); + + /** + * Reorder collection. + * + * @param string $by + * @param string $dir + * @param array|null $manual + * @param string|null $sort_flags + * @return PageCollectionInterface + * @phpstan-return PageCollectionInterface + */ + public function order($by, $dir = 'asc', $manual = null, $sort_flags = null); + + /** + * Check to see if this item is the first in the collection. + * + * @param string $path + * @return bool True if item is first. + */ + public function isFirst($path): bool; + + /** + * Check to see if this item is the last in the collection. + * + * @param string $path + * @return bool True if item is last. + */ + public function isLast($path): bool; + + /** + * Gets the previous sibling based on current position. + * + * @param string $path + * @return PageInterface The previous item. + * @phpstan-return T + */ + public function prevSibling($path); + + /** + * Gets the next sibling based on current position. + * + * @param string $path + * @return PageInterface The next item. + * @phpstan-return T + */ + public function nextSibling($path); + + /** + * Returns the adjacent sibling based on a direction. + * + * @param string $path + * @param int $direction either -1 or +1 + * @return PageInterface|PageCollectionInterface|false The sibling item. + * @phpstan-return T|false + */ + public function adjacentSibling($path, $direction = 1); + + /** + * Returns the item in the current position. + * + * @param string $path the path the item + * @return int|null The index of the current page, null if not found. + */ + public function currentPosition($path): ?int; + + /** + * Returns the items between a set of date ranges of either the page date field (default) or + * an arbitrary datetime page field where start date and end date are optional + * Dates must be passed in as text that strtotime() can process + * http://php.net/manual/en/function.strtotime.php + * + * @param string|null $startDate + * @param string|null $endDate + * @param string|null $field + * @return PageCollectionInterface + * @phpstan-return PageCollectionInterface + * @throws Exception + */ + public function dateRange($startDate = null, $endDate = null, $field = null); + + /** + * Creates new collection with only visible pages + * + * @return PageCollectionInterface The collection with only visible pages + * @phpstan-return PageCollectionInterface + */ + public function visible(); + + /** + * Creates new collection with only non-visible pages + * + * @return PageCollectionInterface The collection with only non-visible pages + * @phpstan-return PageCollectionInterface + */ + public function nonVisible(); + + /** + * Creates new collection with only pages + * + * @return PageCollectionInterface The collection with only pages + * @phpstan-return PageCollectionInterface + */ + public function pages(); + + /** + * Creates new collection with only modules + * + * @return PageCollectionInterface The collection with only modules + * @phpstan-return PageCollectionInterface + */ + public function modules(); + + /** + * Creates new collection with only modules + * + * @return PageCollectionInterface The collection with only modules + * @phpstan-return PageCollectionInterface + * @deprecated 1.7 Use $this->modules() instead + */ + public function modular(); + + /** + * Creates new collection with only non-module pages + * + * @return PageCollectionInterface The collection with only non-module pages + * @phpstan-return PageCollectionInterface + * @deprecated 1.7 Use $this->pages() instead + */ + public function nonModular(); + + /** + * Creates new collection with only published pages + * + * @return PageCollectionInterface The collection with only published pages + * @phpstan-return PageCollectionInterface + */ + public function published(); + + /** + * Creates new collection with only non-published pages + * + * @return PageCollectionInterface The collection with only non-published pages + * @phpstan-return PageCollectionInterface + */ + public function nonPublished(); + + /** + * Creates new collection with only routable pages + * + * @return PageCollectionInterface The collection with only routable pages + * @phpstan-return PageCollectionInterface + */ + public function routable(); + + /** + * Creates new collection with only non-routable pages + * + * @return PageCollectionInterface The collection with only non-routable pages + * @phpstan-return PageCollectionInterface + */ + public function nonRoutable(); + + /** + * Creates new collection with only pages of the specified type + * + * @param string $type + * @return PageCollectionInterface The collection + * @phpstan-return PageCollectionInterface + */ + public function ofType($type); + + /** + * Creates new collection with only pages of one of the specified types + * + * @param string[] $types + * @return PageCollectionInterface The collection + * @phpstan-return PageCollectionInterface + */ + public function ofOneOfTheseTypes($types); + + /** + * Creates new collection with only pages of one of the specified access levels + * + * @param array $accessLevels + * @return PageCollectionInterface The collection + * @phpstan-return PageCollectionInterface + */ + public function ofOneOfTheseAccessLevels($accessLevels); + + /** + * Converts collection into an array. + * + * @return array + */ + public function toArray(); + + /** + * Get the extended version of this Collection with each page keyed by route + * + * @return array + * @throws Exception + */ + public function toExtendedArray(); +} diff --git a/system/src/Grav/Common/Page/Interfaces/PageContentInterface.php b/system/src/Grav/Common/Page/Interfaces/PageContentInterface.php new file mode 100644 index 0000000..2df4286 --- /dev/null +++ b/system/src/Grav/Common/Page/Interfaces/PageContentInterface.php @@ -0,0 +1,267 @@ +true) for example + * + * @param array|null $var New array of name value pairs where the name is the process and value is true or false + * @return array Array of name value pairs where the name is the process and value is true or false + */ + public function process($var = null); + + /** + * Gets and Sets the slug for the Page. The slug is used in the URL routing. If not set it uses + * the parent folder from the path + * + * @param string|null $var New slug, e.g. 'my-blog' + * @return string The slug + */ + public function slug($var = null); + + /** + * Get/set order number of this page. + * + * @param int|null $var New order as a number + * @return string|bool Order in a form of '02.' or false if not set + */ + public function order($var = null); + + /** + * Gets and sets the identifier for this Page object. + * + * @param string|null $var New identifier + * @return string The identifier + */ + public function id($var = null); + + /** + * Gets and sets the modified timestamp. + * + * @param int|null $var New modified unix timestamp + * @return int Modified unix timestamp + */ + public function modified($var = null); + + /** + * Gets and sets the option to show the last_modified header for the page. + * + * @param bool|null $var New last_modified header value + * @return bool Show last_modified header + */ + public function lastModified($var = null); + + /** + * Get/set the folder. + * + * @param string|null $var New folder + * @return string|null The folder + */ + public function folder($var = null); + + /** + * Gets and sets the date for this Page object. This is typically passed in via the page headers + * + * @param string|null $var New string representation of a date + * @return int Unix timestamp representation of the date + */ + public function date($var = null); + + /** + * Gets and sets the date format for this Page object. This is typically passed in via the page headers + * using typical PHP date string structure - http://php.net/manual/en/function.date.php + * + * @param string|null $var New string representation of a date format + * @return string String representation of a date format + */ + public function dateformat($var = null); + + /** + * Gets and sets the taxonomy array which defines which taxonomies this page identifies itself with. + * + * @param array|null $var New array of taxonomies + * @return array An array of taxonomies + */ + public function taxonomy($var = null); + + /** + * Gets the configured state of the processing method. + * + * @param string $process The process name, eg "twig" or "markdown" + * @return bool Whether or not the processing method is enabled for this Page + */ + public function shouldProcess($process); + + /** + * Returns true if page is a module. + * + * @return bool + */ + public function isModule(): bool; + + /** + * Returns whether or not this Page object has a .md file associated with it or if its just a directory. + * + * @return bool True if its a page with a .md file associated + */ + public function isPage(); + + /** + * Returns whether or not this Page object is a directory or a page. + * + * @return bool True if its a directory + */ + public function isDir(); + + /** + * Returns whether the page exists in the filesystem. + * + * @return bool + */ + public function exists(); + + /** + * Returns the blueprint from the page. + * + * @param string $name Name of the Blueprint form. Used by flex only. + * @return Blueprint Returns a Blueprint. + */ + public function getBlueprint(string $name = ''); +} diff --git a/system/src/Grav/Common/Page/Interfaces/PageFormInterface.php b/system/src/Grav/Common/Page/Interfaces/PageFormInterface.php new file mode 100644 index 0000000..3c88ebf --- /dev/null +++ b/system/src/Grav/Common/Page/Interfaces/PageFormInterface.php @@ -0,0 +1,33 @@ + blueprint, ...], where blueprint follows the regular form blueprint format. + * + * @return array + */ + //public function getForms(): array; + + /** + * Add forms to this page. + * + * @param array $new + * @return $this + */ + public function addForms(array $new/*, $override = true*/); + + /** + * Alias of $this->getForms(); + * + * @return array + */ + public function forms();//: array; +} diff --git a/system/src/Grav/Common/Page/Interfaces/PageInterface.php b/system/src/Grav/Common/Page/Interfaces/PageInterface.php new file mode 100644 index 0000000..8595c54 --- /dev/null +++ b/system/src/Grav/Common/Page/Interfaces/PageInterface.php @@ -0,0 +1,25 @@ +save() in order to perform the move. + * + * @param PageInterface $parent New parent page. + * @return $this + */ + public function move(PageInterface $parent); + + /** + * Prepare a copy from the page. Copies also everything that's under the current page. + * + * Returns a new Page object for the copy. + * You need to call $this->save() in order to perform the move. + * + * @param PageInterface $parent New parent page. + * @return $this + */ + public function copy(PageInterface $parent); + + /** + * Get blueprints for the page. + * + * @return Blueprint + */ + public function blueprints(); + + /** + * Get the blueprint name for this page. Use the blueprint form field if set + * + * @return string + */ + public function blueprintName(); + + /** + * Validate page header. + * + * @throws Exception + */ + public function validate(); + + /** + * Filter page header from illegal contents. + */ + public function filter(); + + /** + * Get unknown header variables. + * + * @return array + */ + public function extra(); + + /** + * Convert page to an array. + * + * @return array + */ + public function toArray(); + + /** + * Convert page to YAML encoded string. + * + * @return string + */ + public function toYaml(); + + /** + * Convert page to JSON encoded string. + * + * @return string + */ + public function toJson(); + + /** + * Returns normalized list of name => form pairs. + * + * @return array + */ + public function forms(); + + /** + * @param array $new + */ + public function addForms(array $new); + + /** + * Gets and sets the name field. If no name field is set, it will return 'default.md'. + * + * @param string|null $var The name of this page. + * @return string The name of this page. + */ + public function name($var = null); + + /** + * Returns child page type. + * + * @return string + */ + public function childType(); + + /** + * Gets and sets the template field. This is used to find the correct Twig template file to render. + * If no field is set, it will return the name without the .md extension + * + * @param string|null $var the template name + * @return string the template name + */ + public function template($var = null); + + /** + * Allows a page to override the output render format, usually the extension provided + * in the URL. (e.g. `html`, `json`, `xml`, etc). + * + * @param string|null $var + * @return string + */ + public function templateFormat($var = null); + + /** + * Gets and sets the extension field. + * + * @param string|null $var + * @return string|null + */ + public function extension($var = null); + + /** + * Gets and sets the expires field. If not set will return the default + * + * @param int|null $var The new expires value. + * @return int The expires value + */ + public function expires($var = null); + + /** + * Gets and sets the cache-control property. If not set it will return the default value (null) + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control for more details on valid options + * + * @param string|null $var + * @return string|null + */ + public function cacheControl($var = null); + + /** + * @param bool|null $var + * @return bool + */ + public function ssl($var = null); + + /** + * Returns the state of the debugger override etting for this page + * + * @return bool + */ + public function debugger(); + + /** + * Function to merge page metadata tags and build an array of Metadata objects + * that can then be rendered in the page. + * + * @param array|null $var an Array of metadata values to set + * @return array an Array of metadata values for the page + */ + public function metadata($var = null); + + /** + * Gets and sets the option to show the etag header for the page. + * + * @param bool|null $var show etag header + * @return bool show etag header + */ + public function eTag($var = null): bool; + + /** + * Gets and sets the path to the .md file for this Page object. + * + * @param string|null $var the file path + * @return string|null the file path + */ + public function filePath($var = null); + + /** + * Gets the relative path to the .md file + * + * @return string The relative file path + */ + public function filePathClean(); + + /** + * Gets and sets the order by which any sub-pages should be sorted. + * + * @param string|null $var the order, either "asc" or "desc" + * @return string the order, either "asc" or "desc" + * @deprecated 1.6 + */ + public function orderDir($var = null); + + /** + * Gets and sets the order by which the sub-pages should be sorted. + * + * default - is the order based on the file system, ie 01.Home before 02.Advark + * title - is the order based on the title set in the pages + * date - is the order based on the date set in the pages + * folder - is the order based on the name of the folder with any numerics omitted + * + * @param string|null $var supported options include "default", "title", "date", and "folder" + * @return string supported options include "default", "title", "date", and "folder" + * @deprecated 1.6 + */ + public function orderBy($var = null); + + /** + * Gets the manual order set in the header. + * + * @param string|null $var supported options include "default", "title", "date", and "folder" + * @return array + * @deprecated 1.6 + */ + public function orderManual($var = null); + + /** + * Gets and sets the maxCount field which describes how many sub-pages should be displayed if the + * sub_pages header property is set for this page object. + * + * @param int|null $var the maximum number of sub-pages + * @return int the maximum number of sub-pages + * @deprecated 1.6 + */ + public function maxCount($var = null); + + /** + * Gets and sets the modular var that helps identify this page is a modular child + * + * @param bool|null $var true if modular_twig + * @return bool true if modular_twig + * @deprecated 1.7 Use ->isModule() or ->modularTwig() method instead. + */ + public function modular($var = null); + + /** + * Gets and sets the modular_twig var that helps identify this page as a modular child page that will need + * twig processing handled differently from a regular page. + * + * @param bool|null $var true if modular_twig + * @return bool true if modular_twig + */ + public function modularTwig($var = null); + + /** + * Returns children of this page. + * + * @return PageCollectionInterface|Collection + */ + public function children(); + + /** + * Check to see if this item is the first in an array of sub-pages. + * + * @return bool True if item is first. + */ + public function isFirst(); + + /** + * Check to see if this item is the last in an array of sub-pages. + * + * @return bool True if item is last + */ + public function isLast(); + + /** + * Gets the previous sibling based on current position. + * + * @return PageInterface the previous Page item + */ + public function prevSibling(); + + /** + * Gets the next sibling based on current position. + * + * @return PageInterface the next Page item + */ + public function nextSibling(); + + /** + * Returns the adjacent sibling based on a direction. + * + * @param int $direction either -1 or +1 + * @return PageInterface|false the sibling page + */ + public function adjacentSibling($direction = 1); + + /** + * Helper method to return an ancestor page. + * + * @param bool|null $lookup Name of the parent folder + * @return PageInterface page you were looking for if it exists + */ + public function ancestor($lookup = null); + + /** + * Helper method to return an ancestor page to inherit from. The current + * page object is returned. + * + * @param string $field Name of the parent folder + * @return PageInterface + */ + public function inherited($field); + + /** + * Helper method to return an ancestor field only to inherit from. The + * first occurrence of an ancestor field will be returned if at all. + * + * @param string $field Name of the parent folder + * @return array + */ + public function inheritedField($field); + + /** + * Helper method to return a page. + * + * @param string $url the url of the page + * @param bool $all + * @return PageInterface page you were looking for if it exists + */ + public function find($url, $all = false); + + /** + * Get a collection of pages in the current context. + * + * @param string|array $params + * @param bool $pagination + * @return Collection + * @throws InvalidArgumentException + */ + public function collection($params = 'content', $pagination = true); + + /** + * @param string|array $value + * @param bool $only_published + * @return PageCollectionInterface|Collection + */ + public function evaluate($value, $only_published = true); + + /** + * Returns whether or not the current folder exists + * + * @return bool + */ + public function folderExists(); + + /** + * Gets the Page Unmodified (original) version of the page. + * + * @return PageInterface The original version of the page. + */ + public function getOriginal(); + + /** + * Gets the action. + * + * @return string The Action string. + */ + public function getAction(); +} diff --git a/system/src/Grav/Common/Page/Interfaces/PageRoutableInterface.php b/system/src/Grav/Common/Page/Interfaces/PageRoutableInterface.php new file mode 100644 index 0000000..2900266 --- /dev/null +++ b/system/src/Grav/Common/Page/Interfaces/PageRoutableInterface.php @@ -0,0 +1,180 @@ +page = $page ?? Grav::instance()['page'] ?? null; + + // Add defaults to the configuration. + if (null === $config || !isset($config['markdown'], $config['images'])) { + $c = Grav::instance()['config']; + $config = $config ?? []; + $config += [ + 'markdown' => $c->get('system.pages.markdown', []), + 'images' => $c->get('system.images', []) + ]; + } + + $this->config = $config; + } + + /** + * @return PageInterface|null + */ + public function getPage(): ?PageInterface + { + return $this->page; + } + + /** + * @return array + */ + public function getConfig(): array + { + return $this->config; + } + + /** + * @param object $markdown + * @return void + */ + public function fireInitializedEvent($markdown): void + { + $grav = Grav::instance(); + + $grav->fireEvent('onMarkdownInitialized', new Event(['markdown' => $markdown, 'page' => $this->page])); + } + + /** + * Process a Link excerpt + * + * @param array $excerpt + * @param string $type + * @return array + */ + public function processLinkExcerpt(array $excerpt, string $type = 'link'): array + { + $grav = Grav::instance(); + $url = htmlspecialchars_decode(rawurldecode($excerpt['element']['attributes']['href'])); + $url_parts = $this->parseUrl($url); + + // If there is a query, then parse it and build action calls. + if (isset($url_parts['query'])) { + $actions = array_reduce( + explode('&', $url_parts['query']), + static function ($carry, $item) { + $parts = explode('=', $item, 2); + $value = isset($parts[1]) ? rawurldecode($parts[1]) : true; + $carry[$parts[0]] = $value; + + return $carry; + }, + [] + ); + + // Valid attributes supported. + $valid_attributes = $grav['config']->get('system.pages.markdown.valid_link_attributes') ?? []; + + $skip = []; + // Unless told to not process, go through actions. + if (array_key_exists('noprocess', $actions)) { + $skip = is_bool($actions['noprocess']) ? $actions : explode(',', $actions['noprocess']); + unset($actions['noprocess']); + } + + // Loop through actions for the image and call them. + foreach ($actions as $attrib => $value) { + if (!in_array($attrib, $skip)) { + $key = $attrib; + + if (in_array($attrib, $valid_attributes, true)) { + // support both class and classes. + if ($attrib === 'classes') { + $attrib = 'class'; + } + $excerpt['element']['attributes'][$attrib] = str_replace(',', ' ', $value); + unset($actions[$key]); + } + } + } + + $url_parts['query'] = http_build_query($actions, '', '&', PHP_QUERY_RFC3986); + } + + // If no query elements left, unset query. + if (empty($url_parts['query'])) { + unset($url_parts['query']); + } + + // Set path to / if not set. + if (empty($url_parts['path'])) { + $url_parts['path'] = ''; + } + + // If scheme isn't http(s).. + if (!empty($url_parts['scheme']) && !in_array($url_parts['scheme'], ['http', 'https'])) { + // Handle custom streams. + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + if ($type === 'link' && $locator->isStream($url)) { + $path = $locator->findResource($url, false) ?: $locator->findResource($url, false, true); + $url_parts['path'] = $grav['base_url_relative'] . '/' . $path; + unset($url_parts['stream'], $url_parts['scheme']); + } + + $excerpt['element']['attributes']['href'] = Uri::buildUrl($url_parts); + + return $excerpt; + } + + // Handle paths and such. + $url_parts = Uri::convertUrl($this->page, $url_parts, $type); + + // Build the URL from the component parts and set it on the element. + $excerpt['element']['attributes']['href'] = Uri::buildUrl($url_parts); + + return $excerpt; + } + + /** + * Process an image excerpt + * + * @param array $excerpt + * @return array + */ + public function processImageExcerpt(array $excerpt): array + { + $url = htmlspecialchars_decode(urldecode($excerpt['element']['attributes']['src'])); + $url_parts = $this->parseUrl($url); + + $media = null; + $filename = null; + + if (!empty($url_parts['stream'])) { + $filename = $url_parts['scheme'] . '://' . ($url_parts['path'] ?? ''); + + $media = $this->page->getMedia(); + } else { + $grav = Grav::instance(); + /** @var Pages $pages */ + $pages = $grav['pages']; + + // File is also local if scheme is http(s) and host matches. + $local_file = isset($url_parts['path']) + && (empty($url_parts['scheme']) || in_array($url_parts['scheme'], ['http', 'https'], true)) + && (empty($url_parts['host']) || $url_parts['host'] === $grav['uri']->host()); + + if ($local_file) { + $filename = Utils::basename($url_parts['path']); + $folder = dirname($url_parts['path']); + + // Get the local path to page media if possible. + if ($this->page && $folder === $this->page->url(false, false, false)) { + // Get the media objects for this page. + $media = $this->page->getMedia(); + } else { + // see if this is an external page to this one + $base_url = rtrim($grav['base_url_relative'] . $pages->base(), '/'); + $page_route = '/' . ltrim(str_replace($base_url, '', $folder), '/'); + + $ext_page = $pages->find($page_route, true); + if ($ext_page) { + $media = $ext_page->getMedia(); + } else { + $grav->fireEvent('onMediaLocate', new Event(['route' => $page_route, 'media' => &$media])); + } + } + } + } + + // If there is a media file that matches the path referenced.. + if ($media && $filename && isset($media[$filename])) { + // Get the medium object. + /** @var Medium $medium */ + $medium = $media[$filename]; + + // Process operations + $medium = $this->processMediaActions($medium, $url_parts); + $element_excerpt = $excerpt['element']['attributes']; + + $alt = $element_excerpt['alt'] ?? ''; + $title = $element_excerpt['title'] ?? ''; + $class = $element_excerpt['class'] ?? ''; + $id = $element_excerpt['id'] ?? ''; + + $excerpt['element'] = $medium->parsedownElement($title, $alt, $class, $id, true); + } else { + // Not a current page media file, see if it needs converting to relative. + $excerpt['element']['attributes']['src'] = Uri::buildUrl($url_parts); + } + + return $excerpt; + } + + /** + * Process media actions + * + * @param Medium $medium + * @param string|array $url + * @return Medium|Link + */ + public function processMediaActions($medium, $url) + { + $url_parts = is_string($url) ? $this->parseUrl($url) : $url; + $actions = []; + + + // if there is a query, then parse it and build action calls + if (isset($url_parts['query'])) { + $actions = array_reduce( + explode('&', $url_parts['query']), + static function ($carry, $item) { + $parts = explode('=', $item, 2); + $value = $parts[1] ?? null; + $carry[] = ['method' => $parts[0], 'params' => $value]; + + return $carry; + }, + [] + ); + } + + $defaults = $this->config['images']['defaults'] ?? []; + if (count($defaults)) { + foreach ($defaults as $method => $params) { + if (array_search($method, array_column($actions, 'method')) === false) { + $actions[] = [ + 'method' => $method, + 'params' => $params, + ]; + } + } + } + + // loop through actions for the image and call them + foreach ($actions as $action) { + $matches = []; + + if (preg_match('/\[(.*)\]/', $action['params'], $matches)) { + $args = [explode(',', $matches[1])]; + } else { + $args = explode(',', $action['params']); + } + + $medium = call_user_func_array([$medium, $action['method']], $args); + } + + if (isset($url_parts['fragment'])) { + $medium->urlHash($url_parts['fragment']); + } + + return $medium; + } + + /** + * Variation of parse_url() which works also with local streams. + * + * @param string $url + * @return array + */ + protected function parseUrl(string $url) + { + $url_parts = Utils::multibyteParseUrl($url); + + if (isset($url_parts['scheme'])) { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + + // Special handling for the streams. + if ($locator->schemeExists($url_parts['scheme'])) { + if (isset($url_parts['host'])) { + // Merge host and path into a path. + $url_parts['path'] = $url_parts['host'] . (isset($url_parts['path']) ? '/' . $url_parts['path'] : ''); + unset($url_parts['host']); + } + + $url_parts['stream'] = true; + } + } + + return $url_parts; + } +} diff --git a/system/src/Grav/Common/Page/Media.php b/system/src/Grav/Common/Page/Media.php new file mode 100644 index 0000000..b29bbf3 --- /dev/null +++ b/system/src/Grav/Common/Page/Media.php @@ -0,0 +1,286 @@ +setPath($path); + $this->media_order = $media_order; + + $this->__wakeup(); + if ($load) { + $this->init(); + } + } + + /** + * Initialize static variables on unserialize. + */ + public function __wakeup() + { + if (null === static::$global) { + // Add fallback to global media. + static::$global = GlobalMedia::getInstance(); + } + } + + /** + * Return raw route to the page. + * + * @return string|null Route to the page or null if media isn't for a page. + */ + public function getRawRoute(): ?string + { + $path = $this->getPath(); + if ($path) { + /** @var Pages $pages */ + $pages = $this->getGrav()['pages']; + $page = $pages->get($path); + if ($page) { + return $page->rawRoute(); + } + } + + return null; + } + + /** + * Return page route. + * + * @return string|null Route to the page or null if media isn't for a page. + */ + public function getRoute(): ?string + { + $path = $this->getPath(); + if ($path) { + /** @var Pages $pages */ + $pages = $this->getGrav()['pages']; + $page = $pages->get($path); + if ($page) { + return $page->route(); + } + } + + return null; + } + + /** + * @param string $offset + * @return bool + */ + #[\ReturnTypeWillChange] + public function offsetExists($offset) + { + return parent::offsetExists($offset) ?: isset(static::$global[$offset]); + } + + /** + * @param string $offset + * @return MediaObjectInterface|null + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return parent::offsetGet($offset) ?: static::$global[$offset]; + } + + /** + * Initialize class. + * + * @return void + */ + protected function init() + { + $path = $this->getPath(); + + // Handle special cases where page doesn't exist in filesystem. + if (!$path || !is_dir($path)) { + return; + } + + $grav = Grav::instance(); + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + + /** @var Config $config */ + $config = $grav['config']; + + $exif_reader = isset($grav['exif']) ? $grav['exif']->getReader() : null; + $media_types = array_keys($config->get('media.types', [])); + + $iterator = new FilesystemIterator($path, FilesystemIterator::UNIX_PATHS | FilesystemIterator::SKIP_DOTS); + + $media = []; + + foreach ($iterator as $file => $info) { + // Ignore folders and Markdown files. + $filename = $info->getFilename(); + if (!$info->isFile() || $info->getExtension() === 'md' || $filename === 'frontmatter.yaml' || $filename === 'media.json' || strpos($filename, '.') === 0) { + continue; + } + + // Find out what type we're dealing with + [$basename, $ext, $type, $extra] = $this->getFileParts($filename); + + if (!in_array(strtolower($ext), $media_types, true)) { + continue; + } + + if ($type === 'alternative') { + $media["{$basename}.{$ext}"][$type][$extra] = ['file' => $file, 'size' => $info->getSize()]; + } else { + $media["{$basename}.{$ext}"][$type] = ['file' => $file, 'size' => $info->getSize()]; + } + } + + foreach ($media as $name => $types) { + // First prepare the alternatives in case there is no base medium + if (!empty($types['alternative'])) { + /** + * @var string|int $ratio + * @var array $alt + */ + foreach ($types['alternative'] as $ratio => &$alt) { + $alt['file'] = $this->createFromFile($alt['file']); + + if (empty($alt['file'])) { + unset($types['alternative'][$ratio]); + } else { + $alt['file']->set('size', $alt['size']); + } + } + unset($alt); + } + + $file_path = null; + + // Create the base medium + if (empty($types['base'])) { + if (!isset($types['alternative'])) { + continue; + } + + $max = max(array_keys($types['alternative'])); + $medium = $types['alternative'][$max]['file']; + $file_path = $medium->path(); + $medium = MediumFactory::scaledFromMedium($medium, $max, 1)['file']; + } else { + $medium = $this->createFromFile($types['base']['file']); + if ($medium) { + $medium->set('size', $types['base']['size']); + $file_path = $medium->path(); + } + } + + if (empty($medium)) { + continue; + } + + // metadata file + $meta_path = $file_path . '.meta.yaml'; + + if (file_exists($meta_path)) { + $types['meta']['file'] = $meta_path; + } elseif ($file_path && $exif_reader && $medium->get('mime') === 'image/jpeg' && empty($types['meta']) && $config->get('system.media.auto_metadata_exif')) { + $meta = $exif_reader->read($file_path); + + if ($meta) { + $meta_data = $meta->getData(); + $meta_trimmed = array_diff_key($meta_data, array_flip($this->standard_exif)); + if ($meta_trimmed) { + if ($locator->isStream($meta_path)) { + $file = File::instance($locator->findResource($meta_path, true, true)); + } else { + $file = File::instance($meta_path); + } + $file->save(Yaml::dump($meta_trimmed)); + $types['meta']['file'] = $meta_path; + } + } + } + + if (!empty($types['meta'])) { + $medium->addMetaFile($types['meta']['file']); + } + + if (!empty($types['thumb'])) { + // We will not turn it into medium yet because user might never request the thumbnail + // not wasting any resources on that, maybe we should do this for medium in general? + $medium->set('thumbnails.page', $types['thumb']['file']); + } + + // Build missing alternatives + if (!empty($types['alternative'])) { + $alternatives = $types['alternative']; + $max = max(array_keys($alternatives)); + + for ($i=$max; $i > 1; $i--) { + if (isset($alternatives[$i])) { + continue; + } + + $types['alternative'][$i] = MediumFactory::scaledFromMedium($alternatives[$max]['file'], $max, $i); + } + + foreach ($types['alternative'] as $altMedium) { + if ($altMedium['file'] != $medium) { + $altWidth = $altMedium['file']->get('width'); + $medWidth = $medium->get('width'); + if ($altWidth && $medWidth) { + $ratio = $altWidth / $medWidth; + $medium->addAlternative($ratio, $altMedium['file']); + } + } + } + } + + $this->add($name, $medium); + } + } + + /** + * @return string|null + * @deprecated 1.6 Use $this->getPath() instead. + */ + public function path(): ?string + { + return $this->getPath(); + } +} diff --git a/system/src/Grav/Common/Page/Medium/AbstractMedia.php b/system/src/Grav/Common/Page/Medium/AbstractMedia.php new file mode 100644 index 0000000..906d044 --- /dev/null +++ b/system/src/Grav/Common/Page/Medium/AbstractMedia.php @@ -0,0 +1,344 @@ +path; + } + + /** + * @param string|null $path + * @return void + */ + public function setPath(?string $path): void + { + $this->path = $path; + } + + /** + * Get medium by filename. + * + * @param string $filename + * @return MediaObjectInterface|null + */ + public function get($filename) + { + return $this->offsetGet($filename); + } + + /** + * Call object as function to get medium by filename. + * + * @param string $filename + * @return mixed + */ + #[\ReturnTypeWillChange] + public function __invoke($filename) + { + return $this->offsetGet($filename); + } + + /** + * Set file modification timestamps (query params) for all the media files. + * + * @param string|int|null $timestamp + * @return $this + */ + public function setTimestamps($timestamp = null) + { + foreach ($this->items as $instance) { + $instance->setTimestamp($timestamp); + } + + return $this; + } + + /** + * Get a list of all media. + * + * @return MediaObjectInterface[] + */ + public function all() + { + $this->items = $this->orderMedia($this->items); + + return $this->items; + } + + /** + * Get a list of all image media. + * + * @return MediaObjectInterface[] + */ + public function images() + { + $this->images = $this->orderMedia($this->images); + + return $this->images; + } + + /** + * Get a list of all video media. + * + * @return MediaObjectInterface[] + */ + public function videos() + { + $this->videos = $this->orderMedia($this->videos); + + return $this->videos; + } + + /** + * Get a list of all audio media. + * + * @return MediaObjectInterface[] + */ + public function audios() + { + $this->audios = $this->orderMedia($this->audios); + + return $this->audios; + } + + /** + * Get a list of all file media. + * + * @return MediaObjectInterface[] + */ + public function files() + { + $this->files = $this->orderMedia($this->files); + + return $this->files; + } + + /** + * @param string $name + * @param MediaObjectInterface|null $file + * @return void + */ + public function add($name, $file) + { + if (null === $file) { + return; + } + + $this->offsetSet($name, $file); + + switch ($file->type) { + case 'image': + $this->images[$name] = $file; + break; + case 'video': + $this->videos[$name] = $file; + break; + case 'audio': + $this->audios[$name] = $file; + break; + default: + $this->files[$name] = $file; + } + } + + /** + * @param string $name + * @return void + */ + public function hide($name) + { + $this->offsetUnset($name); + + unset($this->images[$name], $this->videos[$name], $this->audios[$name], $this->files[$name]); + } + + /** + * Create Medium from a file. + * + * @param string $file + * @param array $params + * @return Medium|null + */ + public function createFromFile($file, array $params = []) + { + return MediumFactory::fromFile($file, $params); + } + + /** + * Create Medium from array of parameters + * + * @param array $items + * @param Blueprint|null $blueprint + * @return Medium|null + */ + public function createFromArray(array $items = [], Blueprint $blueprint = null) + { + return MediumFactory::fromArray($items, $blueprint); + } + + /** + * @param MediaObjectInterface $mediaObject + * @return ImageFile + */ + public function getImageFileObject(MediaObjectInterface $mediaObject): ImageFile + { + return ImageFile::open($mediaObject->get('filepath')); + } + + /** + * Order the media based on the page's media_order + * + * @param array $media + * @return array + */ + protected function orderMedia($media) + { + if (null === $this->media_order) { + $path = $this->getPath(); + if (null !== $path) { + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + $page = $pages->get($path); + if ($page && isset($page->header()->media_order)) { + $this->media_order = array_map('trim', explode(',', $page->header()->media_order)); + } + } + } + + if (!empty($this->media_order) && is_array($this->media_order)) { + $media = Utils::sortArrayByArray($media, $this->media_order); + } else { + ksort($media, SORT_NATURAL | SORT_FLAG_CASE); + } + + return $media; + } + + protected function fileExists(string $filename, string $destination): bool + { + return file_exists("{$destination}/{$filename}"); + } + + /** + * Get filename, extension and meta part. + * + * @param string $filename + * @return array + */ + protected function getFileParts($filename) + { + if (preg_match('/(.*)@(\d+)x\.(.*)$/', $filename, $matches)) { + $name = $matches[1]; + $extension = $matches[3]; + $extra = (int) $matches[2]; + $type = 'alternative'; + + if ($extra === 1) { + $type = 'base'; + $extra = null; + } + } else { + $fileParts = explode('.', $filename); + + $name = array_shift($fileParts); + $extension = null; + $extra = null; + $type = 'base'; + + while (($part = array_shift($fileParts)) !== null) { + if ($part !== 'meta' && $part !== 'thumb') { + if (null !== $extension) { + $name .= '.' . $extension; + } + $extension = $part; + } else { + $type = $part; + $extra = '.' . $part . '.' . implode('.', $fileParts); + break; + } + } + } + + return [$name, $extension, $type, $extra]; + } + + protected function getGrav(): Grav + { + return Grav::instance(); + } + + protected function getConfig(): Config + { + return $this->getGrav()['config']; + } + + protected function getLanguage(): Language + { + return $this->getGrav()['language']; + } + + protected function clearCache(): void + { + /** @var UniformResourceLocator $locator */ + $locator = $this->getGrav()['locator']; + $locator->clearCache(); + } +} diff --git a/system/src/Grav/Common/Page/Medium/AudioMedium.php b/system/src/Grav/Common/Page/Medium/AudioMedium.php new file mode 100644 index 0000000..81d3a5b --- /dev/null +++ b/system/src/Grav/Common/Page/Medium/AudioMedium.php @@ -0,0 +1,36 @@ +resetPlayer(); + + return $this; + } +} diff --git a/system/src/Grav/Common/Page/Medium/GlobalMedia.php b/system/src/Grav/Common/Page/Medium/GlobalMedia.php new file mode 100644 index 0000000..66ccca7 --- /dev/null +++ b/system/src/Grav/Common/Page/Medium/GlobalMedia.php @@ -0,0 +1,150 @@ +resolveStream($offset)); + } + + /** + * @param string $offset + * @return MediaObjectInterface|null + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return parent::offsetGet($offset) ?: $this->addMedium($offset); + } + + /** + * @param string $filename + * @return string|null + */ + protected function resolveStream($filename) + { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + if (!$locator->isStream($filename)) { + return null; + } + + return $locator->findResource($filename) ?: null; + } + + /** + * @param string $stream + * @return MediaObjectInterface|null + */ + protected function addMedium($stream) + { + $filename = $this->resolveStream($stream); + if (!$filename) { + return null; + } + + $path = dirname($filename); + [$basename, $ext,, $extra] = $this->getFileParts(Utils::basename($filename)); + $medium = MediumFactory::fromFile($filename); + + if (null === $medium) { + return null; + } + + $medium->set('size', filesize($filename)); + $scale = (int) ($extra ?: 1); + + if ($scale !== 1) { + $altMedium = $medium; + + // Create scaled down regular sized image. + $medium = MediumFactory::scaledFromMedium($altMedium, $scale, 1)['file']; + + if (empty($medium)) { + return null; + } + + // Add original sized image as alternative. + $medium->addAlternative($scale, $altMedium['file']); + + // Locate or generate smaller retina images. + for ($i = $scale-1; $i > 1; $i--) { + $altFilename = "{$path}/{$basename}@{$i}x.{$ext}"; + + if (file_exists($altFilename)) { + $scaled = MediumFactory::fromFile($altFilename); + } else { + $scaled = MediumFactory::scaledFromMedium($altMedium, $scale, $i)['file']; + } + + if ($scaled) { + $medium->addAlternative($i, $scaled); + } + } + } + + $meta = "{$path}/{$basename}.{$ext}.yaml"; + if (file_exists($meta)) { + $medium->addMetaFile($meta); + } + $meta = "{$path}/{$basename}.{$ext}.meta.yaml"; + if (file_exists($meta)) { + $medium->addMetaFile($meta); + } + + $thumb = "{$path}/{$basename}.thumb.{$ext}"; + if (file_exists($thumb)) { + $medium->set('thumbnails.page', $thumb); + } + + $this->add($stream, $medium); + + return $medium; + } +} diff --git a/system/src/Grav/Common/Page/Medium/ImageFile.php b/system/src/Grav/Common/Page/Medium/ImageFile.php new file mode 100644 index 0000000..554382a --- /dev/null +++ b/system/src/Grav/Common/Page/Medium/ImageFile.php @@ -0,0 +1,212 @@ +adapter; + if ($adapter) { + $adapter->deinit(); + } + } + + /** + * Clear previously applied operations + * + * @return void + */ + public function clearOperations() + { + $this->operations = []; + } + + /** + * This is the same as the Gregwar Image class except this one fires a Grav Event on creation of new cached file + * + * @param string $type the image type + * @param int $quality the quality (for JPEG) + * @param bool $actual + * @param array $extras + * @return string + */ + public function cacheFile($type = 'jpg', $quality = 80, $actual = false, $extras = []) + { + if ($type === 'guess') { + $type = $this->guessType(); + } + + if (!$this->forceCache && !count($this->operations) && $type === $this->guessType()) { + return $this->getFilename($this->getFilePath()); + } + + // Computes the hash + $this->hash = $this->getHash($type, $quality, $extras); + + /** @var Config $config */ + $config = Grav::instance()['config']; + + // Seo friendly image names + $seofriendly = $config->get('system.images.seofriendly', false); + + if ($seofriendly) { + $mini_hash = substr($this->hash, 0, 4) . substr($this->hash, -4); + $cacheFile = "{$this->prettyName}-{$mini_hash}"; + } else { + $cacheFile = "{$this->hash}-{$this->prettyName}"; + } + + $cacheFile .= '.' . $type; + + // If the files does not exists, save it + $image = $this; + + // Target file should be younger than all the current image + // dependencies + $conditions = array( + 'younger-than' => $this->getDependencies() + ); + + // The generating function + $generate = function ($target) use ($image, $type, $quality) { + $result = $image->save($target, $type, $quality); + + if ($result !== $target) { + throw new GenerationError($result); + } + + Grav::instance()->fireEvent('onImageMediumSaved', new Event(['image' => $target])); + }; + + // Asking the cache for the cacheFile + try { + $perms = $config->get('system.images.cache_perms', '0755'); + $perms = octdec($perms); + $file = $this->getCacheSystem()->setDirectoryMode($perms)->getOrCreateFile($cacheFile, $conditions, $generate, $actual); + } catch (GenerationError $e) { + $file = $e->getNewFile(); + } + + // Nulling the resource + $adapter = $this->getAdapter(); + $adapter->setSource(new Source\File($file)); + $adapter->deinit(); + + if ($actual) { + return $file; + } + + return $this->getFilename($file); + } + + /** + * Gets the hash. + * + * @param string $type + * @param int $quality + * @param array $extras + * @return string + */ + public function getHash($type = 'guess', $quality = 80, $extras = []) + { + if (null === $this->hash) { + $this->generateHash($type, $quality, $extras); + } + + return $this->hash; + } + + /** + * Generates the hash. + * + * @param string $type + * @param int $quality + * @param array $extras + */ + public function generateHash($type = 'guess', $quality = 80, $extras = []) + { + $inputInfos = $this->source->getInfos(); + + $data = [ + $inputInfos, + $this->serializeOperations(), + $type, + $quality, + $extras + ]; + + $this->hash = sha1(serialize($data)); + } + + /** + * Read exif rotation from file and apply it. + */ + public function fixOrientation() + { + if (!extension_loaded('exif')) { + throw new RuntimeException('You need to EXIF PHP Extension to use this function'); + } + + if (!file_exists($this->source->getInfos()) || !in_array(exif_imagetype($this->source->getInfos()), [IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM], true)) { + return $this; + } + + // resolve any streams + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $filepath = $this->source->getInfos(); + if ($locator->isStream($filepath)) { + $filepath = $locator->findResource($this->source->getInfos(), true, true); + } + + // Make sure file exists + if (!file_exists($filepath)) { + return $this; + } + + try { + $exif = @exif_read_data($filepath); + } catch (Exception $e) { + Grav::instance()['log']->error($filepath . ' - ' . $e->getMessage()); + return $this; + } + + if ($exif === false || !array_key_exists('Orientation', $exif)) { + return $this; + } + + return $this->applyExifOrientation($exif['Orientation']); + } +} diff --git a/system/src/Grav/Common/Page/Medium/ImageMedium.php b/system/src/Grav/Common/Page/Medium/ImageMedium.php new file mode 100644 index 0000000..580e9f5 --- /dev/null +++ b/system/src/Grav/Common/Page/Medium/ImageMedium.php @@ -0,0 +1,499 @@ +getGrav()['config']; + + $this->thumbnailTypes = ['page', 'media', 'default']; + $this->default_quality = $config->get('system.images.default_image_quality', 85); + $this->def('debug', $config->get('system.images.debug')); + + $path = $this->get('filepath'); + if (!$path || !file_exists($path) || !filesize($path)) { + return; + } + + $this->set('thumbnails.media', $path); + + if (!($this->offsetExists('width') && $this->offsetExists('height') && $this->offsetExists('mime'))) { + $image_info = getimagesize($path); + if ($image_info) { + $this->def('width', (int) $image_info[0]); + $this->def('height', (int) $image_info[1]); + $this->def('mime', $image_info['mime']); + } + } + + $this->reset(); + + if ($config->get('system.images.cache_all', false)) { + $this->cache(); + } + } + + /** + * @return array + */ + public function getMeta(): array + { + return [ + 'width' => $this->width, + 'height' => $this->height, + ] + parent::getMeta(); + } + + /** + * Also unset the image on destruct. + */ + #[\ReturnTypeWillChange] + public function __destruct() + { + unset($this->image); + } + + /** + * Also clone image. + */ + #[\ReturnTypeWillChange] + public function __clone() + { + if ($this->image) { + $this->image = clone $this->image; + } + + parent::__clone(); + } + + /** + * Reset image. + * + * @return $this + */ + public function reset() + { + parent::reset(); + + if ($this->image) { + $this->image(); + $this->medium_querystring = []; + $this->filter(); + $this->clearAlternatives(); + } + + $this->format = 'guess'; + $this->quality = $this->default_quality; + + $this->debug_watermarked = false; + + $config = $this->getGrav()['config']; + // Set CLS configuration + $this->auto_sizes = $config->get('system.images.cls.auto_sizes', false); + $this->aspect_ratio = $config->get('system.images.cls.aspect_ratio', false); + $this->retina_scale = $config->get('system.images.cls.retina_scale', 1); + + return $this; + } + + /** + * Add meta file for the medium. + * + * @param string $filepath + * @return $this + */ + public function addMetaFile($filepath) + { + parent::addMetaFile($filepath); + + // Apply filters in meta file + $this->reset(); + + return $this; + } + + /** + * Return PATH to image. + * + * @param bool $reset + * @return string path to image + */ + public function path($reset = true) + { + $output = $this->saveImage(); + + if ($reset) { + $this->reset(); + } + + return $output; + } + + /** + * Return URL to image. + * + * @param bool $reset + * @return string + */ + public function url($reset = true) + { + $grav = $this->getGrav(); + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + $image_path = (string)($locator->findResource('cache://images', true) ?: $locator->findResource('cache://images', true, true)); + $saved_image_path = $this->saved_image_path = $this->saveImage(); + + $output = preg_replace('|^' . preg_quote(GRAV_ROOT, '|') . '|', '', $saved_image_path) ?: $saved_image_path; + + if ($locator->isStream($output)) { + $output = (string)($locator->findResource($output, false) ?: $locator->findResource($output, false, true)); + } + + if (Utils::startsWith($output, $image_path)) { + $image_dir = $locator->findResource('cache://images', false); + $output = '/' . $image_dir . preg_replace('|^' . preg_quote($image_path, '|') . '|', '', $output); + } + + if ($reset) { + $this->reset(); + } + + return trim($grav['base_url'] . '/' . $this->urlQuerystring($output), '\\'); + } + + /** + * Return srcset string for this Medium and its alternatives. + * + * @param bool $reset + * @return string + */ + public function srcset($reset = true) + { + if (empty($this->alternatives)) { + if ($reset) { + $this->reset(); + } + + return ''; + } + + $srcset = []; + foreach ($this->alternatives as $ratio => $medium) { + $srcset[] = $medium->url($reset) . ' ' . $medium->get('width') . 'w'; + } + $srcset[] = str_replace(' ', '%20', $this->url($reset)) . ' ' . $this->get('width') . 'w'; + + return implode(', ', $srcset); + } + + /** + * Parsedown element for source display mode + * + * @param array $attributes + * @param bool $reset + * @return array + */ + public function sourceParsedownElement(array $attributes, $reset = true) + { + empty($attributes['src']) && $attributes['src'] = $this->url(false); + + $srcset = $this->srcset($reset); + if ($srcset) { + empty($attributes['srcset']) && $attributes['srcset'] = $srcset; + $attributes['sizes'] = $this->sizes(); + } + + if ($this->saved_image_path && $this->auto_sizes) { + if (!array_key_exists('height', $this->attributes) && !array_key_exists('width', $this->attributes)) { + $info = getimagesize($this->saved_image_path); + $width = (int)$info[0]; + $height = (int)$info[1]; + + $scaling_factor = $this->retina_scale > 0 ? $this->retina_scale : 1; + $attributes['width'] = (int)($width / $scaling_factor); + $attributes['height'] = (int)($height / $scaling_factor); + + if ($this->aspect_ratio) { + $style = ($attributes['style'] ?? ' ') . "--aspect-ratio: $width/$height;"; + $attributes['style'] = trim($style); + } + } + } + + return ['name' => 'img', 'attributes' => $attributes]; + } + + /** + * Turn the current Medium into a Link + * + * @param bool $reset + * @param array $attributes + * @return MediaLinkInterface + */ + public function link($reset = true, array $attributes = []) + { + $attributes['href'] = $this->url(false); + $srcset = $this->srcset(false); + if ($srcset) { + $attributes['data-srcset'] = $srcset; + } + + return parent::link($reset, $attributes); + } + + /** + * Turn the current Medium into a Link with lightbox enabled + * + * @param int $width + * @param int $height + * @param bool $reset + * @return MediaLinkInterface + */ + public function lightbox($width = null, $height = null, $reset = true) + { + if ($this->mode !== 'source') { + $this->display('source'); + } + + if ($width && $height) { + $this->__call('cropResize', [(int) $width, (int) $height]); + } + + return parent::lightbox($width, $height, $reset); + } + + /** + * @param string $enabled + * @return $this + */ + public function autoSizes($enabled = 'true') + { + $this->auto_sizes = $enabled === 'true' ?: false; + + return $this; + } + + /** + * @param string $enabled + * @return $this + */ + public function aspectRatio($enabled = 'true') + { + $this->aspect_ratio = $enabled === 'true' ?: false; + + return $this; + } + + /** + * @param int $scale + * @return $this + */ + public function retinaScale($scale = 1) + { + $this->retina_scale = (int)$scale; + + return $this; + } + + /** + * @param string|null $image + * @param string|null $position + * @param int|float|null $scale + * @return $this + */ + public function watermark($image = null, $position = null, $scale = null) + { + $grav = $this->getGrav(); + + $locator = $grav['locator']; + $config = $grav['config']; + + $args = func_get_args(); + + $file = $args[0] ?? '1'; // using '1' because of markdown. doing ![](image.jpg?watermark) returns $args[0]='1'; + $file = $file === '1' ? $config->get('system.images.watermark.image') : $args[0]; + + $watermark = $locator->findResource($file); + $watermark = ImageFile::open($watermark); + + // Scaling operations + $scale = ($scale ?? $config->get('system.images.watermark.scale', 100)) / 100; + $wwidth = (int) ($this->get('width') * $scale); + $wheight = (int) ($this->get('height') * $scale); + $watermark->resize($wwidth, $wheight); + + // Position operations + $position = !empty($args[1]) ? explode('-', $args[1]) : ['center', 'center']; // todo change to config + $positionY = $position[0] ?? $config->get('system.images.watermark.position_y', 'center'); + $positionX = $position[1] ?? $config->get('system.images.watermark.position_x', 'center'); + + switch ($positionY) + { + case 'top': + $positionY = 0; + break; + + case 'bottom': + $positionY = (int)$this->get('height')-$wheight; + break; + + case 'center': + $positionY = ((int)$this->get('height')/2) - ($wheight/2); + break; + } + + switch ($positionX) + { + case 'left': + $positionX = 0; + break; + + case 'right': + $positionX = (int) ($this->get('width')-$wwidth); + break; + + case 'center': + $positionX = (int) (($this->get('width')/2) - ($wwidth/2)); + break; + } + + $this->__call('merge', [$watermark,$positionX, $positionY]); + + return $this; + } + + /** + * Handle this commonly used variant + * + * @return $this + */ + public function cropZoom() + { + $this->__call('zoomCrop', func_get_args()); + + return $this; + } + + /** + * Add a frame to image + * + * @return $this + */ + public function addFrame(int $border = 10, string $color = '0x000000') + { + if($border > 0 && preg_match('/^0x[a-f0-9]{6}$/i', $color)) { // $border must be an integer and bigger than 0; $color must be formatted as an HEX value (0x??????). + $image = ImageFile::open($this->path()); + } + else { + return $this; + } + + $dst_width = (int) ($image->width()+2*$border); + $dst_height = (int) ($image->height()+2*$border); + + $frame = ImageFile::create($dst_width, $dst_height); + + $frame->__call('fill', [$color]); + + $this->image = $frame; + + $this->__call('merge', [$image, $border, $border]); + + $this->saveImage(); + + return $this; + + } + + /** + * Forward the call to the image processing method. + * + * @param string $method + * @param mixed $args + * @return $this|mixed + */ + #[\ReturnTypeWillChange] + public function __call($method, $args) + { + if (!in_array($method, static::$magic_actions, true)) { + return parent::__call($method, $args); + } + + // Always initialize image. + if (!$this->image) { + $this->image(); + } + + try { + $this->image->{$method}(...$args); + + /** @var ImageMediaInterface $medium */ + foreach ($this->alternatives as $medium) { + $args_copy = $args; + + // regular image: resize 400x400 -> 200x200 + // --> @2x: resize 800x800->400x400 + if (isset(static::$magic_resize_actions[$method])) { + foreach (static::$magic_resize_actions[$method] as $param) { + if (isset($args_copy[$param])) { + $args_copy[$param] *= $medium->get('ratio'); + } + } + } + + // Do the same call for alternative media. + $medium->__call($method, $args_copy); + } + } catch (BadFunctionCallException $e) { + } + + return $this; + } +} diff --git a/system/src/Grav/Common/Page/Medium/Link.php b/system/src/Grav/Common/Page/Medium/Link.php new file mode 100644 index 0000000..1abc7ef --- /dev/null +++ b/system/src/Grav/Common/Page/Medium/Link.php @@ -0,0 +1,102 @@ +attributes = $attributes; + + $source = $medium->reset()->thumbnail('auto')->display('thumbnail'); + if (!$source instanceof MediaObjectInterface) { + throw new RuntimeException('Media has no thumbnail set'); + } + + $source->set('linked', true); + + $this->source = $source; + } + + /** + * Get an element (is array) that can be rendered by the Parsedown engine + * + * @param string|null $title + * @param string|null $alt + * @param string|null $class + * @param string|null $id + * @param bool $reset + * @return array + */ + public function parsedownElement($title = null, $alt = null, $class = null, $id = null, $reset = true) + { + $innerElement = $this->source->parsedownElement($title, $alt, $class, $id, $reset); + + return [ + 'name' => 'a', + 'attributes' => $this->attributes, + 'handler' => is_array($innerElement) ? 'element' : 'line', + 'text' => $innerElement + ]; + } + + /** + * Forward the call to the source element + * + * @param string $method + * @param mixed $args + * @return mixed + */ + #[\ReturnTypeWillChange] + public function __call($method, $args) + { + $object = $this->source; + $callable = [$object, $method]; + if (!is_callable($callable)) { + throw new BadMethodCallException(get_class($object) . '::' . $method . '() not found.'); + } + + $object = call_user_func_array($callable, $args); + if (!$object instanceof MediaLinkInterface) { + // Don't start nesting links, if user has multiple link calls in his + // actions, we will drop the previous links. + return $this; + } + + $this->source = $object; + + return $object; + } +} diff --git a/system/src/Grav/Common/Page/Medium/Medium.php b/system/src/Grav/Common/Page/Medium/Medium.php new file mode 100644 index 0000000..a17f68a --- /dev/null +++ b/system/src/Grav/Common/Page/Medium/Medium.php @@ -0,0 +1,140 @@ +get('system.media.enable_media_timestamp', true)) { + $this->timestamp = Grav::instance()['cache']->getKey(); + } + + $this->def('mime', 'application/octet-stream'); + + if (!$this->offsetExists('size')) { + $path = $this->get('filepath'); + $this->def('size', filesize($path)); + } + + $this->reset(); + } + + /** + * Clone medium. + */ + #[\ReturnTypeWillChange] + public function __clone() + { + // Allows future compatibility as parent::__clone() works. + } + + /** + * Add meta file for the medium. + * + * @param string $filepath + */ + public function addMetaFile($filepath) + { + $this->metadata = (array)CompiledYamlFile::instance($filepath)->content(); + $this->merge($this->metadata); + } + + /** + * @return array + */ + public function getMeta(): array + { + return [ + 'mime' => $this->mime, + 'size' => $this->size, + 'modified' => $this->modified, + ]; + } + + /** + * Return string representation of the object (html). + * + * @return string + */ + #[\ReturnTypeWillChange] + public function __toString() + { + return $this->html(); + } + + /** + * @param string $thumb + * @return Medium|null + */ + protected function createThumbnail($thumb) + { + return MediumFactory::fromFile($thumb, ['type' => 'thumbnail']); + } + + /** + * @param array $attributes + * @return MediaLinkInterface + */ + protected function createLink(array $attributes) + { + return new Link($attributes, $this); + } + + /** + * @return Grav + */ + protected function getGrav(): Grav + { + return Grav::instance(); + } + + /** + * @return array + */ + protected function getItems(): array + { + return $this->items; + } +} diff --git a/system/src/Grav/Common/Page/Medium/MediumFactory.php b/system/src/Grav/Common/Page/Medium/MediumFactory.php new file mode 100644 index 0000000..0796a83 --- /dev/null +++ b/system/src/Grav/Common/Page/Medium/MediumFactory.php @@ -0,0 +1,220 @@ +get('media.types.' . strtolower($ext)) : null; + if (!is_array($media_params)) { + return null; + } + + // Remove empty 'image' attribute + if (isset($media_params['image']) && empty($media_params['image'])) { + unset($media_params['image']); + } + + $params += $media_params; + + // Add default settings for undefined variables. + $params += (array)$config->get('media.types.defaults'); + $params += [ + 'type' => 'file', + 'thumb' => 'media/thumb.png', + 'mime' => 'application/octet-stream', + 'filepath' => $file, + 'filename' => $filename, + 'basename' => $basename, + 'extension' => $ext, + 'path' => $path, + 'modified' => filemtime($file), + 'thumbnails' => [] + ]; + + $locator = Grav::instance()['locator']; + + $file = $locator->findResource("image://{$params['thumb']}"); + if ($file) { + $params['thumbnails']['default'] = $file; + } + + return static::fromArray($params); + } + + /** + * Create Medium from an uploaded file + * + * @param UploadedFileInterface $uploadedFile + * @param array $params + * @return Medium|null + */ + public static function fromUploadedFile(UploadedFileInterface $uploadedFile, array $params = []) + { + // For now support only FormFlashFiles, which exist over multiple requests. Also ignore errored and moved media. + if (!$uploadedFile instanceof FormFlashFile || $uploadedFile->getError() !== \UPLOAD_ERR_OK || $uploadedFile->isMoved()) { + return null; + } + + $clientName = $uploadedFile->getClientFilename(); + if (!$clientName) { + return null; + } + + $parts = Utils::pathinfo($clientName); + $filename = $parts['basename']; + $ext = $parts['extension'] ?? ''; + $basename = $parts['filename']; + $file = $uploadedFile->getTmpFile(); + $path = $file ? dirname($file) : ''; + + $config = Grav::instance()['config']; + + $media_params = $ext ? $config->get('media.types.' . strtolower($ext)) : null; + if (!is_array($media_params)) { + return null; + } + + $params += $media_params; + + // Add default settings for undefined variables. + $params += (array)$config->get('media.types.defaults'); + $params += [ + 'type' => 'file', + 'thumb' => 'media/thumb.png', + 'mime' => 'application/octet-stream', + 'filepath' => $file, + 'filename' => $filename, + 'basename' => $basename, + 'extension' => $ext, + 'path' => $path, + 'modified' => $file ? filemtime($file) : 0, + 'thumbnails' => [] + ]; + + $locator = Grav::instance()['locator']; + + $file = $locator->findResource("image://{$params['thumb']}"); + if ($file) { + $params['thumbnails']['default'] = $file; + } + + return static::fromArray($params); + } + + /** + * Create Medium from array of parameters + * + * @param array $items + * @param Blueprint|null $blueprint + * @return Medium + */ + public static function fromArray(array $items = [], Blueprint $blueprint = null) + { + $type = $items['type'] ?? null; + + switch ($type) { + case 'image': + return new ImageMedium($items, $blueprint); + case 'thumbnail': + return new ThumbnailImageMedium($items, $blueprint); + case 'vector': + return new VectorImageMedium($items, $blueprint); + case 'animated': + return new StaticImageMedium($items, $blueprint); + case 'video': + return new VideoMedium($items, $blueprint); + case 'audio': + return new AudioMedium($items, $blueprint); + default: + return new Medium($items, $blueprint); + } + } + + /** + * Create a new ImageMedium by scaling another ImageMedium object. + * + * @param ImageMediaInterface|MediaObjectInterface $medium + * @param int $from + * @param int $to + * @return ImageMediaInterface|MediaObjectInterface|array + */ + public static function scaledFromMedium($medium, $from, $to) + { + if (!$medium instanceof ImageMedium) { + return $medium; + } + + if ($to > $from) { + return $medium; + } + + $ratio = $to / $from; + $width = $medium->get('width') * $ratio; + $height = $medium->get('height') * $ratio; + + $prev_basename = $medium->get('basename'); + $basename = str_replace('@' . $from . 'x', $to !== 1 ? '@' . $to . 'x' : '', $prev_basename); + + $debug = $medium->get('debug'); + $medium->set('debug', false); + $medium->setImagePrettyName($basename); + + $file = $medium->resize($width, $height)->path(); + + $medium->set('debug', $debug); + $medium->setImagePrettyName($prev_basename); + + $size = filesize($file); + + $medium = self::fromFile($file); + if ($medium) { + $medium->set('basename', $basename); + $medium->set('filename', $basename . '.' . $medium->extension); + $medium->set('size', $size); + } + + return ['file' => $medium, 'size' => $size]; + } +} diff --git a/system/src/Grav/Common/Page/Medium/ParsedownHtmlTrait.php b/system/src/Grav/Common/Page/Medium/ParsedownHtmlTrait.php new file mode 100644 index 0000000..3326150 --- /dev/null +++ b/system/src/Grav/Common/Page/Medium/ParsedownHtmlTrait.php @@ -0,0 +1,44 @@ +parsedownElement($title, $alt, $class, $id, $reset); + + if (!$this->parsedown) { + $this->parsedown = new Parsedown(new Excerpts()); + } + + return $this->parsedown->elementToHtml($element); + } +} diff --git a/system/src/Grav/Common/Page/Medium/RenderableInterface.php b/system/src/Grav/Common/Page/Medium/RenderableInterface.php new file mode 100644 index 0000000..e6ce40b --- /dev/null +++ b/system/src/Grav/Common/Page/Medium/RenderableInterface.php @@ -0,0 +1,41 @@ +url($reset); + } + + return ['name' => 'img', 'attributes' => $attributes]; + } + + /** + * @return $this + */ + public function higherQualityAlternative() + { + return $this; + } +} diff --git a/system/src/Grav/Common/Page/Medium/StaticResizeTrait.php b/system/src/Grav/Common/Page/Medium/StaticResizeTrait.php new file mode 100644 index 0000000..a48f8e5 --- /dev/null +++ b/system/src/Grav/Common/Page/Medium/StaticResizeTrait.php @@ -0,0 +1,24 @@ +get('width'); + $height = $this->get('height'); + if ($width && $height) { + return; + } + + // Make sure that getting image size is supported. + if ($this->mime !== 'image/svg+xml' || !\extension_loaded('simplexml')) { + return; + } + + // Make sure that the image exists. + $path = $this->get('filepath'); + if (!$path || !file_exists($path) || !filesize($path)) { + return; + } + + $xml = simplexml_load_string(file_get_contents($path)); + $attr = $xml ? $xml->attributes() : null; + if (!$attr instanceof \SimpleXMLElement) { + return; + } + + // Get the size from svg image. + if ($attr->width && $attr->height) { + $width = (string)$attr->width; + $height = (string)$attr->height; + } elseif ($attr->viewBox && \count($size = explode(' ', (string)$attr->viewBox)) === 4) { + [,$width,$height,] = $size; + } + + if ($width && $height) { + $this->def('width', (int)$width); + $this->def('height', (int)$height); + } + } +} diff --git a/system/src/Grav/Common/Page/Medium/VideoMedium.php b/system/src/Grav/Common/Page/Medium/VideoMedium.php new file mode 100644 index 0000000..326417c --- /dev/null +++ b/system/src/Grav/Common/Page/Medium/VideoMedium.php @@ -0,0 +1,36 @@ +resetPlayer(); + + return $this; + } +} diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php new file mode 100644 index 0000000..90b8c05 --- /dev/null +++ b/system/src/Grav/Common/Page/Page.php @@ -0,0 +1,2935 @@ +taxonomy = []; + $this->process = $config->get('system.pages.process'); + $this->published = true; + } + + /** + * Initializes the page instance variables based on a file + * + * @param SplFileInfo $file The file information for the .md file that the page represents + * @param string|null $extension + * @return $this + */ + public function init(SplFileInfo $file, $extension = null) + { + $config = Grav::instance()['config']; + + $this->initialized = true; + + // some extension logic + if (empty($extension)) { + $this->extension('.' . $file->getExtension()); + } else { + $this->extension($extension); + } + + // extract page language from page extension + $language = trim(Utils::basename($this->extension(), 'md'), '.') ?: null; + $this->language($language); + + $this->hide_home_route = $config->get('system.home.hide_in_urls', false); + $this->home_route = $this->adjustRouteCase($config->get('system.home.alias')); + $this->filePath($file->getPathname()); + $this->modified($file->getMTime()); + $this->id($this->modified() . md5($this->filePath())); + $this->routable(true); + $this->header(); + $this->date(); + $this->metadata(); + $this->url(); + $this->visible(); + $this->modularTwig(strpos($this->slug(), '_') === 0); + $this->setPublishState(); + $this->published(); + $this->urlExtension(); + + return $this; + } + + #[\ReturnTypeWillChange] + public function __clone() + { + $this->initialized = false; + $this->header = $this->header ? clone $this->header : null; + } + + /** + * @return void + */ + public function initialize(): void + { + if (!$this->initialized) { + $this->initialized = true; + $this->route = null; + $this->raw_route = null; + $this->_forms = null; + } + } + + /** + * @return void + */ + protected function processFrontmatter() + { + // Quick check for twig output tags in frontmatter if enabled + $process_fields = (array)$this->header(); + if (Utils::contains(json_encode(array_values($process_fields)), '{{')) { + $ignored_fields = []; + foreach ((array)Grav::instance()['config']->get('system.pages.frontmatter.ignore_fields') as $field) { + if (isset($process_fields[$field])) { + $ignored_fields[$field] = $process_fields[$field]; + unset($process_fields[$field]); + } + } + $text_header = Grav::instance()['twig']->processString(json_encode($process_fields, JSON_UNESCAPED_UNICODE), ['page' => $this]); + $this->header((object)(json_decode($text_header, true) + $ignored_fields)); + } + } + + /** + * Return an array with the routes of other translated languages + * + * @param bool $onlyPublished only return published translations + * @return array the page translated languages + */ + public function translatedLanguages($onlyPublished = false) + { + $grav = Grav::instance(); + + /** @var Language $language */ + $language = $grav['language']; + + $languages = $language->getLanguages(); + $defaultCode = $language->getDefault(); + + $name = substr($this->name, 0, -strlen($this->extension())); + $translatedLanguages = []; + + foreach ($languages as $languageCode) { + $languageExtension = ".{$languageCode}.md"; + $path = $this->path . DS . $this->folder . DS . $name . $languageExtension; + $exists = file_exists($path); + + // Default language may be saved without language file location. + if (!$exists && $languageCode === $defaultCode) { + $languageExtension = '.md'; + $path = $this->path . DS . $this->folder . DS . $name . $languageExtension; + $exists = file_exists($path); + } + + if ($exists) { + $aPage = new Page(); + $aPage->init(new SplFileInfo($path), $languageExtension); + $aPage->route($this->route()); + $aPage->rawRoute($this->rawRoute()); + $route = $aPage->header()->routes['default'] ?? $aPage->rawRoute(); + if (!$route) { + $route = $aPage->route(); + } + + if ($onlyPublished && !$aPage->published()) { + continue; + } + + $translatedLanguages[$languageCode] = $route; + } + } + + return $translatedLanguages; + } + + /** + * Return an array listing untranslated languages available + * + * @param bool $includeUnpublished also list unpublished translations + * @return array the page untranslated languages + */ + public function untranslatedLanguages($includeUnpublished = false) + { + $grav = Grav::instance(); + + /** @var Language $language */ + $language = $grav['language']; + + $languages = $language->getLanguages(); + $translated = array_keys($this->translatedLanguages(!$includeUnpublished)); + + return array_values(array_diff($languages, $translated)); + } + + /** + * Gets and Sets the raw data + * + * @param string|null $var Raw content string + * @return string Raw content string + */ + public function raw($var = null) + { + $file = $this->file(); + + if ($var) { + // First update file object. + if ($file) { + $file->raw($var); + } + + // Reset header and content. + $this->modified = time(); + $this->id($this->modified() . md5($this->filePath())); + $this->header = null; + $this->content = null; + $this->summary = null; + } + + return $file ? $file->raw() : ''; + } + + /** + * Gets and Sets the page frontmatter + * + * @param string|null $var + * + * @return string + */ + public function frontmatter($var = null) + { + if ($var) { + $this->frontmatter = (string)$var; + + // Update also file object. + $file = $this->file(); + if ($file) { + $file->frontmatter((string)$var); + } + + // Force content re-processing. + $this->id(time() . md5($this->filePath())); + } + if (!$this->frontmatter) { + $this->header(); + } + + return $this->frontmatter; + } + + /** + * Gets and Sets the header based on the YAML configuration at the top of the .md file + * + * @param object|array|null $var a YAML object representing the configuration for the file + * @return \stdClass the current YAML configuration + */ + public function header($var = null) + { + if ($var) { + $this->header = (object)$var; + + // Update also file object. + $file = $this->file(); + if ($file) { + $file->header((array)$var); + } + + // Force content re-processing. + $this->id(time() . md5($this->filePath())); + } + if (!$this->header) { + $file = $this->file(); + if ($file) { + try { + $this->raw_content = $file->markdown(); + $this->frontmatter = $file->frontmatter(); + $this->header = (object)$file->header(); + + if (!Utils::isAdminPlugin()) { + // If there's a `frontmatter.yaml` file merge that in with the page header + // note page's own frontmatter has precedence and will overwrite any defaults + $frontmatter_filename = $this->path . '/' . $this->folder . '/frontmatter.yaml'; + if (file_exists($frontmatter_filename)) { + $frontmatter_file = CompiledYamlFile::instance($frontmatter_filename); + $frontmatter_data = $frontmatter_file->content(); + $this->header = (object)array_replace_recursive( + $frontmatter_data, + (array)$this->header + ); + $frontmatter_file->free(); + } + + // Process frontmatter with Twig if enabled + if (Grav::instance()['config']->get('system.pages.frontmatter.process_twig') === true) { + $this->processFrontmatter(); + } + } + } catch (Exception $e) { + $file->raw(Grav::instance()['language']->translate([ + 'GRAV.FRONTMATTER_ERROR_PAGE', + $this->slug(), + $file->filename(), + $e->getMessage(), + $file->raw() + ])); + $this->raw_content = $file->markdown(); + $this->frontmatter = $file->frontmatter(); + $this->header = (object)$file->header(); + } + $var = true; + } + } + + if ($var) { + if (isset($this->header->modified)) { + $this->modified($this->header->modified); + } + if (isset($this->header->slug)) { + $this->slug($this->header->slug); + } + if (isset($this->header->routes)) { + $this->routes = (array)$this->header->routes; + } + if (isset($this->header->title)) { + $this->title = trim($this->header->title); + } + if (isset($this->header->language)) { + $this->language = trim($this->header->language); + } + if (isset($this->header->template)) { + $this->template = trim($this->header->template); + } + if (isset($this->header->menu)) { + $this->menu = trim($this->header->menu); + } + if (isset($this->header->routable)) { + $this->routable = (bool)$this->header->routable; + } + if (isset($this->header->visible)) { + $this->visible = (bool)$this->header->visible; + } + if (isset($this->header->redirect)) { + $this->redirect = trim($this->header->redirect); + } + if (isset($this->header->external_url)) { + $this->external_url = trim($this->header->external_url); + } + if (isset($this->header->order_dir)) { + $this->order_dir = trim($this->header->order_dir); + } + if (isset($this->header->order_by)) { + $this->order_by = trim($this->header->order_by); + } + if (isset($this->header->order_manual)) { + $this->order_manual = (array)$this->header->order_manual; + } + if (isset($this->header->dateformat)) { + $this->dateformat($this->header->dateformat); + } + if (isset($this->header->date)) { + $this->date($this->header->date); + } + if (isset($this->header->markdown_extra)) { + $this->markdown_extra = (bool)$this->header->markdown_extra; + } + if (isset($this->header->taxonomy)) { + $this->taxonomy($this->header->taxonomy); + } + if (isset($this->header->max_count)) { + $this->max_count = (int)$this->header->max_count; + } + if (isset($this->header->process)) { + foreach ((array)$this->header->process as $process => $status) { + $this->process[$process] = (bool)$status; + } + } + if (isset($this->header->published)) { + $this->published = (bool)$this->header->published; + } + if (isset($this->header->publish_date)) { + $this->publishDate($this->header->publish_date); + } + if (isset($this->header->unpublish_date)) { + $this->unpublishDate($this->header->unpublish_date); + } + if (isset($this->header->expires)) { + $this->expires = (int)$this->header->expires; + } + if (isset($this->header->cache_control)) { + $this->cache_control = $this->header->cache_control; + } + if (isset($this->header->etag)) { + $this->etag = (bool)$this->header->etag; + } + if (isset($this->header->last_modified)) { + $this->last_modified = (bool)$this->header->last_modified; + } + if (isset($this->header->ssl)) { + $this->ssl = (bool)$this->header->ssl; + } + if (isset($this->header->template_format)) { + $this->template_format = $this->header->template_format; + } + if (isset($this->header->debugger)) { + $this->debugger = (bool)$this->header->debugger; + } + if (isset($this->header->append_url_extension)) { + $this->url_extension = $this->header->append_url_extension; + } + } + + return $this->header; + } + + /** + * Get page language + * + * @param string|null $var + * @return mixed + */ + public function language($var = null) + { + if ($var !== null) { + $this->language = $var; + } + + return $this->language; + } + + /** + * Modify a header value directly + * + * @param string $key + * @param mixed $value + */ + public function modifyHeader($key, $value) + { + $this->header->{$key} = $value; + } + + /** + * @return int + */ + public function httpResponseCode() + { + return (int)($this->header()->http_response_code ?? 200); + } + + /** + * @return array + */ + public function httpHeaders() + { + $headers = []; + + $grav = Grav::instance(); + $format = $this->templateFormat(); + $cache_control = $this->cacheControl(); + $expires = $this->expires(); + + // Set Content-Type header + $headers['Content-Type'] = Utils::getMimeByExtension($format, 'text/html'); + + // Calculate Expires Headers if set to > 0 + if ($expires > 0) { + $expires_date = gmdate('D, d M Y H:i:s', time() + $expires) . ' GMT'; + if (!$cache_control) { + $headers['Cache-Control'] = 'max-age=' . $expires; + } + $headers['Expires'] = $expires_date; + } + + // Set Cache-Control header + if ($cache_control) { + $headers['Cache-Control'] = strtolower($cache_control); + } + + // Set Last-Modified header + if ($this->lastModified()) { + $last_modified = $this->modified(); + foreach ($this->children()->modular() as $cpage) { + $modular_mtime = $cpage->modified(); + if ($modular_mtime > $last_modified) { + $last_modified = $modular_mtime; + } + } + + $last_modified_date = gmdate('D, d M Y H:i:s', $last_modified) . ' GMT'; + $headers['Last-Modified'] = $last_modified_date; + } + + // Ask Grav to calculate ETag from the final content. + if ($this->eTag()) { + $headers['ETag'] = '1'; + } + + // Set Vary: Accept-Encoding header + if ($grav['config']->get('system.pages.vary_accept_encoding', false)) { + $headers['Vary'] = 'Accept-Encoding'; + } + + + // Added new Headers event + $headers_obj = (object) $headers; + Grav::instance()->fireEvent('onPageHeaders', new Event(['headers' => $headers_obj])); + + return (array)$headers_obj; + } + + /** + * Get the summary. + * + * @param int|null $size Max summary size. + * @param bool $textOnly Only count text size. + * @return string + */ + public function summary($size = null, $textOnly = false) + { + $config = (array)Grav::instance()['config']->get('site.summary'); + if (isset($this->header->summary)) { + $config = array_merge($config, $this->header->summary); + } + + // Return summary based on settings in site config file + if (!$config['enabled']) { + return $this->content(); + } + + // Set up variables to process summary from page or from custom summary + if ($this->summary === null) { + $content = $textOnly ? strip_tags($this->content()) : $this->content(); + $summary_size = $this->summary_size; + } else { + $content = $textOnly ? strip_tags($this->summary) : $this->summary; + $summary_size = mb_strwidth($content, 'utf-8'); + } + + // Return calculated summary based on summary divider's position + $format = $config['format']; + // Return entire page content on wrong/ unknown format + if (!in_array($format, ['short', 'long'])) { + return $content; + } + if (($format === 'short') && isset($summary_size)) { + // Slice the string + if (mb_strwidth($content, 'utf8') > $summary_size) { + return mb_substr($content, 0, $summary_size); + } + + return $content; + } + + // Get summary size from site config's file + if ($size === null) { + $size = $config['size']; + } + + // If the size is zero, return the entire page content + if ($size === 0) { + return $content; + // Return calculated summary based on defaults + } + if (!is_numeric($size) || ($size < 0)) { + $size = 300; + } + + // Only return string but not html, wrap whatever html tag you want when using + if ($textOnly) { + if (mb_strwidth($content, 'utf-8') <= $size) { + return $content; + } + + return mb_strimwidth($content, 0, $size, '…', 'UTF-8'); + } + + $summary = Utils::truncateHtml($content, $size); + + return html_entity_decode($summary, ENT_COMPAT | ENT_HTML401, 'UTF-8'); + } + + /** + * Sets the summary of the page + * + * @param string $summary Summary + */ + public function setSummary($summary) + { + $this->summary = $summary; + } + + /** + * Gets and Sets the content based on content portion of the .md file + * + * @param string|null $var Content + * @return string Content + */ + public function content($var = null) + { + if ($var !== null) { + $this->raw_content = $var; + + // Update file object. + $file = $this->file(); + if ($file) { + $file->markdown($var); + } + + // Force re-processing. + $this->id(time() . md5($this->filePath())); + $this->content = null; + } + // If no content, process it + if ($this->content === null) { + // Get media + $this->media(); + + /** @var Config $config */ + $config = Grav::instance()['config']; + + // Load cached content + /** @var Cache $cache */ + $cache = Grav::instance()['cache']; + $cache_id = md5('page' . $this->getCacheKey()); + $content_obj = $cache->fetch($cache_id); + + if (is_array($content_obj)) { + $this->content = $content_obj['content']; + $this->content_meta = $content_obj['content_meta']; + } else { + $this->content = $content_obj; + } + + + $process_markdown = $this->shouldProcess('markdown'); + $process_twig = $this->shouldProcess('twig') || $this->modularTwig(); + + $cache_enable = $this->header->cache_enable ?? $config->get( + 'system.cache.enabled', + true + ); + $twig_first = $this->header->twig_first ?? $config->get( + 'system.pages.twig_first', + false + ); + + // never cache twig means it's always run after content + $never_cache_twig = $this->header->never_cache_twig ?? $config->get( + 'system.pages.never_cache_twig', + true + ); + + // if no cached-content run everything + if ($never_cache_twig) { + if ($this->content === false || $cache_enable === false) { + $this->content = $this->raw_content; + Grav::instance()->fireEvent('onPageContentRaw', new Event(['page' => $this])); + + if ($process_markdown) { + $this->processMarkdown(); + } + + // Content Processed but not cached yet + Grav::instance()->fireEvent('onPageContentProcessed', new Event(['page' => $this])); + + if ($cache_enable) { + $this->cachePageContent(); + } + } + + if ($process_twig) { + $this->processTwig(); + } + } else { + if ($this->content === false || $cache_enable === false) { + $this->content = $this->raw_content; + Grav::instance()->fireEvent('onPageContentRaw', new Event(['page' => $this])); + + if ($twig_first) { + if ($process_twig) { + $this->processTwig(); + } + if ($process_markdown) { + $this->processMarkdown(); + } + + // Content Processed but not cached yet + Grav::instance()->fireEvent('onPageContentProcessed', new Event(['page' => $this])); + } else { + if ($process_markdown) { + $this->processMarkdown($process_twig); + } + + // Content Processed but not cached yet + Grav::instance()->fireEvent('onPageContentProcessed', new Event(['page' => $this])); + + if ($process_twig) { + $this->processTwig(); + } + } + + if ($cache_enable) { + $this->cachePageContent(); + } + } + } + + // Handle summary divider + $delimiter = $config->get('site.summary.delimiter', '==='); + $divider_pos = mb_strpos($this->content, "

{$delimiter}

"); + if ($divider_pos !== false) { + $this->summary_size = $divider_pos; + $this->content = str_replace("

{$delimiter}

", '', $this->content); + } + + // Fire event when Page::content() is called + Grav::instance()->fireEvent('onPageContent', new Event(['page' => $this])); + } + + return $this->content; + } + + /** + * Get the contentMeta array and initialize content first if it's not already + * + * @return mixed + */ + public function contentMeta() + { + if ($this->content === null) { + $this->content(); + } + + return $this->getContentMeta(); + } + + /** + * Add an entry to the page's contentMeta array + * + * @param string $name + * @param mixed $value + */ + public function addContentMeta($name, $value) + { + $this->content_meta[$name] = $value; + } + + /** + * Return the whole contentMeta array as it currently stands + * + * @param string|null $name + * + * @return mixed|null + */ + public function getContentMeta($name = null) + { + if ($name) { + return $this->content_meta[$name] ?? null; + } + + return $this->content_meta; + } + + /** + * Sets the whole content meta array in one shot + * + * @param array $content_meta + * + * @return array + */ + public function setContentMeta($content_meta) + { + return $this->content_meta = $content_meta; + } + + /** + * Process the Markdown content. Uses Parsedown or Parsedown Extra depending on configuration + * + * @param bool $keepTwig If true, content between twig tags will not be processed. + * @return void + */ + protected function processMarkdown(bool $keepTwig = false) + { + /** @var Config $config */ + $config = Grav::instance()['config']; + + $markdownDefaults = (array)$config->get('system.pages.markdown'); + if (isset($this->header()->markdown)) { + $markdownDefaults = array_merge($markdownDefaults, $this->header()->markdown); + } + + // pages.markdown_extra is deprecated, but still check it... + if (!isset($markdownDefaults['extra']) && (isset($this->markdown_extra) || $config->get('system.pages.markdown_extra') !== null)) { + user_error('Configuration option \'system.pages.markdown_extra\' is deprecated since Grav 1.5, use \'system.pages.markdown.extra\' instead', E_USER_DEPRECATED); + + $markdownDefaults['extra'] = $this->markdown_extra ?: $config->get('system.pages.markdown_extra'); + } + + $extra = $markdownDefaults['extra'] ?? false; + $defaults = [ + 'markdown' => $markdownDefaults, + 'images' => $config->get('system.images', []) + ]; + + $excerpts = new Excerpts($this, $defaults); + + // Initialize the preferred variant of Parsedown + if ($extra) { + $parsedown = new ParsedownExtra($excerpts); + } else { + $parsedown = new Parsedown($excerpts); + } + + $content = $this->content; + if ($keepTwig) { + $token = [ + '/' . Utils::generateRandomString(3), + Utils::generateRandomString(3) . '/' + ]; + // Base64 encode any twig. + $content = preg_replace_callback( + ['/({#.*?#})/mu', '/({{.*?}})/mu', '/({%.*?%})/mu'], + static function ($matches) use ($token) { return $token[0] . base64_encode($matches[1]) . $token[1]; }, + $content + ); + } + + $content = $parsedown->text($content); + + if ($keepTwig) { + // Base64 decode the encoded twig. + $content = preg_replace_callback( + ['`' . $token[0] . '([A-Za-z0-9+/]+={0,2})' . $token[1] . '`mu'], + static function ($matches) { return base64_decode($matches[1]); }, + $content + ); + } + + $this->content = $content; + } + + + /** + * Process the Twig page content. + * + * @return void + */ + private function processTwig() + { + /** @var Twig $twig */ + $twig = Grav::instance()['twig']; + $this->content = $twig->processPage($this, $this->content); + } + + /** + * Fires the onPageContentProcessed event, and caches the page content using a unique ID for the page + * + * @return void + */ + public function cachePageContent() + { + /** @var Cache $cache */ + $cache = Grav::instance()['cache']; + $cache_id = md5('page' . $this->getCacheKey()); + $cache->save($cache_id, ['content' => $this->content, 'content_meta' => $this->content_meta]); + } + + /** + * Needed by the onPageContentProcessed event to get the raw page content + * + * @return string the current page content + */ + public function getRawContent() + { + return $this->content; + } + + /** + * Needed by the onPageContentProcessed event to set the raw page content + * + * @param string|null $content + * @return void + */ + public function setRawContent($content) + { + $this->content = $content ?? ''; + } + + /** + * Get value from a page variable (used mostly for creating edit forms). + * + * @param string $name Variable name. + * @param mixed $default + * @return mixed + */ + public function value($name, $default = null) + { + if ($name === 'content') { + return $this->raw_content; + } + if ($name === 'route') { + $parent = $this->parent(); + + return $parent ? $parent->rawRoute() : ''; + } + if ($name === 'order') { + $order = $this->order(); + + return $order ? (int)$this->order() : ''; + } + if ($name === 'ordering') { + return (bool)$this->order(); + } + if ($name === 'folder') { + return preg_replace(PAGE_ORDER_PREFIX_REGEX, '', $this->folder); + } + if ($name === 'slug') { + return $this->slug(); + } + if ($name === 'name') { + $name = $this->name(); + $language = $this->language() ? '.' . $this->language() : ''; + $pattern = '%(' . preg_quote($language, '%') . ')?\.md$%'; + $name = preg_replace($pattern, '', $name); + + if ($this->isModule()) { + return 'modular/' . $name; + } + + return $name; + } + if ($name === 'media') { + return $this->media()->all(); + } + if ($name === 'media.file') { + return $this->media()->files(); + } + if ($name === 'media.video') { + return $this->media()->videos(); + } + if ($name === 'media.image') { + return $this->media()->images(); + } + if ($name === 'media.audio') { + return $this->media()->audios(); + } + + $path = explode('.', $name); + $scope = array_shift($path); + + if ($name === 'frontmatter') { + return $this->frontmatter; + } + + if ($scope === 'header') { + $current = $this->header(); + foreach ($path as $field) { + if (is_object($current) && isset($current->{$field})) { + $current = $current->{$field}; + } elseif (is_array($current) && isset($current[$field])) { + $current = $current[$field]; + } else { + return $default; + } + } + + return $current; + } + + return $default; + } + + /** + * Gets and Sets the Page raw content + * + * @param string|null $var + * @return string + */ + public function rawMarkdown($var = null) + { + if ($var !== null) { + $this->raw_content = $var; + } + + return $this->raw_content; + } + + /** + * @return bool + * @internal + */ + public function translated(): bool + { + return $this->initialized; + } + + /** + * Get file object to the page. + * + * @return MarkdownFile|null + */ + public function file() + { + if ($this->name) { + return MarkdownFile::instance($this->filePath()); + } + + return null; + } + + /** + * Save page if there's a file assigned to it. + * + * @param bool|array $reorder Internal use. + */ + public function save($reorder = true) + { + // Perform move, copy [or reordering] if needed. + $this->doRelocation(); + + $file = $this->file(); + if ($file) { + $file->filename($this->filePath()); + $file->header((array)$this->header()); + $file->markdown($this->raw_content); + $file->save(); + } + + // Perform reorder if required + if ($reorder && is_array($reorder)) { + $this->doReorder($reorder); + } + + // We need to signal Flex Pages about the change. + /** @var Flex|null $flex */ + $flex = Grav::instance()['flex'] ?? null; + $directory = $flex ? $flex->getDirectory('pages') : null; + if (null !== $directory) { + $directory->clearCache(); + } + + $this->_original = null; + } + + /** + * Prepare move page to new location. Moves also everything that's under the current page. + * + * You need to call $this->save() in order to perform the move. + * + * @param PageInterface $parent New parent page. + * @return $this + */ + public function move(PageInterface $parent) + { + if (!$this->_original) { + $clone = clone $this; + $this->_original = $clone; + } + + $this->_action = 'move'; + + if ($this->route() === $parent->route()) { + throw new RuntimeException('Failed: Cannot set page parent to self'); + } + if (Utils::startsWith($parent->rawRoute(), $this->rawRoute())) { + throw new RuntimeException('Failed: Cannot set page parent to a child of current page'); + } + + $this->parent($parent); + $this->id(time() . md5($this->filePath())); + + if ($parent->path()) { + $this->path($parent->path() . '/' . $this->folder()); + } + + if ($parent->route()) { + $this->route($parent->route() . '/' . $this->slug()); + } else { + $this->route(Grav::instance()['pages']->root()->route() . '/' . $this->slug()); + } + + $this->raw_route = null; + + return $this; + } + + /** + * Prepare a copy from the page. Copies also everything that's under the current page. + * + * Returns a new Page object for the copy. + * You need to call $this->save() in order to perform the move. + * + * @param PageInterface $parent New parent page. + * @return $this + */ + public function copy(PageInterface $parent) + { + $this->move($parent); + $this->_action = 'copy'; + + return $this; + } + + /** + * Get blueprints for the page. + * + * @return Blueprint + */ + public function blueprints() + { + $grav = Grav::instance(); + + /** @var Pages $pages */ + $pages = $grav['pages']; + + $blueprint = $pages->blueprints($this->blueprintName()); + $fields = $blueprint->fields(); + $edit_mode = isset($grav['admin']) ? $grav['config']->get('plugins.admin.edit_mode') : null; + + // override if you only want 'normal' mode + if (empty($fields) && ($edit_mode === 'auto' || $edit_mode === 'normal')) { + $blueprint = $pages->blueprints('default'); + } + + // override if you only want 'expert' mode + if (!empty($fields) && $edit_mode === 'expert') { + $blueprint = $pages->blueprints(''); + } + + return $blueprint; + } + + /** + * Returns the blueprint from the page. + * + * @param string $name Not used. + * @return Blueprint Returns a Blueprint. + */ + public function getBlueprint(string $name = '') + { + return $this->blueprints(); + } + + /** + * Get the blueprint name for this page. Use the blueprint form field if set + * + * @return string + */ + public function blueprintName() + { + if (!isset($_POST['blueprint'])) { + return $this->template(); + } + + $post_value = $_POST['blueprint']; + $sanitized_value = htmlspecialchars(strip_tags($post_value), ENT_QUOTES, 'UTF-8'); + + return $sanitized_value ?: $this->template(); + } + + /** + * Validate page header. + * + * @return void + * @throws Exception + */ + public function validate() + { + $blueprints = $this->blueprints(); + $blueprints->validate($this->toArray()); + } + + /** + * Filter page header from illegal contents. + * + * @return void + */ + public function filter() + { + $blueprints = $this->blueprints(); + $values = $blueprints->filter($this->toArray()); + if ($values && isset($values['header'])) { + $this->header($values['header']); + } + } + + /** + * Get unknown header variables. + * + * @return array + */ + public function extra() + { + $blueprints = $this->blueprints(); + + return $blueprints->extra($this->toArray()['header'], 'header.'); + } + + /** + * Convert page to an array. + * + * @return array + */ + public function toArray() + { + return [ + 'header' => (array)$this->header(), + 'content' => (string)$this->value('content') + ]; + } + + /** + * Convert page to YAML encoded string. + * + * @return string + */ + public function toYaml() + { + return Yaml::dump($this->toArray(), 20); + } + + /** + * Convert page to JSON encoded string. + * + * @return string + */ + public function toJson() + { + return json_encode($this->toArray()); + } + + /** + * @return string + */ + public function getCacheKey(): string + { + return $this->id(); + } + + /** + * Gets and sets the associated media as found in the page folder. + * + * @param Media|null $var Representation of associated media. + * @return Media Representation of associated media. + */ + public function media($var = null) + { + if ($var) { + $this->setMedia($var); + } + + /** @var Media $media */ + $media = $this->getMedia(); + + return $media; + } + + /** + * Get filesystem path to the associated media. + * + * @return string|null + */ + public function getMediaFolder() + { + return $this->path(); + } + + /** + * Get display order for the associated media. + * + * @return array Empty array means default ordering. + */ + public function getMediaOrder() + { + $header = $this->header(); + + return isset($header->media_order) ? array_map('trim', explode(',', (string)$header->media_order)) : []; + } + + /** + * Gets and sets the name field. If no name field is set, it will return 'default.md'. + * + * @param string|null $var The name of this page. + * @return string The name of this page. + */ + public function name($var = null) + { + if ($var !== null) { + $this->name = $var; + } + + return $this->name ?: 'default.md'; + } + + /** + * Returns child page type. + * + * @return string + */ + public function childType() + { + return isset($this->header->child_type) ? (string)$this->header->child_type : ''; + } + + /** + * Gets and sets the template field. This is used to find the correct Twig template file to render. + * If no field is set, it will return the name without the .md extension + * + * @param string|null $var the template name + * @return string the template name + */ + public function template($var = null) + { + if ($var !== null) { + $this->template = $var; + } + if (empty($this->template)) { + $this->template = ($this->isModule() ? 'modular/' : '') . str_replace($this->extension(), '', $this->name()); + } + + return $this->template; + } + + /** + * Allows a page to override the output render format, usually the extension provided in the URL. + * (e.g. `html`, `json`, `xml`, etc). + * + * @param string|null $var + * @return string + */ + public function templateFormat($var = null) + { + if (null !== $var) { + $this->template_format = is_string($var) ? $var : null; + } + + if (!isset($this->template_format)) { + $this->template_format = ltrim($this->header->append_url_extension ?? Utils::getPageFormat(), '.'); + } + + return $this->template_format; + } + + /** + * Gets and sets the extension field. + * + * @param string|null $var + * @return string + */ + public function extension($var = null) + { + if ($var !== null) { + $this->extension = $var; + } + if (empty($this->extension)) { + $this->extension = '.' . Utils::pathinfo($this->name(), PATHINFO_EXTENSION); + } + + return $this->extension; + } + + /** + * Returns the page extension, got from the page `url_extension` config and falls back to the + * system config `system.pages.append_url_extension`. + * + * @return string The extension of this page. For example `.html` + */ + public function urlExtension() + { + if ($this->home()) { + return ''; + } + + // if not set in the page get the value from system config + if (null === $this->url_extension) { + $this->url_extension = Grav::instance()['config']->get('system.pages.append_url_extension', ''); + } + + return $this->url_extension; + } + + /** + * Gets and sets the expires field. If not set will return the default + * + * @param int|null $var The new expires value. + * @return int The expires value + */ + public function expires($var = null) + { + if ($var !== null) { + $this->expires = $var; + } + + return $this->expires ?? Grav::instance()['config']->get('system.pages.expires'); + } + + /** + * Gets and sets the cache-control property. If not set it will return the default value (null) + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control for more details on valid options + * + * @param string|null $var + * @return string|null + */ + public function cacheControl($var = null) + { + if ($var !== null) { + $this->cache_control = $var; + } + + return $this->cache_control ?? Grav::instance()['config']->get('system.pages.cache_control'); + } + + /** + * Gets and sets the title for this Page. If no title is set, it will use the slug() to get a name + * + * @param string|null $var the title of the Page + * @return string the title of the Page + */ + public function title($var = null) + { + if ($var !== null) { + $this->title = $var; + } + if (empty($this->title)) { + $this->title = ucfirst($this->slug()); + } + + return $this->title; + } + + /** + * Gets and sets the menu name for this Page. This is the text that can be used specifically for navigation. + * If no menu field is set, it will use the title() + * + * @param string|null $var the menu field for the page + * @return string the menu field for the page + */ + public function menu($var = null) + { + if ($var !== null) { + $this->menu = $var; + } + if (empty($this->menu)) { + $this->menu = $this->title(); + } + + return $this->menu; + } + + /** + * Gets and Sets whether or not this Page is visible for navigation + * + * @param bool|null $var true if the page is visible + * @return bool true if the page is visible + */ + public function visible($var = null) + { + if ($var !== null) { + $this->visible = (bool)$var; + } + + if ($this->visible === null) { + // Set item visibility in menu if folder is different from slug + // eg folder = 01.Home and slug = Home + if (preg_match(PAGE_ORDER_PREFIX_REGEX, $this->folder)) { + $this->visible = true; + } else { + $this->visible = false; + } + } + + return $this->visible; + } + + /** + * Gets and Sets whether or not this Page is considered published + * + * @param bool|null $var true if the page is published + * @return bool true if the page is published + */ + public function published($var = null) + { + if ($var !== null) { + $this->published = (bool)$var; + } + + // If not published, should not be visible in menus either + if ($this->published === false) { + $this->visible = false; + } + + return $this->published; + } + + /** + * Gets and Sets the Page publish date + * + * @param string|null $var string representation of a date + * @return int unix timestamp representation of the date + */ + public function publishDate($var = null) + { + if ($var !== null) { + $this->publish_date = Utils::date2timestamp($var, $this->dateformat); + } + + return $this->publish_date; + } + + /** + * Gets and Sets the Page unpublish date + * + * @param string|null $var string representation of a date + * @return int|null unix timestamp representation of the date + */ + public function unpublishDate($var = null) + { + if ($var !== null) { + $this->unpublish_date = Utils::date2timestamp($var, $this->dateformat); + } + + return $this->unpublish_date; + } + + /** + * Gets and Sets whether or not this Page is routable, ie you can reach it + * via a URL. + * The page must be *routable* and *published* + * + * @param bool|null $var true if the page is routable + * @return bool true if the page is routable + */ + public function routable($var = null) + { + if ($var !== null) { + $this->routable = (bool)$var; + } + + return $this->routable && $this->published(); + } + + /** + * @param bool|null $var + * @return bool + */ + public function ssl($var = null) + { + if ($var !== null) { + $this->ssl = (bool)$var; + } + + return $this->ssl; + } + + /** + * Gets and Sets the process setup for this Page. This is multi-dimensional array that consists of + * a simple array of arrays with the form array("markdown"=>true) for example + * + * @param array|null $var an Array of name value pairs where the name is the process and value is true or false + * @return array an Array of name value pairs where the name is the process and value is true or false + */ + public function process($var = null) + { + if ($var !== null) { + $this->process = (array)$var; + } + + return $this->process; + } + + /** + * Returns the state of the debugger override setting for this page + * + * @return bool + */ + public function debugger() + { + return !(isset($this->debugger) && $this->debugger === false); + } + + /** + * Function to merge page metadata tags and build an array of Metadata objects + * that can then be rendered in the page. + * + * @param array|null $var an Array of metadata values to set + * @return array an Array of metadata values for the page + */ + public function metadata($var = null) + { + if ($var !== null) { + $this->metadata = (array)$var; + } + + // if not metadata yet, process it. + if (null === $this->metadata) { + $header_tag_http_equivs = ['content-type', 'default-style', 'refresh', 'x-ua-compatible', 'content-security-policy']; + + $this->metadata = []; + + // Set the Generator tag + $metadata = [ + 'generator' => 'GravCMS' + ]; + + $config = Grav::instance()['config']; + + $escape = !$config->get('system.strict_mode.twig_compat', false) || $config->get('system.twig.autoescape', true); + + // Get initial metadata for the page + $metadata = array_merge($metadata, $config->get('site.metadata', [])); + + if (isset($this->header->metadata) && is_array($this->header->metadata)) { + // Merge any site.metadata settings in with page metadata + $metadata = array_merge($metadata, $this->header->metadata); + } + + // Build an array of meta objects.. + foreach ((array)$metadata as $key => $value) { + // Lowercase the key + $key = strtolower($key); + // If this is a property type metadata: "og", "twitter", "facebook" etc + // Backward compatibility for nested arrays in metas + if (is_array($value)) { + foreach ($value as $property => $prop_value) { + $prop_key = $key . ':' . $property; + $this->metadata[$prop_key] = [ + 'name' => $prop_key, + 'property' => $prop_key, + 'content' => $escape ? htmlspecialchars($prop_value, ENT_QUOTES | ENT_HTML5, 'UTF-8') : $prop_value + ]; + } + } else { + // If it this is a standard meta data type + if ($value) { + if (in_array($key, $header_tag_http_equivs, true)) { + $this->metadata[$key] = [ + 'http_equiv' => $key, + 'content' => $escape ? htmlspecialchars($value, ENT_COMPAT, 'UTF-8') : $value + ]; + } elseif ($key === 'charset') { + $this->metadata[$key] = ['charset' => $escape ? htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8') : $value]; + } else { + // if it's a social metadata with separator, render as property + $separator = strpos($key, ':'); + $hasSeparator = $separator && $separator < strlen($key) - 1; + $entry = [ + 'content' => $escape ? htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8') : $value + ]; + + if ($hasSeparator && !Utils::startsWith($key, ['twitter', 'flattr','fediverse'])) { + $entry['property'] = $key; + } else { + $entry['name'] = $key; + } + + $this->metadata[$key] = $entry; + } + } + } + } + } + + return $this->metadata; + } + + /** + * Reset the metadata and pull from header again + */ + public function resetMetadata() + { + $this->metadata = null; + } + + /** + * Gets and Sets the slug for the Page. The slug is used in the URL routing. If not set it uses + * the parent folder from the path + * + * @param string|null $var the slug, e.g. 'my-blog' + * @return string the slug + */ + public function slug($var = null) + { + if ($var !== null && $var !== '') { + $this->slug = $var; + } + + if (empty($this->slug)) { + $this->slug = $this->adjustRouteCase(preg_replace(PAGE_ORDER_PREFIX_REGEX, '', (string) $this->folder)) ?: null; + } + + return $this->slug; + } + + /** + * Get/set order number of this page. + * + * @param int|null $var + * @return string|bool + */ + public function order($var = null) + { + if ($var !== null) { + $order = $var ? sprintf('%02d.', (int)$var) : ''; + $this->folder($order . preg_replace(PAGE_ORDER_PREFIX_REGEX, '', $this->folder)); + + return $order; + } + + preg_match(PAGE_ORDER_PREFIX_REGEX, $this->folder, $order); + + return $order[0] ?? false; + } + + /** + * Gets the URL for a page - alias of url(). + * + * @param bool $include_host + * @return string the permalink + */ + public function link($include_host = false) + { + return $this->url($include_host); + } + + /** + * Gets the URL with host information, aka Permalink. + * @return string The permalink. + */ + public function permalink() + { + return $this->url(true, false, true, true); + } + + /** + * Returns the canonical URL for a page + * + * @param bool $include_lang + * @return string + */ + public function canonical($include_lang = true) + { + return $this->url(true, true, $include_lang); + } + + /** + * Gets the url for the Page. + * + * @param bool $include_host Defaults false, but true would include http://yourhost.com + * @param bool $canonical True to return the canonical URL + * @param bool $include_base Include base url on multisite as well as language code + * @param bool $raw_route + * @return string The url. + */ + public function url($include_host = false, $canonical = false, $include_base = true, $raw_route = false) + { + // Override any URL when external_url is set + if (isset($this->external_url)) { + return $this->external_url; + } + + $grav = Grav::instance(); + + /** @var Pages $pages */ + $pages = $grav['pages']; + + /** @var Config $config */ + $config = $grav['config']; + + // get base route (multi-site base and language) + $route = $include_base ? $pages->baseRoute() : ''; + + // add full route if configured to do so + if (!$include_host && $config->get('system.absolute_urls', false)) { + $include_host = true; + } + + if ($canonical) { + $route .= $this->routeCanonical(); + } elseif ($raw_route) { + $route .= $this->rawRoute(); + } else { + $route .= $this->route(); + } + + /** @var Uri $uri */ + $uri = $grav['uri']; + $url = $uri->rootUrl($include_host) . '/' . trim($route, '/') . $this->urlExtension(); + + return Uri::filterPath($url); + } + + /** + * Gets the route for the page based on the route headers if available, else from + * the parents route and the current Page's slug. + * + * @param string|null $var Set new default route. + * @return string|null The route for the Page. + */ + public function route($var = null) + { + if ($var !== null) { + $this->route = $var; + } + + if (empty($this->route)) { + $baseRoute = null; + + // calculate route based on parent slugs + $parent = $this->parent(); + if (isset($parent)) { + if ($this->hide_home_route && $parent->route() === $this->home_route) { + $baseRoute = ''; + } else { + $baseRoute = (string)$parent->route(); + } + } + + $this->route = isset($baseRoute) ? $baseRoute . '/' . $this->slug() : null; + + if (!empty($this->routes) && isset($this->routes['default'])) { + $this->routes['aliases'][] = $this->route; + $this->route = $this->routes['default']; + + return $this->route; + } + } + + return $this->route; + } + + /** + * Helper method to clear the route out so it regenerates next time you use it + */ + public function unsetRouteSlug() + { + unset($this->route, $this->slug); + } + + /** + * Gets and Sets the page raw route + * + * @param string|null $var + * @return null|string + */ + public function rawRoute($var = null) + { + if ($var !== null) { + $this->raw_route = $var; + } + + if (empty($this->raw_route)) { + $parent = $this->parent(); + $baseRoute = $parent ? (string)$parent->rawRoute() : null; + + $slug = $this->adjustRouteCase(preg_replace(PAGE_ORDER_PREFIX_REGEX, '', $this->folder)); + + $this->raw_route = isset($baseRoute) ? $baseRoute . '/' . $slug : null; + } + + return $this->raw_route; + } + + /** + * Gets the route aliases for the page based on page headers. + * + * @param array|null $var list of route aliases + * @return array The route aliases for the Page. + */ + public function routeAliases($var = null) + { + if ($var !== null) { + $this->routes['aliases'] = (array)$var; + } + + if (!empty($this->routes) && isset($this->routes['aliases'])) { + return $this->routes['aliases']; + } + + return []; + } + + /** + * Gets the canonical route for this page if its set. If provided it will use + * that value, else if it's `true` it will use the default route. + * + * @param string|null $var + * @return bool|string + */ + public function routeCanonical($var = null) + { + if ($var !== null) { + $this->routes['canonical'] = $var; + } + + if (!empty($this->routes) && isset($this->routes['canonical'])) { + return $this->routes['canonical']; + } + + return $this->route(); + } + + /** + * Gets and sets the identifier for this Page object. + * + * @param string|null $var the identifier + * @return string the identifier + */ + public function id($var = null) + { + if (null === $this->id) { + // We need to set unique id to avoid potential cache conflicts between pages. + $var = time() . md5($this->filePath()); + } + if ($var !== null) { + // store unique per language + $active_lang = Grav::instance()['language']->getLanguage() ?: ''; + $id = $active_lang . $var; + $this->id = $id; + } + + return $this->id; + } + + /** + * Gets and sets the modified timestamp. + * + * @param int|null $var modified unix timestamp + * @return int modified unix timestamp + */ + public function modified($var = null) + { + if ($var !== null) { + $this->modified = $var; + } + + return $this->modified; + } + + /** + * Gets the redirect set in the header. + * + * @param string|null $var redirect url + * @return string|null + */ + public function redirect($var = null) + { + if ($var !== null) { + $this->redirect = $var; + } + + return $this->redirect ?: null; + } + + /** + * Gets and sets the option to show the etag header for the page. + * + * @param bool|null $var show etag header + * @return bool show etag header + */ + public function eTag($var = null): bool + { + if ($var !== null) { + $this->etag = $var; + } + if (!isset($this->etag)) { + $this->etag = (bool)Grav::instance()['config']->get('system.pages.etag'); + } + + return $this->etag ?? false; + } + + /** + * Gets and sets the option to show the last_modified header for the page. + * + * @param bool|null $var show last_modified header + * @return bool show last_modified header + */ + public function lastModified($var = null) + { + if ($var !== null) { + $this->last_modified = $var; + } + if (!isset($this->last_modified)) { + $this->last_modified = (bool)Grav::instance()['config']->get('system.pages.last_modified'); + } + + return $this->last_modified; + } + + /** + * Gets and sets the path to the .md file for this Page object. + * + * @param string|null $var the file path + * @return string|null the file path + */ + public function filePath($var = null) + { + if ($var !== null) { + // Filename of the page. + $this->name = Utils::basename($var); + // Folder of the page. + $this->folder = Utils::basename(dirname($var)); + // Path to the page. + $this->path = dirname($var, 2); + } + + return rtrim($this->path . '/' . $this->folder . '/' . ($this->name() ?: ''), '/'); + } + + /** + * Gets the relative path to the .md file + * + * @return string The relative file path + */ + public function filePathClean() + { + return str_replace(GRAV_ROOT . DS, '', $this->filePath()); + } + + /** + * Returns the clean path to the page file + * + * @return string + */ + public function relativePagePath() + { + return str_replace('/' . $this->name(), '', $this->filePathClean()); + } + + /** + * Gets and sets the path to the folder where the .md for this Page object resides. + * This is equivalent to the filePath but without the filename. + * + * @param string|null $var the path + * @return string|null the path + */ + public function path($var = null) + { + if ($var !== null) { + // Folder of the page. + $this->folder = Utils::basename($var); + // Path to the page. + $this->path = dirname($var); + } + + return $this->path ? $this->path . '/' . $this->folder : null; + } + + /** + * Get/set the folder. + * + * @param string|null $var Optional path + * @return string|null + */ + public function folder($var = null) + { + if ($var !== null) { + $this->folder = $var; + } + + return $this->folder; + } + + /** + * Gets and sets the date for this Page object. This is typically passed in via the page headers + * + * @param string|null $var string representation of a date + * @return int unix timestamp representation of the date + */ + public function date($var = null) + { + if ($var !== null) { + $this->date = Utils::date2timestamp($var, $this->dateformat); + } + + if (!$this->date) { + $this->date = $this->modified; + } + + return $this->date; + } + + /** + * Gets and sets the date format for this Page object. This is typically passed in via the page headers + * using typical PHP date string structure - http://php.net/manual/en/function.date.php + * + * @param string|null $var string representation of a date format + * @return string string representation of a date format + */ + public function dateformat($var = null) + { + if ($var !== null) { + $this->dateformat = $var; + } + + return $this->dateformat; + } + + /** + * Gets and sets the order by which any sub-pages should be sorted. + * + * @param string|null $var the order, either "asc" or "desc" + * @return string the order, either "asc" or "desc" + * @deprecated 1.6 + */ + public function orderDir($var = null) + { + //user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6', E_USER_DEPRECATED); + + if ($var !== null) { + $this->order_dir = $var; + } + + if (empty($this->order_dir)) { + $this->order_dir = 'asc'; + } + + return $this->order_dir; + } + + /** + * Gets and sets the order by which the sub-pages should be sorted. + * + * default - is the order based on the file system, ie 01.Home before 02.Advark + * title - is the order based on the title set in the pages + * date - is the order based on the date set in the pages + * folder - is the order based on the name of the folder with any numerics omitted + * + * @param string|null $var supported options include "default", "title", "date", and "folder" + * @return string supported options include "default", "title", "date", and "folder" + * @deprecated 1.6 + */ + public function orderBy($var = null) + { + //user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6', E_USER_DEPRECATED); + + if ($var !== null) { + $this->order_by = $var; + } + + return $this->order_by; + } + + /** + * Gets the manual order set in the header. + * + * @param string|null $var supported options include "default", "title", "date", and "folder" + * @return array + * @deprecated 1.6 + */ + public function orderManual($var = null) + { + //user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6', E_USER_DEPRECATED); + + if ($var !== null) { + $this->order_manual = $var; + } + + return (array)$this->order_manual; + } + + /** + * Gets and sets the maxCount field which describes how many sub-pages should be displayed if the + * sub_pages header property is set for this page object. + * + * @param int|null $var the maximum number of sub-pages + * @return int the maximum number of sub-pages + * @deprecated 1.6 + */ + public function maxCount($var = null) + { + //user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6', E_USER_DEPRECATED); + + if ($var !== null) { + $this->max_count = (int)$var; + } + if (empty($this->max_count)) { + /** @var Config $config */ + $config = Grav::instance()['config']; + $this->max_count = (int)$config->get('system.pages.list.count'); + } + + return $this->max_count; + } + + /** + * Gets and sets the taxonomy array which defines which taxonomies this page identifies itself with. + * + * @param array|null $var an array of taxonomies + * @return array an array of taxonomies + */ + public function taxonomy($var = null) + { + if ($var !== null) { + // make sure first level are arrays + array_walk($var, static function (&$value) { + $value = (array) $value; + }); + // make sure all values are strings + array_walk_recursive($var, static function (&$value) { + $value = (string) $value; + }); + $this->taxonomy = $var; + } + + return $this->taxonomy; + } + + /** + * Gets and sets the modular var that helps identify this page is a modular child + * + * @param bool|null $var true if modular_twig + * @return bool true if modular_twig + * @deprecated 1.7 Use ->isModule() or ->modularTwig() method instead. + */ + public function modular($var = null) + { + user_error(__METHOD__ . '() is deprecated since Grav 1.7, use ->isModule() or ->modularTwig() method instead', E_USER_DEPRECATED); + + return $this->modularTwig($var); + } + + /** + * Gets and sets the modular_twig var that helps identify this page as a modular child page that will need + * twig processing handled differently from a regular page. + * + * @param bool|null $var true if modular_twig + * @return bool true if modular_twig + */ + public function modularTwig($var = null) + { + if ($var !== null) { + $this->modular_twig = (bool)$var; + if ($var) { + $this->visible(false); + // some routable logic + if (empty($this->header->routable)) { + $this->routable = false; + } + } + } + + return $this->modular_twig ?? false; + } + + /** + * Gets the configured state of the processing method. + * + * @param string $process the process, eg "twig" or "markdown" + * @return bool whether or not the processing method is enabled for this Page + */ + public function shouldProcess($process) + { + return (bool)($this->process[$process] ?? false); + } + + /** + * Gets and Sets the parent object for this page + * + * @param PageInterface|null $var the parent page object + * @return PageInterface|null the parent page object if it exists. + */ + public function parent(PageInterface $var = null) + { + if ($var) { + $this->parent = $var->path(); + + return $var; + } + + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + return $pages->get($this->parent); + } + + /** + * Gets the top parent object for this page. Can return page itself. + * + * @return PageInterface The top parent page object. + */ + public function topParent() + { + $topParent = $this; + + while (true) { + $theParent = $topParent->parent(); + if ($theParent !== null && $theParent->parent() !== null) { + $topParent = $theParent; + } else { + break; + } + } + + return $topParent; + } + + /** + * Returns children of this page. + * + * @return PageCollectionInterface|Collection + */ + public function children() + { + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + return $pages->children($this->path()); + } + + + /** + * Check to see if this item is the first in an array of sub-pages. + * + * @return bool True if item is first. + */ + public function isFirst() + { + $parent = $this->parent(); + $collection = $parent ? $parent->collection('content', false) : null; + if ($collection instanceof Collection) { + return $collection->isFirst($this->path()); + } + + return true; + } + + /** + * Check to see if this item is the last in an array of sub-pages. + * + * @return bool True if item is last + */ + public function isLast() + { + $parent = $this->parent(); + $collection = $parent ? $parent->collection('content', false) : null; + if ($collection instanceof Collection) { + return $collection->isLast($this->path()); + } + + return true; + } + + /** + * Gets the previous sibling based on current position. + * + * @return PageInterface the previous Page item + */ + public function prevSibling() + { + return $this->adjacentSibling(-1); + } + + /** + * Gets the next sibling based on current position. + * + * @return PageInterface the next Page item + */ + public function nextSibling() + { + return $this->adjacentSibling(1); + } + + /** + * Returns the adjacent sibling based on a direction. + * + * @param int $direction either -1 or +1 + * @return PageInterface|false the sibling page + */ + public function adjacentSibling($direction = 1) + { + $parent = $this->parent(); + $collection = $parent ? $parent->collection('content', false) : null; + if ($collection instanceof Collection) { + return $collection->adjacentSibling($this->path(), $direction); + } + + return false; + } + + /** + * Returns the item in the current position. + * + * @return int|null The index of the current page. + */ + public function currentPosition() + { + $parent = $this->parent(); + $collection = $parent ? $parent->collection('content', false) : null; + if ($collection instanceof Collection) { + return $collection->currentPosition($this->path()); + } + + return 1; + } + + /** + * Returns whether or not this page is the currently active page requested via the URL. + * + * @return bool True if it is active + */ + public function active() + { + $uri_path = rtrim(urldecode(Grav::instance()['uri']->path()), '/') ?: '/'; + $routes = Grav::instance()['pages']->routes(); + + return isset($routes[$uri_path]) && $routes[$uri_path] === $this->path(); + } + + /** + * Returns whether or not this URI's URL contains the URL of the active page. + * Or in other words, is this page's URL in the current URL + * + * @return bool True if active child exists + */ + public function activeChild() + { + $grav = Grav::instance(); + /** @var Uri $uri */ + $uri = $grav['uri']; + /** @var Pages $pages */ + $pages = $grav['pages']; + $uri_path = rtrim(urldecode($uri->path()), '/'); + $routes = $pages->routes(); + + if (isset($routes[$uri_path])) { + $page = $pages->find($uri->route()); + /** @var PageInterface|null $child_page */ + $child_page = $page ? $page->parent() : null; + while ($child_page && !$child_page->root()) { + if ($this->path() === $child_page->path()) { + return true; + } + $child_page = $child_page->parent(); + } + } + + return false; + } + + /** + * Returns whether or not this page is the currently configured home page. + * + * @return bool True if it is the homepage + */ + public function home() + { + $home = Grav::instance()['config']->get('system.home.alias'); + + return $this->route() === $home || $this->rawRoute() === $home; + } + + /** + * Returns whether or not this page is the root node of the pages tree. + * + * @return bool True if it is the root + */ + public function root() + { + return !$this->parent && !$this->name && !$this->visible; + } + + /** + * Helper method to return an ancestor page. + * + * @param bool|null $lookup Name of the parent folder + * @return PageInterface page you were looking for if it exists + */ + public function ancestor($lookup = null) + { + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + return $pages->ancestor($this->route, $lookup); + } + + /** + * Helper method to return an ancestor page to inherit from. The current + * page object is returned. + * + * @param string $field Name of the parent folder + * @return PageInterface + */ + public function inherited($field) + { + [$inherited, $currentParams] = $this->getInheritedParams($field); + + $this->modifyHeader($field, $currentParams); + + return $inherited; + } + + /** + * Helper method to return an ancestor field only to inherit from. The + * first occurrence of an ancestor field will be returned if at all. + * + * @param string $field Name of the parent folder + * + * @return array + */ + public function inheritedField($field) + { + [$inherited, $currentParams] = $this->getInheritedParams($field); + + return $currentParams; + } + + /** + * Method that contains shared logic for inherited() and inheritedField() + * + * @param string $field Name of the parent folder + * @return array + */ + protected function getInheritedParams($field) + { + $pages = Grav::instance()['pages']; + + /** @var Pages $pages */ + $inherited = $pages->inherited($this->route, $field); + $inheritedParams = $inherited ? (array)$inherited->value('header.' . $field) : []; + $currentParams = (array)$this->value('header.' . $field); + if ($inheritedParams && is_array($inheritedParams)) { + $currentParams = array_replace_recursive($inheritedParams, $currentParams); + } + + return [$inherited, $currentParams]; + } + + /** + * Helper method to return a page. + * + * @param string $url the url of the page + * @param bool $all + * + * @return PageInterface page you were looking for if it exists + */ + public function find($url, $all = false) + { + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + return $pages->find($url, $all); + } + + /** + * Get a collection of pages in the current context. + * + * @param string|array $params + * @param bool $pagination + * + * @return PageCollectionInterface|Collection + * @throws InvalidArgumentException + */ + public function collection($params = 'content', $pagination = true) + { + if (is_string($params)) { + // Look into a page header field. + $params = (array)$this->value('header.' . $params); + } elseif (!is_array($params)) { + throw new InvalidArgumentException('Argument should be either header variable name or array of parameters'); + } + + $params['filter'] = ($params['filter'] ?? []) + ['translated' => true]; + $context = [ + 'pagination' => $pagination, + 'self' => $this + ]; + + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + return $pages->getCollection($params, $context); + } + + /** + * @param string|array $value + * @param bool $only_published + * @return PageCollectionInterface|Collection + */ + public function evaluate($value, $only_published = true) + { + $params = [ + 'items' => $value, + 'published' => $only_published + ]; + $context = [ + 'event' => false, + 'pagination' => false, + 'url_taxonomy_filters' => false, + 'self' => $this + ]; + + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + return $pages->getCollection($params, $context); + } + + /** + * Returns whether or not this Page object has a .md file associated with it or if its just a directory. + * + * @return bool True if its a page with a .md file associated + */ + public function isPage() + { + if ($this->name) { + return true; + } + + return false; + } + + /** + * Returns whether or not this Page object is a directory or a page. + * + * @return bool True if its a directory + */ + public function isDir() + { + return !$this->isPage(); + } + + /** + * @return bool + */ + public function isModule(): bool + { + return $this->modularTwig(); + } + + /** + * Returns whether the page exists in the filesystem. + * + * @return bool + */ + public function exists() + { + $file = $this->file(); + + return $file && $file->exists(); + } + + /** + * Returns whether or not the current folder exists + * + * @return bool + */ + public function folderExists() + { + return file_exists($this->path()); + } + + /** + * Cleans the path. + * + * @param string $path the path + * @return string the path + */ + protected function cleanPath($path) + { + $lastchunk = strrchr($path, DS); + if (strpos($lastchunk, ':') !== false) { + $path = str_replace($lastchunk, '', $path); + } + + return $path; + } + + /** + * Reorders all siblings according to a defined order + * + * @param array|null $new_order + */ + protected function doReorder($new_order) + { + if (!$this->_original) { + return; + } + + $pages = Grav::instance()['pages']; + $pages->init(); + + $this->_original->path($this->path()); + + $parent = $this->parent(); + $siblings = $parent ? $parent->children() : null; + + if ($siblings) { + $siblings->order('slug', 'asc', $new_order); + + $counter = 0; + + // Reorder all moved pages. + foreach ($siblings as $slug => $page) { + $order = (int)trim($page->order(), '.'); + $counter++; + + if ($order) { + if ($page->path() === $this->path() && $this->folderExists()) { + // Handle current page; we do want to change ordering number, but nothing else. + $this->order($counter); + $this->save(false); + } else { + // Handle all the other pages. + $page = $pages->get($page->path()); + if ($page && $page->folderExists() && !$page->_action) { + $page = $page->move($this->parent()); + $page->order($counter); + $page->save(false); + } + } + } + } + } + } + + /** + * Moves or copies the page in filesystem. + * + * @internal + * @return void + * @throws Exception + */ + protected function doRelocation() + { + if (!$this->_original) { + return; + } + + if (is_dir($this->_original->path())) { + if ($this->_action === 'move') { + Folder::move($this->_original->path(), $this->path()); + } elseif ($this->_action === 'copy') { + Folder::copy($this->_original->path(), $this->path()); + } + } + + if ($this->name() !== $this->_original->name()) { + $path = $this->path(); + if (is_file($path . '/' . $this->_original->name())) { + rename($path . '/' . $this->_original->name(), $path . '/' . $this->name()); + } + } + } + + /** + * @return void + */ + protected function setPublishState() + { + // Handle publishing dates if no explicit published option set + if (Grav::instance()['config']->get('system.pages.publish_dates') && !isset($this->header->published)) { + // unpublish if required, if not clear cache right before page should be unpublished + if ($this->unpublishDate()) { + if ($this->unpublishDate() < time()) { + $this->published(false); + } else { + $this->published(); + Grav::instance()['cache']->setLifeTime($this->unpublishDate()); + } + } + // publish if required, if not clear cache right before page is published + if ($this->publishDate() && $this->publishDate() > time()) { + $this->published(false); + Grav::instance()['cache']->setLifeTime($this->publishDate()); + } + } + } + + /** + * @param string $route + * @return string + */ + protected function adjustRouteCase($route) + { + $case_insensitive = Grav::instance()['config']->get('system.force_lowercase_urls'); + + return $case_insensitive ? mb_strtolower($route) : $route; + } + + /** + * Gets the Page Unmodified (original) version of the page. + * + * @return PageInterface The original version of the page. + */ + public function getOriginal() + { + return $this->_original; + } + + /** + * Gets the action. + * + * @return string|null The Action string. + */ + public function getAction() + { + return $this->_action; + } +} diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php new file mode 100644 index 0000000..df23287 --- /dev/null +++ b/system/src/Grav/Common/Page/Pages.php @@ -0,0 +1,2258 @@ + */ + protected $instances = []; + /** @var array */ + protected $index = []; + /** @var array */ + protected $children; + /** @var string */ + protected $base = ''; + /** @var string[] */ + protected $baseRoute = []; + /** @var string[] */ + protected $routes = []; + /** @var array */ + protected $sort; + /** @var Blueprints */ + protected $blueprints; + /** @var bool */ + protected $enable_pages = true; + /** @var int */ + protected $last_modified; + /** @var string[] */ + protected $ignore_files; + /** @var string[] */ + protected $ignore_folders; + /** @var bool */ + protected $ignore_hidden; + /** @var string */ + protected $check_method; + /** @var string */ + protected $simple_pages_hash; + /** @var string */ + protected $pages_cache_id; + /** @var bool */ + protected $initialized = false; + /** @var string */ + protected $active_lang; + /** @var bool */ + protected $fire_events = false; + /** @var Types|null */ + protected static $types; + /** @var string|null */ + protected static $home_route; + + + /** + * Constructor + * + * @param Grav $grav + */ + public function __construct(Grav $grav) + { + $this->grav = $grav; + } + + /** + * @return FlexDirectory|null + */ + public function getDirectory(): ?FlexDirectory + { + return $this->directory; + } + + /** + * Method used in admin to disable frontend pages from being initialized. + */ + public function disablePages(): void + { + $this->enable_pages = false; + } + + /** + * Method used in admin to later load frontend pages. + */ + public function enablePages(): void + { + if (!$this->enable_pages) { + $this->enable_pages = true; + + $this->init(); + } + } + + /** + * Get or set base path for the pages. + * + * @param string|null $path + * @return string + */ + public function base($path = null) + { + if ($path !== null) { + $path = trim($path, '/'); + $this->base = $path ? '/' . $path : ''; + $this->baseRoute = []; + } + + return $this->base; + } + + /** + * + * Get base route for Grav pages. + * + * @param string|null $lang Optional language code for multilingual routes. + * @return string + */ + public function baseRoute($lang = null) + { + $key = $lang ?: $this->active_lang ?: 'default'; + + if (!isset($this->baseRoute[$key])) { + /** @var Language $language */ + $language = $this->grav['language']; + + $path_base = rtrim($this->base(), '/'); + $path_lang = $language->enabled() ? $language->getLanguageURLPrefix($lang) : ''; + + $this->baseRoute[$key] = $path_base . $path_lang; + } + + return $this->baseRoute[$key]; + } + + /** + * + * Get route for Grav site. + * + * @param string $route Optional route to the page. + * @param string|null $lang Optional language code for multilingual links. + * @return string + */ + public function route($route = '/', $lang = null) + { + if (!$route || $route === '/') { + return $this->baseRoute($lang) ?: '/'; + } + + return $this->baseRoute($lang) . $route; + } + + /** + * Get relative referrer route and language code. Returns null if the route isn't within the current base, language (if set) and route. + * + * @example `$langCode = null; $referrer = $pages->referrerRoute($langCode, '/admin');` returns relative referrer url within /admin and updates $langCode + * @example `$langCode = 'en'; $referrer = $pages->referrerRoute($langCode, '/admin');` returns relative referrer url within the /en/admin + * + * @param string|null $langCode Variable to store the language code. If already set, check only against that language. + * @param string $route Optional route within the site. + * @return string|null + * @since 1.7.23 + */ + public function referrerRoute(?string &$langCode, string $route = '/'): ?string + { + $referrer = $_SERVER['HTTP_REFERER'] ?? null; + + // Start by checking that referrer came from our site. + $root = $this->grav['base_url_absolute']; + if (!is_string($referrer) || !str_starts_with($referrer, $root)) { + return null; + } + + /** @var Language $language */ + $language = $this->grav['language']; + + // Get all language codes and append no language. + if (null === $langCode) { + $languages = $language->enabled() ? $language->getLanguages() : []; + $languages[] = ''; + } else { + $languages[] = $langCode; + } + + $path_base = rtrim($this->base(), '/'); + $path_route = rtrim($route, '/'); + + // Try to figure out the language code. + foreach ($languages as $code) { + $path_lang = $code ? "/{$code}" : ''; + + $base = $path_base . $path_lang . $path_route; + if ($referrer === $base || str_starts_with($referrer, "{$base}/")) { + if (null === $langCode) { + $langCode = $code; + } + + return substr($referrer, \strlen($base)); + } + } + + return null; + } + + /** + * + * Get base URL for Grav pages. + * + * @param string|null $lang Optional language code for multilingual links. + * @param bool|null $absolute If true, return absolute url, if false, return relative url. Otherwise return default. + * @return string + */ + public function baseUrl($lang = null, $absolute = null) + { + if ($absolute === null) { + $type = 'base_url'; + } elseif ($absolute) { + $type = 'base_url_absolute'; + } else { + $type = 'base_url_relative'; + } + + return $this->grav[$type] . $this->baseRoute($lang); + } + + /** + * + * Get home URL for Grav site. + * + * @param string|null $lang Optional language code for multilingual links. + * @param bool|null $absolute If true, return absolute url, if false, return relative url. Otherwise return default. + * @return string + */ + public function homeUrl($lang = null, $absolute = null) + { + return $this->baseUrl($lang, $absolute) ?: '/'; + } + + /** + * + * Get URL for Grav site. + * + * @param string $route Optional route to the page. + * @param string|null $lang Optional language code for multilingual links. + * @param bool|null $absolute If true, return absolute url, if false, return relative url. Otherwise return default. + * @return string + */ + public function url($route = '/', $lang = null, $absolute = null) + { + if (!$route || $route === '/') { + return $this->homeUrl($lang, $absolute); + } + + return $this->baseUrl($lang, $absolute) . Uri::filterPath($route); + } + + /** + * @param string $method + * @return void + */ + public function setCheckMethod($method): void + { + $this->check_method = strtolower($method); + } + + /** + * @return void + */ + public function register(): void + { + $config = $this->grav['config']; + $type = $config->get('system.pages.type'); + if ($type === 'flex') { + $this->initFlexPages(); + } + } + + /** + * Reset pages (used in search indexing etc). + * + * @return void + */ + public function reset(): void + { + $this->initialized = false; + + $this->init(); + } + + /** + * Class initialization. Must be called before using this class. + */ + public function init(): void + { + if ($this->initialized) { + return; + } + + $config = $this->grav['config']; + $this->ignore_files = (array)$config->get('system.pages.ignore_files'); + $this->ignore_folders = (array)$config->get('system.pages.ignore_folders'); + $this->ignore_hidden = (bool)$config->get('system.pages.ignore_hidden'); + $this->fire_events = (bool)$config->get('system.pages.events.page'); + + $this->instances = []; + $this->index = []; + $this->children = []; + $this->routes = []; + + if (!$this->check_method) { + $this->setCheckMethod($config->get('system.cache.check.method', 'file')); + } + + if ($this->enable_pages === false) { + $page = $this->buildRootPage(); + $this->instances[$page->path()] = $page; + + return; + } + + $this->buildPages(); + + $this->initialized = true; + } + + /** + * Get or set last modification time. + * + * @param int|null $modified + * @return int|null + */ + public function lastModified($modified = null) + { + if ($modified && $modified > $this->last_modified) { + $this->last_modified = $modified; + } + + return $this->last_modified; + } + + /** + * Returns a list of all pages. + * + * @return PageInterface[] + */ + public function instances() + { + $instances = []; + foreach ($this->index as $path => $instance) { + $page = $this->get($path); + if ($page) { + $instances[$path] = $page; + } + } + + return $instances; + } + + /** + * Returns a list of all routes. + * + * @return array + */ + public function routes() + { + return $this->routes; + } + + /** + * Adds a page and assigns a route to it. + * + * @param PageInterface $page Page to be added. + * @param string|null $route Optional route (uses route from the object if not set). + */ + public function addPage(PageInterface $page, $route = null): void + { + $path = $page->path() ?? ''; + if (!isset($this->index[$path])) { + $this->index[$path] = $page; + $this->instances[$path] = $page; + } + $route = $page->route($route); + $parent = $page->parent(); + if ($parent) { + $this->children[$parent->path() ?? ''][$path] = ['slug' => $page->slug()]; + } + $this->routes[$route] = $path; + + $this->grav->fireEvent('onPageProcessed', new Event(['page' => $page])); + } + + /** + * Get a collection of pages in the given context. + * + * @param array $params + * @param array $context + * @return PageCollectionInterface|Collection + */ + public function getCollection(array $params = [], array $context = []) + { + if (!isset($params['items'])) { + return new Collection(); + } + + /** @var Config $config */ + $config = $this->grav['config']; + + $context += [ + 'event' => true, + 'pagination' => true, + 'url_taxonomy_filters' => $config->get('system.pages.url_taxonomy_filters'), + 'taxonomies' => (array)$config->get('site.taxonomies'), + 'pagination_page' => 1, + 'self' => null, + ]; + + // Include taxonomies from the URL if requested. + $process_taxonomy = $params['url_taxonomy_filters'] ?? $context['url_taxonomy_filters']; + if ($process_taxonomy) { + /** @var Uri $uri */ + $uri = $this->grav['uri']; + foreach ($context['taxonomies'] as $taxonomy) { + $param = $uri->param(rawurlencode($taxonomy)); + $items = is_string($param) ? explode(',', $param) : []; + foreach ($items as $item) { + $params['taxonomies'][$taxonomy][] = htmlspecialchars_decode(rawurldecode($item), ENT_QUOTES); + } + } + } + + $pagination = $params['pagination'] ?? $context['pagination']; + if ($pagination && !isset($params['page'], $params['start'])) { + /** @var Uri $uri */ + $uri = $this->grav['uri']; + $context['current_page'] = $uri->currentPage(); + } + + $collection = $this->evaluate($params['items'], $context['self']); + $collection->setParams($params); + + // Filter by taxonomies. + foreach ($params['taxonomies'] ?? [] as $taxonomy => $items) { + foreach ($collection as $page) { + // Don't include modules + if ($page->isModule()) { + continue; + } + + $test = $page->taxonomy()[$taxonomy] ?? []; + foreach ($items as $item) { + if (!$test || !in_array($item, $test, true)) { + $collection->remove($page->path()); + } + } + } + } + + $filters = $params['filter'] ?? []; + + // Assume published=true if not set. + if (!isset($filters['published']) && !isset($filters['non-published'])) { + $filters['published'] = true; + } + + // Remove any inclusive sets from filter. + $sets = ['published', 'visible', 'modular', 'routable']; + foreach ($sets as $type) { + $nonType = "non-{$type}"; + if (isset($filters[$type], $filters[$nonType]) && $filters[$type] === $filters[$nonType]) { + if (!$filters[$type]) { + // Both options are false, return empty collection as nothing can match the filters. + return new Collection(); + } + + // Both options are true, remove opposite filters as all pages will match the filters. + unset($filters[$type], $filters[$nonType]); + } + } + + // Filter the collection + foreach ($filters as $type => $filter) { + if (null === $filter) { + continue; + } + + // Convert non-type to type. + if (str_starts_with($type, 'non-')) { + $type = substr($type, 4); + $filter = !$filter; + } + + switch ($type) { + case 'translated': + if ($filter) { + $collection = $collection->translated(); + } else { + $collection = $collection->nonTranslated(); + } + break; + case 'published': + if ($filter) { + $collection = $collection->published(); + } else { + $collection = $collection->nonPublished(); + } + break; + case 'visible': + if ($filter) { + $collection = $collection->visible(); + } else { + $collection = $collection->nonVisible(); + } + break; + case 'page': + if ($filter) { + $collection = $collection->pages(); + } else { + $collection = $collection->modules(); + } + break; + case 'module': + case 'modular': + if ($filter) { + $collection = $collection->modules(); + } else { + $collection = $collection->pages(); + } + break; + case 'routable': + if ($filter) { + $collection = $collection->routable(); + } else { + $collection = $collection->nonRoutable(); + } + break; + case 'type': + $collection = $collection->ofType($filter); + break; + case 'types': + $collection = $collection->ofOneOfTheseTypes($filter); + break; + case 'access': + $collection = $collection->ofOneOfTheseAccessLevels($filter); + break; + } + } + + if (isset($params['dateRange'])) { + $start = $params['dateRange']['start'] ?? null; + $end = $params['dateRange']['end'] ?? null; + $field = $params['dateRange']['field'] ?? null; + $collection = $collection->dateRange($start, $end, $field); + } + + if (isset($params['order'])) { + $by = $params['order']['by'] ?? 'default'; + $dir = $params['order']['dir'] ?? 'asc'; + $custom = $params['order']['custom'] ?? null; + $sort_flags = $params['order']['sort_flags'] ?? null; + + if (is_array($sort_flags)) { + $sort_flags = array_map('constant', $sort_flags); //transform strings to constant value + $sort_flags = array_reduce($sort_flags, static function ($a, $b) { + return $a | $b; + }, 0); //merge constant values using bit or + } + + $collection = $collection->order($by, $dir, $custom, $sort_flags); + } + + // New Custom event to handle things like pagination. + if ($context['event']) { + $this->grav->fireEvent('onCollectionProcessed', new Event(['collection' => $collection, 'context' => $context])); + } + + if ($context['pagination']) { + // Slice and dice the collection if pagination is required + $params = $collection->params(); + + $limit = (int)($params['limit'] ?? 0); + $page = (int)($params['page'] ?? $context['current_page'] ?? 0); + $start = (int)($params['start'] ?? 0); + $start = $limit > 0 && $page > 0 ? ($page - 1) * $limit : max(0, $start); + + if ($start || ($limit && $collection->count() > $limit)) { + $collection->slice($start, $limit ?: null); + } + } + + return $collection; + } + + /** + * @param array|string $value + * @param PageInterface|null $self + * @return Collection + */ + protected function evaluate($value, PageInterface $self = null) + { + // Parse command. + if (is_string($value)) { + // Format: @command.param + $cmd = $value; + $params = []; + } elseif (is_array($value) && count($value) === 1 && !is_int(key($value))) { + // Format: @command.param: { attr1: value1, attr2: value2 } + $cmd = (string)key($value); + $params = (array)current($value); + } else { + $result = []; + foreach ((array)$value as $key => $val) { + if (is_int($key)) { + $result = $result + $this->evaluate($val, $self)->toArray(); + } else { + $result = $result + $this->evaluate([$key => $val], $self)->toArray(); + } + } + + return new Collection($result); + } + + $parts = explode('.', $cmd); + $scope = array_shift($parts); + $type = $parts[0] ?? null; + + /** @var PageInterface|null $page */ + $page = null; + switch ($scope) { + case 'self@': + case '@self': + $page = $self; + break; + + case 'page@': + case '@page': + $page = isset($params[0]) ? $this->find($params[0]) : null; + break; + + case 'root@': + case '@root': + $page = $this->root(); + break; + + case 'taxonomy@': + case '@taxonomy': + // Gets a collection of pages by using one of the following formats: + // @taxonomy.category: blog + // @taxonomy.category: [ blog, featured ] + // @taxonomy: { category: [ blog, featured ], level: 1 } + + /** @var Taxonomy $taxonomy_map */ + $taxonomy_map = Grav::instance()['taxonomy']; + + if (!empty($parts)) { + $params = [implode('.', $parts) => $params]; + } + + return $taxonomy_map->findTaxonomy($params); + } + + if (!$page) { + return new Collection(); + } + + // Handle '@page', '@page.modular: false', '@self' and '@self.modular: false'. + if (null === $type || (in_array($type, ['modular', 'modules']) && ($params[0] ?? null) === false)) { + $type = 'children'; + } + + switch ($type) { + case 'all': + $collection = $page->children(); + break; + case 'modules': + case 'modular': + $collection = $page->children()->modules(); + break; + case 'pages': + case 'children': + $collection = $page->children()->pages(); + break; + case 'page': + case 'self': + $collection = !$page->root() ? (new Collection())->addPage($page) : new Collection(); + break; + case 'parent': + $parent = $page->parent(); + $collection = new Collection(); + $collection = $parent ? $collection->addPage($parent) : $collection; + break; + case 'siblings': + $parent = $page->parent(); + if ($parent) { + /** @var Collection $collection */ + $collection = $parent->children(); + $collection = $collection->remove($page->path()); + } else { + $collection = new Collection(); + } + break; + case 'descendants': + $collection = $this->all($page)->remove($page->path())->pages(); + break; + default: + // Unknown type; return empty collection. + $collection = new Collection(); + break; + } + + return $collection; + } + + /** + * Sort sub-pages in a page. + * + * @param PageInterface $page + * @param string|null $order_by + * @param string|null $order_dir + * @return array + */ + public function sort(PageInterface $page, $order_by = null, $order_dir = null, $sort_flags = null) + { + if ($order_by === null) { + $order_by = $page->orderBy(); + } + if ($order_dir === null) { + $order_dir = $page->orderDir(); + } + + $path = $page->path(); + if (null === $path) { + return []; + } + + $children = $this->children[$path] ?? []; + + if (!$children) { + return $children; + } + + if (!isset($this->sort[$path][$order_by])) { + $this->buildSort($path, $children, $order_by, $page->orderManual(), $sort_flags); + } + + $sort = $this->sort[$path][$order_by]; + + if ($order_dir !== 'asc') { + $sort = array_reverse($sort); + } + + return $sort; + } + + /** + * @param Collection $collection + * @param string $orderBy + * @param string $orderDir + * @param array|null $orderManual + * @param int|null $sort_flags + * @return array + * @internal + */ + public function sortCollection(Collection $collection, $orderBy, $orderDir = 'asc', $orderManual = null, $sort_flags = null) + { + $items = $collection->toArray(); + if (!$items) { + return []; + } + + $lookup = md5(json_encode($items) . json_encode($orderManual) . $orderBy . $orderDir); + if (!isset($this->sort[$lookup][$orderBy])) { + $this->buildSort($lookup, $items, $orderBy, $orderManual, $sort_flags); + } + + $sort = $this->sort[$lookup][$orderBy]; + + if ($orderDir !== 'asc') { + $sort = array_reverse($sort); + } + + return $sort; + } + + /** + * Get a page instance. + * + * @param string $path The filesystem full path of the page + * @return PageInterface|null + * @throws RuntimeException + */ + public function get($path) + { + $path = (string)$path; + if ($path === '') { + return null; + } + + // Check for local instances first. + if (array_key_exists($path, $this->instances)) { + return $this->instances[$path]; + } + + $instance = $this->index[$path] ?? null; + if (is_string($instance)) { + if ($this->directory) { + /** @var Language $language */ + $language = $this->grav['language']; + $lang = $language->getActive(); + if ($lang) { + $languages = $language->getFallbackLanguages($lang, true); + $key = $instance; + $instance = null; + foreach ($languages as $code) { + $test = $code ? $key . ':' . $code : $key; + if (($instance = $this->directory->getObject($test, 'flex_key')) !== null) { + break; + } + } + } else { + $instance = $this->directory->getObject($instance, 'flex_key'); + } + } + + if ($instance instanceof PageInterface) { + if ($this->fire_events && method_exists($instance, 'initialize')) { + $instance->initialize(); + } + } else { + /** @var Debugger $debugger */ + $debugger = $this->grav['debugger']; + $debugger->addMessage(sprintf('Flex page %s is missing or broken!', $instance), 'debug'); + } + } + + if ($instance) { + $this->instances[$path] = $instance; + } + + return $instance; + } + + /** + * Get children of the path. + * + * @param string $path + * @return Collection + */ + public function children($path) + { + $children = $this->children[(string)$path] ?? []; + + return new Collection($children, [], $this); + } + + /** + * Get a page ancestor. + * + * @param string $route The relative URL of the page + * @param string|null $path The relative path of the ancestor folder + * @return PageInterface|null + */ + public function ancestor($route, $path = null) + { + if ($path !== null) { + $page = $this->find($route, true); + + if ($page && $page->path() === $path) { + return $page; + } + + $parent = $page ? $page->parent() : null; + if ($parent && !$parent->root()) { + return $this->ancestor($parent->route(), $path); + } + } + + return null; + } + + /** + * Get a page ancestor trait. + * + * @param string $route The relative route of the page + * @param string|null $field The field name of the ancestor to query for + * @return PageInterface|null + */ + public function inherited($route, $field = null) + { + if ($field !== null) { + $page = $this->find($route, true); + + $parent = $page ? $page->parent() : null; + if ($parent && $parent->value('header.' . $field) !== null) { + return $parent; + } + if ($parent && !$parent->root()) { + return $this->inherited($parent->route(), $field); + } + } + + return null; + } + + /** + * Find a page based on route. + * + * @param string $route The route of the page + * @param bool $all If true, return also non-routable pages, otherwise return null if page isn't routable + * @return PageInterface|null + */ + public function find($route, $all = false) + { + $route = urldecode((string)$route); + + // Fetch page if there's a defined route to it. + $path = $this->routes[$route] ?? null; + $page = null !== $path ? $this->get($path) : null; + + // Try without trailing slash + if (null === $page && Utils::endsWith($route, '/')) { + $path = $this->routes[rtrim($route, '/')] ?? null; + $page = null !== $path ? $this->get($path) : null; + } + + if (!$all && !isset($this->grav['admin'])) { + if (null === $page || !$page->routable()) { + // If the page cannot be accessed, look for the site wide routes and wildcards. + $page = $this->findSiteBasedRoute($route) ?? $page; + } + } + + return $page; + } + + /** + * Check site based routes. + * + * @param string $route + * @return PageInterface|null + */ + protected function findSiteBasedRoute($route) + { + /** @var Config $config */ + $config = $this->grav['config']; + + $site_routes = $config->get('site.routes'); + if (!is_array($site_routes)) { + return null; + } + + $page = null; + + // See if route matches one in the site configuration + $site_route = $site_routes[$route] ?? null; + if ($site_route) { + $page = $this->find($site_route); + } else { + // Use reverse order because of B/C (previously matched multiple and returned the last match). + foreach (array_reverse($site_routes, true) as $pattern => $replace) { + $pattern = '#^' . str_replace('/', '\/', ltrim($pattern, '^')) . '#'; + try { + $found = preg_replace($pattern, $replace, $route); + if ($found && $found !== $route) { + $page = $this->find($found); + if ($page) { + return $page; + } + } + } catch (ErrorException $e) { + $this->grav['log']->error('site.routes: ' . $pattern . '-> ' . $e->getMessage()); + } + } + } + + return $page; + } + + /** + * Dispatch URI to a page. + * + * @param string $route The relative URL of the page + * @param bool $all If true, return also non-routable pages, otherwise return null if page isn't routable + * @param bool $redirect If true, allow redirects + * @return PageInterface|null + * @throws Exception + */ + public function dispatch($route, $all = false, $redirect = true) + { + $page = $this->find($route, true); + + // If we want all pages or are in admin, return what we already have. + if ($all || isset($this->grav['admin'])) { + return $page; + } + + if ($page) { + $routable = $page->routable(); + if ($redirect) { + if ($page->redirect()) { + // Follow a redirect page. + $this->grav->redirectLangSafe($page->redirect()); + } + + if (!$routable) { + /** @var Collection $children */ + $children = $page->children()->visible()->routable()->published(); + $child = $children->first(); + if ($child !== null) { + // Redirect to the first visible child as current page isn't routable. + $this->grav->redirectLangSafe($child->route()); + } + } + } + + if ($routable) { + return $page; + } + } + + $route = urldecode((string)$route); + + // The page cannot be reached, look into site wide redirects, routes and wildcards. + $redirectedPage = $this->findSiteBasedRoute($route); + if ($redirectedPage) { + $page = $this->dispatch($redirectedPage->route(), false, $redirect); + } + + /** @var Config $config */ + $config = $this->grav['config']; + + /** @var Uri $uri */ + $uri = $this->grav['uri']; + /** @var \Grav\Framework\Uri\Uri $source_url */ + $source_url = $uri->uri(false); + + // Try Regex style redirects + $site_redirects = $config->get('site.redirects'); + if (is_array($site_redirects)) { + foreach ((array)$site_redirects as $pattern => $replace) { + $pattern = ltrim($pattern, '^'); + $pattern = '#^' . str_replace('/', '\/', $pattern) . '#'; + try { + /** @var string $found */ + $found = preg_replace($pattern, $replace, $source_url); + if ($found && $found !== $source_url) { + $this->grav->redirectLangSafe($found); + } + } catch (ErrorException $e) { + $this->grav['log']->error('site.redirects: ' . $pattern . '-> ' . $e->getMessage()); + } + } + } + + return $page; + } + + /** + * Get root page. + * + * @return PageInterface + * @throws RuntimeException + */ + public function root() + { + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + $path = $locator->findResource('page://'); + $root = is_string($path) ? $this->get(rtrim($path, '/')) : null; + if (null === $root) { + throw new RuntimeException('Internal error'); + } + + return $root; + } + + /** + * Get a blueprint for a page type. + * + * @param string $type + * @return Blueprint + */ + public function blueprints($type) + { + if ($this->blueprints === null) { + $this->blueprints = new Blueprints(self::getTypes()); + } + + try { + $blueprint = $this->blueprints->get($type); + } catch (RuntimeException $e) { + $blueprint = $this->blueprints->get('default'); + } + + if (empty($blueprint->initialized)) { + $blueprint->initialized = true; + $this->grav->fireEvent('onBlueprintCreated', new Event(['blueprint' => $blueprint, 'type' => $type])); + } + + return $blueprint; + } + + /** + * Get all pages + * + * @param PageInterface|null $current + * @return Collection + */ + public function all(PageInterface $current = null) + { + $all = new Collection(); + + /** @var PageInterface $current */ + $current = $current ?: $this->root(); + + if (!$current->root()) { + $all[$current->path()] = ['slug' => $current->slug()]; + } + + foreach ($current->children() as $next) { + $all->append($this->all($next)); + } + + return $all; + } + + /** + * Get available parents raw routes. + * + * @return array + */ + public static function parentsRawRoutes() + { + $rawRoutes = true; + + return self::getParents($rawRoutes); + } + + /** + * Get available parents routes + * + * @param bool $rawRoutes get the raw route or the normal route + * @return array + */ + private static function getParents($rawRoutes) + { + $grav = Grav::instance(); + + /** @var Pages $pages */ + $pages = $grav['pages']; + + $parents = $pages->getList(null, 0, $rawRoutes); + + if (isset($grav['admin'])) { + // Remove current route from parents + + /** @var Admin $admin */ + $admin = $grav['admin']; + + $page = $admin->getPage($admin->route); + $page_route = $page->route(); + if (isset($parents[$page_route])) { + unset($parents[$page_route]); + } + } + + return $parents; + } + + /** + * Get list of route/title of all pages. Title is in HTML. + * + * @param PageInterface|null $current + * @param int $level + * @param bool $rawRoutes + * @param bool $showAll + * @param bool $showFullpath + * @param bool $showSlug + * @param bool $showModular + * @param bool $limitLevels + * @return array + */ + public function getList(PageInterface $current = null, $level = 0, $rawRoutes = false, $showAll = true, $showFullpath = false, $showSlug = false, $showModular = false, $limitLevels = false) + { + if (!$current) { + if ($level) { + throw new RuntimeException('Internal error'); + } + + $current = $this->root(); + } + + $list = []; + + if (!$current->root()) { + if ($rawRoutes) { + $route = $current->rawRoute(); + } else { + $route = $current->route(); + } + + if ($showFullpath) { + $option = htmlspecialchars($current->route()); + } else { + $extra = $showSlug ? '(' . $current->slug() . ') ' : ''; + $option = str_repeat('—-', $level). '▸ ' . $extra . htmlspecialchars($current->title()); + } + + $list[$route] = $option; + } + + if ($limitLevels === false || ($level+1 < $limitLevels)) { + foreach ($current->children() as $next) { + if ($showAll || $next->routable() || ($next->isModule() && $showModular)) { + $list = array_merge($list, $this->getList($next, $level + 1, $rawRoutes, $showAll, $showFullpath, $showSlug, $showModular, $limitLevels)); + } + } + } + + return $list; + } + + /** + * Get available page types. + * + * @return Types + */ + public static function getTypes() + { + if (null === self::$types) { + $grav = Grav::instance(); + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + + // Prevent calls made before theme:// has been initialized (happens when upgrading old version of Admin plugin). + if (!$locator->isStream('theme://')) { + return new Types(); + } + + $scanBlueprintsAndTemplates = static function (Types $types) use ($grav) { + // Scan blueprints + $event = new TypesEvent(); + $event->types = $types; + $grav->fireEvent('onGetPageBlueprints', $event); + + $types->init(); + + // Try new location first. + $lookup = 'theme://blueprints/pages/'; + if (!is_dir($lookup)) { + $lookup = 'theme://blueprints/'; + } + $types->scanBlueprints($lookup); + + // Scan templates + $event = new TypesEvent(); + $event->types = $types; + $grav->fireEvent('onGetPageTemplates', $event); + + $types->scanTemplates('theme://templates/'); + }; + + if ($grav['config']->get('system.cache.enabled')) { + /** @var Cache $cache */ + $cache = $grav['cache']; + + // Use cached types if possible. + $types_cache_id = md5('types'); + $types = $cache->fetch($types_cache_id); + + if (!$types instanceof Types) { + $types = new Types(); + $scanBlueprintsAndTemplates($types); + $cache->save($types_cache_id, $types); + } + } else { + $types = new Types(); + $scanBlueprintsAndTemplates($types); + } + + // Register custom paths to the locator. + $locator = $grav['locator']; + foreach ($types as $type => $paths) { + foreach ($paths as $k => $path) { + if (strpos($path, 'blueprints://') === 0) { + unset($paths[$k]); + } + } + if ($paths) { + $locator->addPath('blueprints', "pages/$type.yaml", $paths); + } + } + + self::$types = $types; + } + + return self::$types; + } + + /** + * Get available page types. + * + * @return array + */ + public static function types() + { + $types = self::getTypes(); + + return $types->pageSelect(); + } + + /** + * Get available page types. + * + * @return array + */ + public static function modularTypes() + { + $types = self::getTypes(); + + return $types->modularSelect(); + } + + /** + * Get template types based on page type (standard or modular) + * + * @param string|null $type + * @return array + */ + public static function pageTypes($type = null) + { + if (null === $type && isset(Grav::instance()['admin'])) { + /** @var Admin $admin */ + $admin = Grav::instance()['admin']; + + /** @var PageInterface|null $page */ + $page = $admin->page(); + + $type = $page && $page->isModule() ? 'modular' : 'standard'; + } + + switch ($type) { + case 'standard': + return static::types(); + case 'modular': + return static::modularTypes(); + } + + return []; + } + + /** + * Get access levels of the site pages + * + * @return array + */ + public function accessLevels() + { + $accessLevels = []; + foreach ($this->all() as $page) { + if ($page instanceof PageInterface && isset($page->header()->access)) { + if (is_array($page->header()->access)) { + foreach ($page->header()->access as $index => $accessLevel) { + if (is_array($accessLevel)) { + foreach ($accessLevel as $innerIndex => $innerAccessLevel) { + $accessLevels[] = $innerIndex; + } + } else { + $accessLevels[] = $index; + } + } + } else { + $accessLevels[] = $page->header()->access; + } + } + } + + return array_unique($accessLevels); + } + + /** + * Get available parents routes + * + * @return array + */ + public static function parents() + { + $rawRoutes = false; + + return self::getParents($rawRoutes); + } + + /** + * Gets the home route + * + * @return string + */ + public static function getHomeRoute() + { + if (empty(self::$home_route)) { + $grav = Grav::instance(); + + /** @var Config $config */ + $config = $grav['config']; + + /** @var Language $language */ + $language = $grav['language']; + + $home = $config->get('system.home.alias'); + + if ($language->enabled()) { + $home_aliases = $config->get('system.home.aliases'); + if ($home_aliases) { + $active = $language->getActive(); + $default = $language->getDefault(); + + try { + if ($active) { + $home = $home_aliases[$active]; + } else { + $home = $home_aliases[$default]; + } + } catch (ErrorException $e) { + $home = $home_aliases[$default]; + } + } + } + + self::$home_route = trim($home, '/'); + } + + return self::$home_route; + } + + /** + * Needed for testing where we change the home route via config + * + * @return string|null + */ + public static function resetHomeRoute() + { + self::$home_route = null; + + return self::getHomeRoute(); + } + + protected function initFlexPages(): void + { + /** @var Debugger $debugger */ + $debugger = $this->grav['debugger']; + $debugger->addMessage('Pages: Flex Directory'); + + /** @var Flex $flex */ + $flex = $this->grav['flex']; + $directory = $flex->getDirectory('pages'); + + /** @var EventDispatcher $dispatcher */ + $dispatcher = $this->grav['events']; + + // Stop /admin/pages from working, display error instead. + $dispatcher->addListener( + 'onAdminPage', + static function (Event $event) use ($directory) { + $grav = Grav::instance(); + $admin = $grav['admin']; + [$base,$location,] = $admin->getRouteDetails(); + if ($location !== 'pages' || isset($grav['flex_objects'])) { + return; + } + + /** @var PageInterface $page */ + $page = $event['page']; + $page->init(new SplFileInfo('plugin://admin/pages/admin/error.md')); + $page->routable(true); + $header = $page->header(); + $header->title = 'Please install missing plugin'; + $page->content("## Please install and enable **[Flex Objects]({$base}/plugins/flex-objects)** plugin. It is required to edit **Flex Pages**."); + + /** @var Header $header */ + $header = $page->header(); + $menu = $directory->getConfig('admin.menu.list'); + $header->access = $menu['authorize'] ?? ['admin.super']; + }, + 100000 + ); + + $this->directory = $directory; + } + + /** + * Builds pages. + * + * @internal + */ + protected function buildPages(): void + { + /** @var Debugger $debugger */ + $debugger = $this->grav['debugger']; + $debugger->startTimer('build-pages', 'Init frontend routes'); + + if ($this->directory) { + $this->buildFlexPages($this->directory); + } else { + $this->buildRegularPages(); + } + $debugger->stopTimer('build-pages'); + } + + protected function buildFlexPages(FlexDirectory $directory): void + { + /** @var Config $config */ + $config = $this->grav['config']; + + // TODO: right now we are just emulating normal pages, it is inefficient and bad... but works! + /** @var PageCollection|PageIndex $collection */ + $collection = $directory->getIndex(null, 'storage_key'); + $cache = $directory->getCache('index'); + + /** @var Language $language */ + $language = $this->grav['language']; + + $this->pages_cache_id = 'pages-' . md5($collection->getCacheChecksum() . $language->getActive() . $config->checksum()); + + $cached = $cache->get($this->pages_cache_id); + + if ($cached && $this->getVersion() === $cached[0]) { + [, $this->index, $this->routes, $this->children, $taxonomy_map, $this->sort] = $cached; + + /** @var Taxonomy $taxonomy */ + $taxonomy = $this->grav['taxonomy']; + $taxonomy->taxonomy($taxonomy_map); + + return; + } + + /** @var Debugger $debugger */ + $debugger = $this->grav['debugger']; + $debugger->addMessage('Page cache missed, rebuilding Flex Pages..'); + + $root = $collection->getRoot(); + $root_path = $root->path(); + $this->routes = []; + $this->instances = [$root_path => $root]; + $this->index = [$root_path => $root]; + $this->children = []; + $this->sort = []; + + if ($this->fire_events) { + $this->grav->fireEvent('onBuildPagesInitialized'); + } + + /** @var PageInterface $page */ + foreach ($collection as $page) { + $path = $page->path(); + if (null === $path) { + throw new RuntimeException('Internal error'); + } + + if ($page instanceof FlexTranslateInterface) { + $page = $page->hasTranslation() ? $page->getTranslation() : null; + } + + if (!$page instanceof FlexPageObject || $path === $root_path) { + continue; + } + + if ($this->fire_events) { + if (method_exists($page, 'initialize')) { + $page->initialize(); + } else { + // TODO: Deprecated, only used in 1.7 betas. + $this->grav->fireEvent('onPageProcessed', new Event(['page' => $page])); + } + } + + $parent = dirname($path); + + $route = $page->rawRoute(); + + // Skip duplicated empty folders (git revert does not remove those). + // TODO: still not perfect, will only work if the page has been translated. + if (isset($this->routes[$route])) { + $oldPath = $this->routes[$route]; + if ($page->isPage()) { + unset($this->index[$oldPath], $this->children[dirname($oldPath)][$oldPath]); + } else { + continue; + } + } + + $this->routes[$route] = $path; + $this->instances[$path] = $page; + $this->index[$path] = $page->getFlexKey(); + // FIXME: ... better... + $this->children[$parent][$path] = ['slug' => $page->slug()]; + if (!isset($this->children[$path])) { + $this->children[$path] = []; + } + } + + foreach ($this->children as $path => $list) { + $page = $this->instances[$path] ?? null; + if (null === $page) { + continue; + } + // Call onFolderProcessed event. + if ($this->fire_events) { + $this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page])); + } + // Sort the children. + $this->children[$path] = $this->sort($page); + } + + $this->routes = []; + $this->buildRoutes(); + + // cache if needed + if (null !== $cache) { + /** @var Taxonomy $taxonomy */ + $taxonomy = $this->grav['taxonomy']; + $taxonomy_map = $taxonomy->taxonomy(); + + // save pages, routes, taxonomy, and sort to cache + $cache->set($this->pages_cache_id, [$this->getVersion(), $this->index, $this->routes, $this->children, $taxonomy_map, $this->sort]); + } + } + + /** + * @return Page + */ + protected function buildRootPage() + { + $grav = Grav::instance(); + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + $path = $locator->findResource('page://'); + if (!is_string($path)) { + throw new RuntimeException('Internal Error'); + } + + /** @var Config $config */ + $config = $grav['config']; + + $page = new Page(); + $page->path($path); + $page->orderDir($config->get('system.pages.order.dir')); + $page->orderBy($config->get('system.pages.order.by')); + $page->modified(0); + $page->routable(false); + $page->template('default'); + $page->extension('.md'); + + return $page; + } + + protected function buildRegularPages(): void + { + /** @var Config $config */ + $config = $this->grav['config']; + + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + /** @var Language $language */ + $language = $this->grav['language']; + + $pages_dirs = $this->getPagesPaths(); + + // Set active language + $this->active_lang = $language->getActive(); + + if ($config->get('system.cache.enabled')) { + /** @var Language $language */ + $language = $this->grav['language']; + + // how should we check for last modified? Default is by file + switch ($this->check_method) { + case 'none': + case 'off': + $hash = 0; + break; + case 'folder': + $hash = Folder::lastModifiedFolder($pages_dirs); + break; + case 'hash': + $hash = Folder::hashAllFiles($pages_dirs); + break; + default: + $hash = Folder::lastModifiedFile($pages_dirs); + } + + $this->simple_pages_hash = json_encode($pages_dirs) . $hash . $config->checksum(); + $this->pages_cache_id = md5($this->simple_pages_hash . $language->getActive()); + + /** @var Cache $cache */ + $cache = $this->grav['cache']; + $cached = $cache->fetch($this->pages_cache_id); + if ($cached && $this->getVersion() === $cached[0]) { + [, $this->index, $this->routes, $this->children, $taxonomy_map, $this->sort] = $cached; + + /** @var Taxonomy $taxonomy */ + $taxonomy = $this->grav['taxonomy']; + $taxonomy->taxonomy($taxonomy_map); + + return; + } + + $this->grav['debugger']->addMessage('Page cache missed, rebuilding pages..'); + } else { + $this->grav['debugger']->addMessage('Page cache disabled, rebuilding pages..'); + } + + $this->resetPages($pages_dirs); + } + + protected function getPagesPaths(): array + { + $grav = Grav::instance(); + $locator = $grav['locator']; + $paths = []; + + $dirs = (array) $grav['config']->get('system.pages.dirs', ['page://']); + foreach ($dirs as $dir) { + $path = $locator->findResource($dir); + if (file_exists($path) && !in_array($path, $paths, true)) { + $paths[] = $path; + } + } + + return $paths; + } + + /** + * Accessible method to manually reset the pages cache + * + * @param array $pages_dirs + */ + public function resetPages(array $pages_dirs): void + { + $this->sort = []; + + foreach ($pages_dirs as $dir) { + $this->recurse($dir); + } + + $this->buildRoutes(); + + // cache if needed + if ($this->grav['config']->get('system.cache.enabled')) { + /** @var Cache $cache */ + $cache = $this->grav['cache']; + /** @var Taxonomy $taxonomy */ + $taxonomy = $this->grav['taxonomy']; + + // save pages, routes, taxonomy, and sort to cache + $cache->save($this->pages_cache_id, [$this->getVersion(), $this->index, $this->routes, $this->children, $taxonomy->taxonomy(), $this->sort]); + } + } + + /** + * Recursive function to load & build page relationships. + * + * @param string $directory + * @param PageInterface|null $parent + * @return PageInterface + * @throws RuntimeException + * @internal + */ + protected function recurse(string $directory, PageInterface $parent = null) + { + $directory = rtrim($directory, DS); + $page = new Page; + + /** @var Config $config */ + $config = $this->grav['config']; + + /** @var Language $language */ + $language = $this->grav['language']; + + // Stuff to do at root page + // Fire event for memory and time consuming plugins... + if ($parent === null && $this->fire_events) { + $this->grav->fireEvent('onBuildPagesInitialized'); + } + + $page->path($directory); + if ($parent) { + $page->parent($parent); + } + + $page->orderDir($config->get('system.pages.order.dir')); + $page->orderBy($config->get('system.pages.order.by')); + + // Add into instances + if (!isset($this->index[$page->path()])) { + $this->index[$page->path()] = $page; + $this->instances[$page->path()] = $page; + if ($parent && $page->path()) { + $this->children[$parent->path()][$page->path()] = ['slug' => $page->slug()]; + } + } elseif ($parent !== null) { + throw new RuntimeException('Fatal error when creating page instances.'); + } + + // Build regular expression for all the allowed page extensions. + $page_extensions = $language->getFallbackPageExtensions(); + $regex = '/^[^\.]*(' . implode('|', array_map( + static function ($str) { + return preg_quote($str, '/'); + }, + $page_extensions + )) . ')$/'; + + $folders = []; + $page_found = null; + $page_extension = '.md'; + $last_modified = 0; + + $iterator = new FilesystemIterator($directory); + foreach ($iterator as $file) { + $filename = $file->getFilename(); + + // Ignore all hidden files if set. + if ($this->ignore_hidden && $filename && strpos($filename, '.') === 0) { + continue; + } + + // Handle folders later. + if ($file->isDir()) { + // But ignore all folders in ignore list. + if (!in_array($filename, $this->ignore_folders, true)) { + $folders[] = $file; + } + continue; + } + + // Ignore all files in ignore list. + if (in_array($filename, $this->ignore_files, true)) { + continue; + } + + // Update last modified date to match the last updated file in the folder. + $modified = $file->getMTime(); + if ($modified > $last_modified) { + $last_modified = $modified; + } + + // Page is the one that matches to $page_extensions list with the lowest index number. + if (preg_match($regex, $filename, $matches, PREG_OFFSET_CAPTURE)) { + $ext = $matches[1][0]; + + if ($page_found === null || array_search($ext, $page_extensions, true) < array_search($page_extension, $page_extensions, true)) { + $page_found = $file; + $page_extension = $ext; + } + } + } + + $content_exists = false; + if ($parent && $page_found) { + $page->init($page_found, $page_extension); + + $content_exists = true; + + if ($this->fire_events) { + $this->grav->fireEvent('onPageProcessed', new Event(['page' => $page])); + } + } + + // Now handle all the folders under the page. + /** @var FilesystemIterator $file */ + foreach ($folders as $file) { + $filename = $file->getFilename(); + + // if folder contains separator, continue + if (Utils::contains($file->getFilename(), $config->get('system.param_sep', ':'))) { + continue; + } + + if (!$page->path()) { + $page->path($file->getPath()); + } + + $path = $directory . DS . $filename; + $child = $this->recurse($path, $page); + + if (preg_match('/^(\d+\.)_/', $filename)) { + $child->routable(false); + $child->modularTwig(true); + } + + $this->children[$page->path()][$child->path()] = ['slug' => $child->slug()]; + + if ($this->fire_events) { + $this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page])); + } + } + + if (!$content_exists) { + // Set routable to false if no page found + $page->routable(false); + + // Hide empty folders if option set + if ($config->get('system.pages.hide_empty_folders')) { + $page->visible(false); + } + } + + // Override the modified time if modular + if ($page->template() === 'modular') { + foreach ($page->collection() as $child) { + $modified = $child->modified(); + + if ($modified > $last_modified) { + $last_modified = $modified; + } + } + } + + // Override the modified and ID so that it takes the latest change into account + $page->modified($last_modified); + $page->id($last_modified . md5($page->filePath() ?? '')); + + // Sort based on Defaults or Page Overridden sort order + $this->children[$page->path()] = $this->sort($page); + + return $page; + } + + /** + * @internal + */ + protected function buildRoutes(): void + { + /** @var Taxonomy $taxonomy */ + $taxonomy = $this->grav['taxonomy']; + + // Get the home route + $home = self::resetHomeRoute(); + // Build routes and taxonomy map. + /** @var PageInterface|string $page */ + foreach ($this->index as $path => $page) { + if (is_string($page)) { + $page = $this->get($path); + } + + if (!$page || $page->root()) { + continue; + } + + // process taxonomy + $taxonomy->addTaxonomy($page); + + $page_path = $page->path(); + if (null === $page_path) { + throw new RuntimeException('Internal Error'); + } + + $route = $page->route(); + $raw_route = $page->rawRoute(); + + // add regular route + if ($route) { + if (isset($this->routes[$route]) && $this->routes[$route] !== $page_path) { + $this->grav['debugger']->addMessage("Route '{$route}' already exists: {$this->routes[$route]}, overwriting with {$page_path}"); + } + $this->routes[$route] = $page_path; + } + + // add raw route + if ($raw_route) { + if (isset($this->routes[$raw_route]) && $this->routes[$route] !== $page_path) { + $this->grav['debugger']->addMessage("Raw Route '{$raw_route}' already exists: {$this->routes[$raw_route]}, overwriting with {$page_path}"); + } + $this->routes[$raw_route] = $page_path; + } + + // add canonical route + $route_canonical = $page->routeCanonical(); + if ($route_canonical) { + if (isset($this->routes[$route_canonical]) && $this->routes[$route_canonical] !== $page_path) { + $this->grav['debugger']->addMessage("Canonical Route '{$route_canonical}' already exists: {$this->routes[$route_canonical]}, overwriting with {$page_path}"); + } + $this->routes[$route_canonical] = $page_path; + } + + // add aliases to routes list if they are provided + $route_aliases = $page->routeAliases(); + if ($route_aliases) { + foreach ($route_aliases as $alias) { + if (isset($this->routes[$alias]) && $this->routes[$alias] !== $page_path) { + $this->grav['debugger']->addMessage("Alias Route '{$alias}' already exists: {$this->routes[$alias]}, overwriting with {$page_path}"); + } + $this->routes[$alias] = $page_path; + } + } + } + + // Alias and set default route to home page. + $homeRoute = "/{$home}"; + if ($home && isset($this->routes[$homeRoute])) { + $home = $this->get($this->routes[$homeRoute]); + if ($home) { + $this->routes['/'] = $this->routes[$homeRoute]; + $home->route('/'); + } + } + } + + /** + * @param string $path + * @param array $pages + * @param string $order_by + * @param array|null $manual + * @param int|null $sort_flags + * @throws RuntimeException + * @internal + */ + protected function buildSort($path, array $pages, $order_by = 'default', $manual = null, $sort_flags = null): void + { + $list = []; + $header_query = null; + $header_default = null; + + // do this header query work only once + if (strpos($order_by, 'header.') === 0) { + $query = explode('|', str_replace('header.', '', $order_by), 2); + $header_query = array_shift($query) ?? ''; + $header_default = array_shift($query); + } + + foreach ($pages as $key => $info) { + $child = $this->get($key); + if (!$child) { + throw new RuntimeException("Page does not exist: {$key}"); + } + + switch ($order_by) { + case 'title': + $list[$key] = $child->title(); + break; + case 'date': + $list[$key] = $child->date(); + $sort_flags = SORT_REGULAR; + break; + case 'modified': + $list[$key] = $child->modified(); + $sort_flags = SORT_REGULAR; + break; + case 'publish_date': + $list[$key] = $child->publishDate(); + $sort_flags = SORT_REGULAR; + break; + case 'unpublish_date': + $list[$key] = $child->unpublishDate(); + $sort_flags = SORT_REGULAR; + break; + case 'slug': + $list[$key] = $child->slug(); + break; + case 'basename': + $list[$key] = Utils::basename($key); + break; + case 'folder': + $list[$key] = $child->folder(); + break; + case 'manual': + case 'default': + default: + if (is_string($header_query)) { + $child_header = $child->header(); + if (!$child_header instanceof Header) { + $child_header = new Header((array)$child_header); + } + $header_value = $child_header->get($header_query); + if (is_array($header_value)) { + $list[$key] = implode(',', $header_value); + } elseif ($header_value) { + $list[$key] = $header_value; + } else { + $list[$key] = $header_default ?: $key; + } + $sort_flags = $sort_flags ?: SORT_REGULAR; + break; + } + $list[$key] = $key; + $sort_flags = $sort_flags ?: SORT_REGULAR; + } + } + + if (!$sort_flags) { + $sort_flags = SORT_NATURAL | SORT_FLAG_CASE; + } + + // handle special case when order_by is random + if ($order_by === 'random') { + $list = $this->arrayShuffle($list); + } else { + // else just sort the list according to specified key + if (extension_loaded('intl') && $this->grav['config']->get('system.intl_enabled')) { + $locale = setlocale(LC_COLLATE, '0'); //`setlocale` with a '0' param returns the current locale set + $col = Collator::create($locale); + if ($col) { + $col->setAttribute(Collator::NUMERIC_COLLATION, Collator::ON); + if (($sort_flags & SORT_NATURAL) === SORT_NATURAL) { + $list = preg_replace_callback('~([0-9]+)\.~', static function ($number) { + return sprintf('%032d.', $number[0]); + }, $list); + if (!is_array($list)) { + throw new RuntimeException('Internal Error'); + } + + $list_vals = array_values($list); + if (is_numeric(array_shift($list_vals))) { + $sort_flags = Collator::SORT_REGULAR; + } else { + $sort_flags = Collator::SORT_STRING; + } + } + + $col->asort($list, $sort_flags); + } else { + asort($list, $sort_flags); + } + } else { + asort($list, $sort_flags); + } + } + + + // Move manually ordered items into the beginning of the list. Order of the unlisted items does not change. + if (is_array($manual) && !empty($manual)) { + $new_list = []; + $i = count($manual); + + foreach ($list as $key => $dummy) { + $info = $pages[$key]; + $order = array_search($info['slug'], $manual, true); + if ($order === false) { + $order = $i++; + } + $new_list[$key] = (int)$order; + } + + $list = $new_list; + + // Apply manual ordering to the list. + asort($list, SORT_NUMERIC); + } + + foreach ($list as $key => $sort) { + $info = $pages[$key]; + $this->sort[$path][$order_by][$key] = $info; + } + } + + /** + * Shuffles an associative array + * + * @param array $list + * @return array + */ + protected function arrayShuffle(array $list): array + { + $keys = array_keys($list); + shuffle($keys); + + $new = []; + foreach ($keys as $key) { + $new[$key] = $list[$key]; + } + + return $new; + } + + /** + * @return string + */ + protected function getVersion(): string + { + return $this->directory ? 'flex' : 'regular'; + } + + /** + * Get the Pages cache ID + * + * this is particularly useful to know if pages have changed and you want + * to sync another cache with pages cache - works best in `onPagesInitialized()` + * + * @return null|string + */ + public function getPagesCacheId(): ?string + { + return $this->pages_cache_id; + } + + /** + * Get the simple pages hash that is not md5 encoded, and isn't specific to language + * + * @return null|string + */ + public function getSimplePagesHash(): ?string + { + return $this->simple_pages_hash; + } +} diff --git a/system/src/Grav/Common/Page/Traits/PageFormTrait.php b/system/src/Grav/Common/Page/Traits/PageFormTrait.php new file mode 100644 index 0000000..b99e7b7 --- /dev/null +++ b/system/src/Grav/Common/Page/Traits/PageFormTrait.php @@ -0,0 +1,126 @@ + blueprint, ...], where blueprint follows the regular form blueprint format. + * + * @return array + */ + public function getForms(): array + { + if (null === $this->_forms) { + $header = $this->header(); + + // Call event to allow filling the page header form dynamically (e.g. use case: Comments plugin) + $grav = Grav::instance(); + $grav->fireEvent('onFormPageHeaderProcessed', new Event(['page' => $this, 'header' => $header])); + + $rules = $header->rules ?? null; + if (!is_array($rules)) { + $rules = []; + } + + $forms = []; + + // First grab page.header.form + $form = $this->normalizeForm($header->form ?? null, null, $rules); + if ($form) { + $forms[$form['name']] = $form; + } + + // Append page.header.forms (override singular form if it clashes) + $headerForms = $header->forms ?? null; + if (is_array($headerForms)) { + foreach ($headerForms as $name => $form) { + $form = $this->normalizeForm($form, $name, $rules); + if ($form) { + $forms[$form['name']] = $form; + } + } + } + + $this->_forms = $forms; + } + + return $this->_forms; + } + + /** + * Add forms to this page. + * + * @param array $new + * @param bool $override + * @return $this + */ + public function addForms(array $new, $override = true) + { + // Initialize forms. + $this->forms(); + + foreach ($new as $name => $form) { + $form = $this->normalizeForm($form, $name); + $name = $form['name'] ?? null; + if ($name && ($override || !isset($this->_forms[$name]))) { + $this->_forms[$name] = $form; + } + } + + return $this; + } + + /** + * Alias of $this->getForms(); + * + * @return array + */ + public function forms(): array + { + return $this->getForms(); + } + + /** + * @param array|null $form + * @param string|null $name + * @param array $rules + * @return array|null + */ + protected function normalizeForm($form, $name = null, array $rules = []): ?array + { + if (!is_array($form)) { + return null; + } + + // Ignore numeric indexes on name. + if (!$name || (string)(int)$name === (string)$name) { + $name = null; + } + + $name = $name ?? $form['name'] ?? $this->slug(); + + $formRules = $form['rules'] ?? null; + if (!is_array($formRules)) { + $formRules = []; + } + + return ['name' => $name, 'rules' => $rules + $formRules] + $form; + } + + abstract public function header($var = null); + abstract public function slug($var = null); +} diff --git a/system/src/Grav/Common/Page/Types.php b/system/src/Grav/Common/Page/Types.php new file mode 100644 index 0000000..d9bdc33 --- /dev/null +++ b/system/src/Grav/Common/Page/Types.php @@ -0,0 +1,179 @@ +items[$type])) { + $this->items[$type] = []; + } elseif (null === $blueprint) { + return; + } + + if (null === $blueprint) { + $blueprint = $this->systemBlueprints[$type] ?? $this->systemBlueprints['default'] ?? null; + } + + if ($blueprint) { + array_unshift($this->items[$type], $blueprint); + } + } + + /** + * @return void + */ + public function init() + { + if (empty($this->systemBlueprints)) { + // Register all blueprints from the blueprints stream. + $this->systemBlueprints = $this->findBlueprints('blueprints://pages'); + foreach ($this->systemBlueprints as $type => $blueprint) { + $this->register($type); + } + } + } + + /** + * @param string $uri + * @return void + */ + public function scanBlueprints($uri) + { + if (!is_string($uri)) { + throw new InvalidArgumentException('First parameter must be URI'); + } + + foreach ($this->findBlueprints($uri) as $type => $blueprint) { + $this->register($type, $blueprint); + } + } + + /** + * @param string $uri + * @return void + */ + public function scanTemplates($uri) + { + if (!is_string($uri)) { + throw new InvalidArgumentException('First parameter must be URI'); + } + + $options = [ + 'compare' => 'Filename', + 'pattern' => '|\.html\.twig$|', + 'filters' => [ + 'value' => '|\.html\.twig$|' + ], + 'value' => 'Filename', + 'recursive' => false + ]; + + foreach (Folder::all($uri, $options) as $type) { + $this->register($type); + } + + $modular_uri = rtrim($uri, '/') . '/modular'; + if (is_dir($modular_uri)) { + foreach (Folder::all($modular_uri, $options) as $type) { + $this->register('modular/' . $type); + } + } + } + + /** + * @return array + */ + public function pageSelect() + { + $list = []; + foreach ($this->items as $name => $file) { + if (strpos($name, '/')) { + continue; + } + $list[$name] = ucfirst(str_replace('_', ' ', $name)); + } + ksort($list); + + return $list; + } + + /** + * @return array + */ + public function modularSelect() + { + $list = []; + foreach ($this->items as $name => $file) { + if (strpos($name, 'modular/') !== 0) { + continue; + } + $list[$name] = ucfirst(trim(str_replace('_', ' ', Utils::basename($name)))); + } + ksort($list); + + return $list; + } + + /** + * @param string $uri + * @return array + */ + private function findBlueprints($uri) + { + $options = [ + 'compare' => 'Filename', + 'pattern' => '|\.yaml$|', + 'filters' => [ + 'key' => '|\.yaml$|' + ], + 'key' => 'SubPathName', + 'value' => 'PathName', + ]; + + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + if ($locator->isStream($uri)) { + $options['value'] = 'Url'; + } + + return Folder::all($uri, $options); + } +} diff --git a/system/src/Grav/Common/Plugin.php b/system/src/Grav/Common/Plugin.php new file mode 100644 index 0000000..7b74c8f --- /dev/null +++ b/system/src/Grav/Common/Plugin.php @@ -0,0 +1,472 @@ +name = $name; + $this->grav = $grav; + + if ($config) { + $this->setConfig($config); + } + } + + /** + * @return ClassLoader|null + * @internal + */ + final public function getAutoloader(): ?ClassLoader + { + return $this->loader; + } + + /** + * @param ClassLoader|null $loader + * @internal + */ + final public function setAutoloader(?ClassLoader $loader): void + { + $this->loader = $loader; + } + + /** + * @param Config $config + * @return $this + */ + public function setConfig(Config $config) + { + $this->config = $config; + + return $this; + } + + /** + * Get configuration of the plugin. + * + * @return array + */ + public function config() + { + return $this->config["plugins.{$this->name}"] ?? []; + } + + /** + * Determine if plugin is running under the admin + * + * @return bool + */ + public function isAdmin() + { + return Utils::isAdminPlugin(); + } + + /** + * Determine if plugin is running under the CLI + * + * @return bool + */ + public function isCli() + { + return defined('GRAV_CLI'); + } + + /** + * Determine if this route is in Admin and active for the plugin + * + * @param string $plugin_route + * @return bool + */ + protected function isPluginActiveAdmin($plugin_route) + { + $active = false; + + /** @var Uri $uri */ + $uri = $this->grav['uri']; + /** @var Config $config */ + $config = $this->config ?? $this->grav['config']; + + if (strpos($uri->path(), $config->get('plugins.admin.route') . '/' . $plugin_route) === false) { + $active = false; + } elseif (isset($uri->paths()[1]) && $uri->paths()[1] === $plugin_route) { + $active = true; + } + + return $active; + } + + /** + * @param array $events + * @return void + */ + protected function enable(array $events) + { + /** @var EventDispatcher $dispatcher */ + $dispatcher = $this->grav['events']; + + foreach ($events as $eventName => $params) { + if (is_string($params)) { + $dispatcher->addListener($eventName, [$this, $params]); + } elseif (is_string($params[0])) { + $dispatcher->addListener($eventName, [$this, $params[0]], $this->getPriority($params, $eventName)); + } else { + foreach ($params as $listener) { + $dispatcher->addListener($eventName, [$this, $listener[0]], $this->getPriority($listener, $eventName)); + } + } + } + } + + /** + * @param array $params + * @param string $eventName + * @return int + */ + private function getPriority($params, $eventName) + { + $override = implode('.', ['priorities', $this->name, $eventName, $params[0]]); + + return $this->grav['config']->get($override) ?? $params[1] ?? 0; + } + + /** + * @param array $events + * @return void + */ + protected function disable(array $events) + { + /** @var EventDispatcher $dispatcher */ + $dispatcher = $this->grav['events']; + + foreach ($events as $eventName => $params) { + if (is_string($params)) { + $dispatcher->removeListener($eventName, [$this, $params]); + } elseif (is_string($params[0])) { + $dispatcher->removeListener($eventName, [$this, $params[0]]); + } else { + foreach ($params as $listener) { + $dispatcher->removeListener($eventName, [$this, $listener[0]]); + } + } + } + } + + /** + * Whether or not an offset exists. + * + * @param string $offset An offset to check for. + * @return bool Returns TRUE on success or FALSE on failure. + */ + #[\ReturnTypeWillChange] + public function offsetExists($offset) + { + if ($offset === 'title') { + $offset = 'name'; + } + + $blueprint = $this->getBlueprint(); + + return isset($blueprint[$offset]); + } + + /** + * Returns the value at specified offset. + * + * @param string $offset The offset to retrieve. + * @return mixed Can return all value types. + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + if ($offset === 'title') { + $offset = 'name'; + } + + $blueprint = $this->getBlueprint(); + + return $blueprint[$offset] ?? null; + } + + /** + * Assigns a value to the specified offset. + * + * @param string $offset The offset to assign the value to. + * @param mixed $value The value to set. + * @throws LogicException + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + throw new LogicException(__CLASS__ . ' blueprints cannot be modified.'); + } + + /** + * Unsets an offset. + * + * @param string $offset The offset to unset. + * @throws LogicException + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + throw new LogicException(__CLASS__ . ' blueprints cannot be modified.'); + } + + /** + * @return array + */ + public function __debugInfo(): array + { + $array = (array)$this; + + unset($array["\0*\0grav"]); + $array["\0*\0config"] = $this->config(); + + return $array; + } + + /** + * This function will search a string for markdown links in a specific format. The link value can be + * optionally compared against via the $internal_regex and operated on by the callback $function + * provided. + * + * format: [plugin:myplugin_name](function_data) + * + * @param string $content The string to perform operations upon + * @param callable $function The anonymous callback function + * @param string $internal_regex Optional internal regex to extra data from + * @return string + */ + protected function parseLinks($content, $function, $internal_regex = '(.*)') + { + $regex = '/\[plugin:(?:' . preg_quote($this->name, '/') . ')\]\(' . $internal_regex . '\)/i'; + + $result = preg_replace_callback($regex, $function, $content); + \assert($result !== null); + + return $result; + } + + /** + * Merge global and page configurations. + * + * WARNING: This method modifies page header! + * + * @param PageInterface $page The page to merge the configurations with the + * plugin settings. + * @param mixed $deep false = shallow|true = recursive|merge = recursive+unique + * @param array $params Array of additional configuration options to + * merge with the plugin settings. + * @param string $type Is this 'plugins' or 'themes' + * @return Data + */ + protected function mergeConfig(PageInterface $page, $deep = false, $params = [], $type = 'plugins') + { + /** @var Config $config */ + $config = $this->config ?? $this->grav['config']; + + $class_name = $this->name; + $class_name_merged = $class_name . '.merged'; + $defaults = $config->get($type . '.' . $class_name, []); + $page_header = $page->header(); + $header = []; + + if (!isset($page_header->{$class_name_merged}) && isset($page_header->{$class_name})) { + // Get default plugin configurations and retrieve page header configuration + $config = $page_header->{$class_name}; + if (is_bool($config)) { + // Overwrite enabled option with boolean value in page header + $config = ['enabled' => $config]; + } + // Merge page header settings using deep or shallow merging technique + $header = $this->mergeArrays($deep, $defaults, $config); + + // Create new config object and set it on the page object so it's cached for next time + $page->modifyHeader($class_name_merged, new Data($header)); + } elseif (isset($page_header->{$class_name_merged})) { + $merged = $page_header->{$class_name_merged}; + $header = $merged->toArray(); + } + if (empty($header)) { + $header = $defaults; + } + // Merge additional parameter with configuration options + $header = $this->mergeArrays($deep, $header, $params); + + // Return configurations as a new data config class + return new Data($header); + } + + /** + * Merge arrays based on deepness + * + * @param string|bool $deep + * @param array $array1 + * @param array $array2 + * @return array + */ + private function mergeArrays($deep, $array1, $array2) + { + if ($deep === 'merge') { + return Utils::arrayMergeRecursiveUnique($array1, $array2); + } + if ($deep === true) { + return array_replace_recursive($array1, $array2); + } + + return array_merge($array1, $array2); + } + + /** + * Persists to disk the plugin parameters currently stored in the Grav Config object + * + * @param string $name The name of the plugin whose config it should store. + * @return bool + */ + public static function saveConfig($name) + { + if (!$name) { + return false; + } + + $grav = Grav::instance(); + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + + $filename = 'config://plugins/' . $name . '.yaml'; + $file = YamlFile::instance((string)$locator->findResource($filename, true, true)); + $content = $grav['config']->get('plugins.' . $name); + $file->save($content); + $file->free(); + unset($file); + + return true; + } + + public static function inheritedConfigOption(string $plugin, string $var, PageInterface $page = null, $default = null) + { + if (Utils::isAdminPlugin()) { + $page = Grav::instance()['admin']->page() ?? null; + } else { + $page = $page ?? Grav::instance()['page'] ?? null; + } + + // Try to find var in the page headers + if ($page instanceof PageInterface && $page->exists()) { + // Loop over pages and look for header vars + while ($page && !$page->root()) { + $header = new Data((array)$page->header()); + $value = $header->get("$plugin.$var"); + if (isset($value)) { + return $value; + } + $page = $page->parent(); + } + } + + return Grav::instance()['config']->get("plugins.$plugin.$var", $default); + } + + /** + * Simpler getter for the plugin blueprint + * + * @return Blueprint + */ + public function getBlueprint() + { + if (null === $this->blueprint) { + $this->loadBlueprint(); + \assert($this->blueprint instanceof Blueprint); + } + + return $this->blueprint; + } + + /** + * Load blueprints. + * + * @return void + */ + protected function loadBlueprint() + { + if (null === $this->blueprint) { + $grav = Grav::instance(); + /** @var Plugins $plugins */ + $plugins = $grav['plugins']; + $data = $plugins->get($this->name); + \assert($data !== null); + $this->blueprint = $data->blueprints(); + } + } +} diff --git a/system/src/Grav/Common/Plugins.php b/system/src/Grav/Common/Plugins.php new file mode 100644 index 0000000..2ab1050 --- /dev/null +++ b/system/src/Grav/Common/Plugins.php @@ -0,0 +1,330 @@ +getIterator('plugins://'); + + $plugins = []; + /** @var SplFileInfo $directory */ + foreach ($iterator as $directory) { + if (!$directory->isDir()) { + continue; + } + $plugins[] = $directory->getFilename(); + } + + sort($plugins, SORT_NATURAL | SORT_FLAG_CASE); + + foreach ($plugins as $plugin) { + $object = $this->loadPlugin($plugin); + if ($object) { + $this->add($object); + } + } + } + + /** + * @return $this + */ + public function setup() + { + $blueprints = []; + $formFields = []; + + $grav = Grav::instance(); + + /** @var Config $config */ + $config = $grav['config']; + + /** @var Plugin $plugin */ + foreach ($this->items as $plugin) { + // Setup only enabled plugins. + if ($config["plugins.{$plugin->name}.enabled"] && $plugin instanceof Plugin) { + if (isset($plugin->features['blueprints'])) { + $blueprints["plugin://{$plugin->name}/blueprints"] = $plugin->features['blueprints']; + } + if (method_exists($plugin, 'getFormFieldTypes')) { + $formFields[get_class($plugin)] = $plugin->features['formfields'] ?? 0; + } + } + } + + if ($blueprints) { + // Order by priority. + arsort($blueprints, SORT_NUMERIC); + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + $locator->addPath('blueprints', '', array_keys($blueprints), ['system', 'blueprints']); + } + + if ($formFields) { + // Order by priority. + arsort($formFields, SORT_NUMERIC); + + $list = []; + foreach ($formFields as $className => $priority) { + $plugin = $this->items[$className]; + $list += $plugin->getFormFieldTypes(); + } + + $this->formFieldTypes = $list; + } + + return $this; + } + + /** + * Registers all plugins. + * + * @return Plugin[] array of Plugin objects + * @throws RuntimeException + */ + public function init() + { + if ($this->plugins_initialized) { + return $this->items; + } + + $grav = Grav::instance(); + + /** @var Config $config */ + $config = $grav['config']; + + /** @var EventDispatcher $events */ + $events = $grav['events']; + + foreach ($this->items as $instance) { + // Register only enabled plugins. + if ($config["plugins.{$instance->name}.enabled"] && $instance instanceof Plugin) { + // Set plugin configuration. + $instance->setConfig($config); + // Register autoloader. + if (method_exists($instance, 'autoload')) { + $instance->setAutoloader($instance->autoload()); + } + // Register event listeners. + $events->addSubscriber($instance); + } + } + + // Plugins Loaded Event + $event = new PluginsLoadedEvent($grav, $this); + $grav->dispatchEvent($event); + + $this->plugins_initialized = true; + + return $this->items; + } + + /** + * Add a plugin + * + * @param Plugin $plugin + * @return void + */ + public function add($plugin) + { + if (is_object($plugin)) { + $this->items[get_class($plugin)] = $plugin; + } + } + + /** + * @return array + */ + public function __debugInfo(): array + { + $array = (array)$this; + + unset($array["\0Grav\Common\Iterator\0iteratorUnset"]); + + return $array; + } + + /** + * @return Plugin[] Index of all plugins by plugin name. + */ + public static function getPlugins(): array + { + /** @var Plugins $plugins */ + $plugins = Grav::instance()['plugins']; + + $list = []; + foreach ($plugins as $instance) { + $list[$instance->name] = $instance; + } + + return $list; + } + + /** + * @param string $name Plugin name + * @return Plugin|null Plugin object or null if plugin cannot be found. + */ + public static function getPlugin(string $name) + { + $list = static::getPlugins(); + + return $list[$name] ?? null; + } + + /** + * Return list of all plugin data with their blueprints. + * + * @return Data[] + */ + public static function all() + { + $grav = Grav::instance(); + + /** @var Plugins $plugins */ + $plugins = $grav['plugins']; + $list = []; + + foreach ($plugins as $instance) { + $name = $instance->name; + + try { + $result = self::get($name); + } catch (Exception $e) { + $exception = new RuntimeException(sprintf('Plugin %s: %s', $name, $e->getMessage()), $e->getCode(), $e); + + /** @var Debugger $debugger */ + $debugger = $grav['debugger']; + $debugger->addMessage("Plugin {$name} cannot be loaded, please check Exceptions tab", 'error'); + $debugger->addException($exception); + + continue; + } + + if ($result) { + $list[$name] = $result; + } + } + + return $list; + } + + /** + * Get a plugin by name + * + * @param string $name + * @return Data|null + */ + public static function get($name) + { + $blueprints = new Blueprints('plugins://'); + $blueprint = $blueprints->get("{$name}/blueprints"); + + // Load default configuration. + $file = CompiledYamlFile::instance("plugins://{$name}/{$name}" . YAML_EXT); + + // ensure this is a valid plugin + if (!$file->exists()) { + return null; + } + + $obj = new Data((array)$file->content(), $blueprint); + + // Override with user configuration. + $obj->merge(Grav::instance()['config']->get('plugins.' . $name) ?: []); + + // Save configuration always to user/config. + $file = CompiledYamlFile::instance("config://plugins/{$name}.yaml"); + $obj->file($file); + + return $obj; + } + + /** + * @param string $name + * @return Plugin|null + */ + protected function loadPlugin($name) + { + // NOTE: ALL THE LOCAL VARIABLES ARE USED INSIDE INCLUDED FILE, DO NOT REMOVE THEM! + $grav = Grav::instance(); + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + $class = null; + + // Start by attempting to load the plugin_name.php file. + $file = $locator->findResource('plugins://' . $name . DS . $name . PLUGIN_EXT); + if (is_file($file)) { + // Local variables available in the file: $grav, $name, $file + $class = include_once $file; + if (!is_object($class) || !is_subclass_of($class, Plugin::class, true)) { + $class = null; + } + } + + // If the class hasn't been initialized yet, guess the class name and create a new instance. + if (null === $class) { + $className = Inflector::camelize($name); + $pluginClassFormat = [ + 'Grav\\Plugin\\' . ucfirst($name). 'Plugin', + 'Grav\\Plugin\\' . $className . 'Plugin', + 'Grav\\Plugin\\' . $className + ]; + + foreach ($pluginClassFormat as $pluginClass) { + if (is_subclass_of($pluginClass, Plugin::class, true)) { + $class = new $pluginClass($name, $grav); + break; + } + } + } + + // Log a warning if plugin cannot be found. + if (null === $class) { + $grav['log']->addWarning( + sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clearcache`", $name) + ); + } + + return $class; + } +} diff --git a/system/src/Grav/Common/Processors/AssetsProcessor.php b/system/src/Grav/Common/Processors/AssetsProcessor.php new file mode 100644 index 0000000..dea7546 --- /dev/null +++ b/system/src/Grav/Common/Processors/AssetsProcessor.php @@ -0,0 +1,41 @@ +startTimer(); + $this->container['assets']->init(); + $this->container->fireEvent('onAssetsInitialized'); + $this->stopTimer(); + + return $handler->handle($request); + } +} diff --git a/system/src/Grav/Common/Processors/BackupsProcessor.php b/system/src/Grav/Common/Processors/BackupsProcessor.php new file mode 100644 index 0000000..72a2d04 --- /dev/null +++ b/system/src/Grav/Common/Processors/BackupsProcessor.php @@ -0,0 +1,41 @@ +startTimer(); + $backups = $this->container['backups']; + $backups->init(); + $this->stopTimer(); + + return $handler->handle($request); + } +} diff --git a/system/src/Grav/Common/Processors/DebuggerAssetsProcessor.php b/system/src/Grav/Common/Processors/DebuggerAssetsProcessor.php new file mode 100644 index 0000000..19e56e0 --- /dev/null +++ b/system/src/Grav/Common/Processors/DebuggerAssetsProcessor.php @@ -0,0 +1,40 @@ +startTimer(); + $this->container['debugger']->addAssets(); + $this->stopTimer(); + + return $handler->handle($request); + } +} diff --git a/system/src/Grav/Common/Processors/Events/RequestHandlerEvent.php b/system/src/Grav/Common/Processors/Events/RequestHandlerEvent.php new file mode 100644 index 0000000..7becf22 --- /dev/null +++ b/system/src/Grav/Common/Processors/Events/RequestHandlerEvent.php @@ -0,0 +1,82 @@ +offsetGet('request'); + } + + /** + * @return Route + */ + public function getRoute(): Route + { + return $this->getRequest()->getAttribute('route'); + } + + /** + * @return RequestHandler + */ + public function getHandler(): RequestHandler + { + return $this->offsetGet('handler'); + } + + /** + * @return ResponseInterface|null + */ + public function getResponse(): ?ResponseInterface + { + return $this->offsetGet('response'); + } + + /** + * @param ResponseInterface $response + * @return $this + */ + public function setResponse(ResponseInterface $response): self + { + $this->offsetSet('response', $response); + $this->stopPropagation(); + + return $this; + } + + /** + * @param string $name + * @param MiddlewareInterface $middleware + * @return RequestHandlerEvent + */ + public function addMiddleware(string $name, MiddlewareInterface $middleware): self + { + /** @var RequestHandler $handler */ + $handler = $this['handler']; + $handler->addMiddleware($name, $middleware); + + return $this; + } +} diff --git a/system/src/Grav/Common/Processors/InitializeProcessor.php b/system/src/Grav/Common/Processors/InitializeProcessor.php new file mode 100644 index 0000000..2c5035b --- /dev/null +++ b/system/src/Grav/Common/Processors/InitializeProcessor.php @@ -0,0 +1,461 @@ +processCli(); + } + } + + /** + * @param ServerRequestInterface $request + * @param RequestHandlerInterface $handler + * @return ResponseInterface + */ + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + $this->startTimer('_init', 'Initialize'); + + // Load configuration. + $config = $this->initializeConfig(); + + // Initialize logger. + $this->initializeLogger($config); + + // Initialize error handlers. + $this->initializeErrors(); + + // Initialize debugger. + $debugger = $this->initializeDebugger(); + + // Debugger can return response right away. + $response = $this->handleDebuggerRequest($debugger, $request); + if ($response) { + $this->stopTimer('_init'); + + return $response; + } + + // Initialize output buffering. + $this->initializeOutputBuffering($config); + + // Set timezone, locale. + $this->initializeLocale($config); + + // Load plugins. + $this->initializePlugins(); + + // Load pages. + $this->initializePages($config); + + // Load accounts (decides class to be used). + // TODO: remove in 2.0. + $this->container['accounts']; + + // Initialize session (used by URI, see issue #3269). + $this->initializeSession($config); + + // Initialize URI (uses session, see issue #3269). + $this->initializeUri($config); + + // Grav may return redirect response right away. + $redirectCode = (int)$config->get('system.pages.redirect_trailing_slash', 1); + if ($redirectCode) { + $response = $this->handleRedirectRequest($request, $redirectCode > 300 ? $redirectCode : null); + if ($response) { + $this->stopTimer('_init'); + + return $response; + } + } + + $this->stopTimer('_init'); + + // Wrap call to next handler so that debugger can profile it. + /** @var Response $response */ + $response = $debugger->profile(static function () use ($handler, $request) { + return $handler->handle($request); + }); + + // Log both request and response and return the response. + return $debugger->logRequest($request, $response); + } + + public function processCli(): void + { + // Load configuration. + $config = $this->initializeConfig(); + + // Initialize logger. + $this->initializeLogger($config); + + // Disable debugger. + $this->container['debugger']->enabled(false); + + // Set timezone, locale. + $this->initializeLocale($config); + + // Load plugins. + $this->initializePlugins(); + + // Load pages. + $this->initializePages($config); + + // Initialize URI. + $this->initializeUri($config); + + // Load accounts (decides class to be used). + // TODO: remove in 2.0. + $this->container['accounts']; + } + + /** + * @return Config + */ + protected function initializeConfig(): Config + { + $this->startTimer('_init_config', 'Configuration'); + + // Initialize Configuration + $grav = $this->container; + + /** @var Config $config */ + $config = $grav['config']; + $config->init(); + $grav['plugins']->setup(); + + if (defined('GRAV_SCHEMA') && $config->get('versions') === null) { + $filename = USER_DIR . 'config/versions.yaml'; + if (!is_file($filename)) { + $versions = [ + 'core' => [ + 'grav' => [ + 'version' => GRAV_VERSION, + 'schema' => GRAV_SCHEMA + ] + ] + ]; + $config->set('versions', $versions); + + $file = new YamlFile($filename, new YamlFormatter(['inline' => 4])); + $file->save($versions); + } + } + + // Override configuration using the environment. + $prefix = 'GRAV_CONFIG'; + $env = getenv($prefix); + if ($env) { + $cPrefix = $prefix . '__'; + $aPrefix = $prefix . '_ALIAS__'; + $cLen = strlen($cPrefix); + $aLen = strlen($aPrefix); + + $keys = $aliases = []; + $env = $_ENV + $_SERVER; + foreach ($env as $key => $value) { + if (!str_starts_with($key, $prefix)) { + continue; + } + if (str_starts_with($key, $cPrefix)) { + $key = str_replace('__', '.', substr($key, $cLen)); + $keys[$key] = $value; + } elseif (str_starts_with($key, $aPrefix)) { + $key = substr($key, $aLen); + $aliases[$key] = $value; + } + } + $list = []; + foreach ($keys as $key => $value) { + foreach ($aliases as $alias => $real) { + $key = str_replace($alias, $real, $key); + } + $list[$key] = $value; + $config->set($key, $value); + } + } + + $this->stopTimer('_init_config'); + + return $config; + } + + /** + * @param Config $config + * @return Logger + */ + protected function initializeLogger(Config $config): Logger + { + $this->startTimer('_init_logger', 'Logger'); + + $grav = $this->container; + + // Initialize Logging + /** @var Logger $log */ + $log = $grav['log']; + + if ($config->get('system.log.handler', 'file') === 'syslog') { + $log->popHandler(); + + $facility = $config->get('system.log.syslog.facility', 'local6'); + $tag = $config->get('system.log.syslog.tag', 'grav'); + $logHandler = new SyslogHandler($tag, $facility); + $formatter = new LineFormatter("%channel%.%level_name%: %message% %extra%"); + $logHandler->setFormatter($formatter); + + $log->pushHandler($logHandler); + } + + $this->stopTimer('_init_logger'); + + return $log; + } + + /** + * @return Errors + */ + protected function initializeErrors(): Errors + { + $this->startTimer('_init_errors', 'Error Handlers Reset'); + + $grav = $this->container; + + // Initialize Error Handlers + /** @var Errors $errors */ + $errors = $grav['errors']; + $errors->resetHandlers(); + + $this->stopTimer('_init_errors'); + + return $errors; + } + + /** + * @return Debugger + */ + protected function initializeDebugger(): Debugger + { + $this->startTimer('_init_debugger', 'Init Debugger'); + + $grav = $this->container; + + /** @var Debugger $debugger */ + $debugger = $grav['debugger']; + $debugger->init(); + + $this->stopTimer('_init_debugger'); + + return $debugger; + } + + /** + * @param Debugger $debugger + * @param ServerRequestInterface $request + * @return ResponseInterface|null + */ + protected function handleDebuggerRequest(Debugger $debugger, ServerRequestInterface $request): ?ResponseInterface + { + // Clockwork integration. + $clockwork = $debugger->getClockwork(); + if ($clockwork) { + $server = $request->getServerParams(); +// $baseUri = str_replace('\\', '/', dirname(parse_url($server['SCRIPT_NAME'], PHP_URL_PATH))); +// if ($baseUri === '/') { +// $baseUri = ''; +// } + $requestTime = $server['REQUEST_TIME_FLOAT'] ?? GRAV_REQUEST_TIME; + + $request = $request->withAttribute('request_time', $requestTime); + + // Handle clockwork API calls. + $uri = $request->getUri(); + if (Utils::contains($uri->getPath(), '/__clockwork/')) { + return $debugger->debuggerRequest($request); + } + + $this->container['clockwork'] = $clockwork; + } + + return null; + } + + /** + * @param Config $config + */ + protected function initializeOutputBuffering(Config $config): void + { + $this->startTimer('_init_ob', 'Initialize Output Buffering'); + + // Use output buffering to prevent headers from being sent too early. + ob_start(); + if ($config->get('system.cache.gzip') && !@ob_start('ob_gzhandler')) { + // Enable zip/deflate with a fallback in case of if browser does not support compressing. + ob_start(); + } + + $this->stopTimer('_init_ob'); + } + + /** + * @param Config $config + */ + protected function initializeLocale(Config $config): void + { + $this->startTimer('_init_locale', 'Initialize Locale'); + + // Initialize the timezone. + $timezone = $config->get('system.timezone'); + if ($timezone) { + date_default_timezone_set($timezone); + } + + $grav = $this->container; + $grav->setLocale(); + + $this->stopTimer('_init_locale'); + } + + protected function initializePlugins(): Plugins + { + $this->startTimer('_init_plugins_load', 'Load Plugins'); + + $grav = $this->container; + + /** @var Plugins $plugins */ + $plugins = $grav['plugins']; + $plugins->init(); + + $this->stopTimer('_init_plugins_load'); + + return $plugins; + } + + protected function initializePages(Config $config): Pages + { + $this->startTimer('_init_pages_register', 'Load Pages'); + + $grav = $this->container; + + /** @var Pages $pages */ + $pages = $grav['pages']; + // Upgrading from older Grav versions won't work without checking if the method exists. + if (method_exists($pages, 'register')) { + $pages->register(); + } + + $this->stopTimer('_init_pages_register'); + + return $pages; + } + + + protected function initializeUri(Config $config): void + { + $this->startTimer('_init_uri', 'Initialize URI'); + + $grav = $this->container; + + /** @var Uri $uri */ + $uri = $grav['uri']; + $uri->init(); + + $this->stopTimer('_init_uri'); + } + + protected function handleRedirectRequest(RequestInterface $request, int $code = null): ?ResponseInterface + { + if (!in_array($request->getMethod(), ['GET', 'HEAD'])) { + return null; + } + + // Redirect pages with trailing slash if configured to do so. + $uri = $request->getUri(); + $path = $uri->getPath() ?: '/'; + $root = $this->container['uri']->rootUrl(); + + if ($path !== $root && $path !== $root . '/' && Utils::endsWith($path, '/')) { + // Use permanent redirect for SEO reasons. + return $this->container->getRedirectResponse((string)$uri->withPath(rtrim($path, '/')), $code); + } + + return null; + } + + /** + * @param Config $config + */ + protected function initializeSession(Config $config): void + { + // FIXME: Initialize session should happen later after plugins have been loaded. This is a workaround to fix session issues in AWS. + if (isset($this->container['session']) && $config->get('system.session.initialize', true)) { + $this->startTimer('_init_session', 'Start Session'); + + /** @var Session $session */ + $session = $this->container['session']; + + try { + $session->init(); + } catch (SessionException $e) { + $session->init(); + $message = 'Session corruption detected, restarting session...'; + $this->addMessage($message); + $this->container['messages']->add($message, 'error'); + } + + $this->stopTimer('_init_session'); + } + } +} diff --git a/system/src/Grav/Common/Processors/PagesProcessor.php b/system/src/Grav/Common/Processors/PagesProcessor.php new file mode 100644 index 0000000..38a47a4 --- /dev/null +++ b/system/src/Grav/Common/Processors/PagesProcessor.php @@ -0,0 +1,115 @@ +startTimer(); + + // Dump Cache state + $this->container['debugger']->addMessage($this->container['cache']->getCacheStatus()); + + $this->container['pages']->init(); + + $route = $this->container['route']; + + $this->container->fireEvent('onPagesInitialized', new Event( + [ + 'pages' => $this->container['pages'], + 'route' => $route, + 'request' => $request + ] + )); + $this->container->fireEvent('onPageInitialized', new Event( + [ + 'page' => $this->container['page'], + 'route' => $route, + 'request' => $request + ] + )); + + /** @var PageInterface $page */ + $page = $this->container['page']; + + if (!$page->routable()) { + $exception = new RequestException($request, 'Page Not Found', 404); + // If no page found, fire event + $event = new PageEvent([ + 'page' => $page, + 'code' => $exception->getCode(), + 'message' => $exception->getMessage(), + 'exception' => $exception, + 'route' => $route, + 'request' => $request + ]); + $event->page = null; + $event = $this->container->fireEvent('onPageNotFound', $event); + + if (isset($event->page)) { + unset($this->container['page']); + $this->container['page'] = $page = $event->page; + } else { + throw new RuntimeException('Page Not Found', 404); + } + + $this->addMessage("Routed to page {$page->rawRoute()} (type: {$page->template()}) [Not Found fallback]"); + } else { + $this->addMessage("Routed to page {$page->rawRoute()} (type: {$page->template()})"); + + $task = $this->container['task']; + $action = $this->container['action']; + + /** @var Forms $forms */ + $forms = $this->container['forms'] ?? null; + $form = $forms ? $forms->getActiveForm() : null; + + $options = ['page' => $page, 'form' => $form, 'request' => $request]; + if ($task) { + $event = new Event(['task' => $task] + $options); + $this->container->fireEvent('onPageTask', $event); + $this->container->fireEvent('onPageTask.' . $task, $event); + } elseif ($action) { + $event = new Event(['action' => $action] + $options); + $this->container->fireEvent('onPageAction', $event); + $this->container->fireEvent('onPageAction.' . $action, $event); + } + } + + $this->stopTimer(); + + return $handler->handle($request); + } +} diff --git a/system/src/Grav/Common/Processors/PluginsProcessor.php b/system/src/Grav/Common/Processors/PluginsProcessor.php new file mode 100644 index 0000000..320d8f2 --- /dev/null +++ b/system/src/Grav/Common/Processors/PluginsProcessor.php @@ -0,0 +1,41 @@ +startTimer(); + $grav = $this->container; + $grav->fireEvent('onPluginsInitialized'); + $this->stopTimer(); + + return $handler->handle($request); + } +} diff --git a/system/src/Grav/Common/Processors/ProcessorBase.php b/system/src/Grav/Common/Processors/ProcessorBase.php new file mode 100644 index 0000000..2a6244d --- /dev/null +++ b/system/src/Grav/Common/Processors/ProcessorBase.php @@ -0,0 +1,70 @@ +container = $container; + } + + /** + * @param string|null $id + * @param string|null $title + */ + protected function startTimer($id = null, $title = null): void + { + /** @var Debugger $debugger */ + $debugger = $this->container['debugger']; + $debugger->startTimer($id ?? $this->id, $title ?? $this->title); + } + + /** + * @param string|null $id + */ + protected function stopTimer($id = null): void + { + /** @var Debugger $debugger */ + $debugger = $this->container['debugger']; + $debugger->stopTimer($id ?? $this->id); + } + + /** + * @param string $message + * @param string $label + * @param bool $isString + */ + protected function addMessage($message, $label = 'info', $isString = true): void + { + /** @var Debugger $debugger */ + $debugger = $this->container['debugger']; + $debugger->addMessage($message, $label, $isString); + } +} diff --git a/system/src/Grav/Common/Processors/ProcessorInterface.php b/system/src/Grav/Common/Processors/ProcessorInterface.php new file mode 100644 index 0000000..3178f1a --- /dev/null +++ b/system/src/Grav/Common/Processors/ProcessorInterface.php @@ -0,0 +1,20 @@ +startTimer(); + + $container = $this->container; + $output = $container['output']; + + if ($output instanceof ResponseInterface) { + return $output; + } + + /** @var PageInterface $page */ + $page = $this->container['page']; + + // Use internal Grav output. + $container->output = $output; + + ob_start(); + + $event = new Event(['page' => $page, 'output' => &$container->output]); + $container->fireEvent('onOutputGenerated', $event); + + echo $container->output; + + $html = ob_get_clean(); + + // remove any output + $container->output = ''; + + $event = new Event(['page' => $page, 'output' => $html]); + $this->container->fireEvent('onOutputRendered', $event); + + $this->stopTimer(); + + return new Response($page->httpResponseCode(), $page->httpHeaders(), $html); + } +} diff --git a/system/src/Grav/Common/Processors/RequestProcessor.php b/system/src/Grav/Common/Processors/RequestProcessor.php new file mode 100644 index 0000000..97122ea --- /dev/null +++ b/system/src/Grav/Common/Processors/RequestProcessor.php @@ -0,0 +1,66 @@ +startTimer(); + + $header = $request->getHeaderLine('Content-Type'); + $type = trim(strstr($header, ';', true) ?: $header); + if ($type === 'application/json') { + $request = $request->withParsedBody(json_decode($request->getBody()->getContents(), true)); + } + + $uri = $request->getUri(); + $ext = mb_strtolower(Utils::pathinfo($uri->getPath(), PATHINFO_EXTENSION)); + + $request = $request + ->withAttribute('grav', $this->container) + ->withAttribute('time', $_SERVER['REQUEST_TIME_FLOAT'] ?? GRAV_REQUEST_TIME) + ->withAttribute('route', Uri::getCurrentRoute()->withExtension($ext)) + ->withAttribute('referrer', $this->container['uri']->referrer()); + + $event = new RequestHandlerEvent(['request' => $request, 'handler' => $handler]); + /** @var RequestHandlerEvent $event */ + $event = $this->container->fireEvent('onRequestHandlerInit', $event); + $response = $event->getResponse(); + $this->stopTimer(); + + if ($response) { + return $response; + } + + return $handler->handle($request); + } +} diff --git a/system/src/Grav/Common/Processors/SchedulerProcessor.php b/system/src/Grav/Common/Processors/SchedulerProcessor.php new file mode 100644 index 0000000..c3f05cb --- /dev/null +++ b/system/src/Grav/Common/Processors/SchedulerProcessor.php @@ -0,0 +1,42 @@ +startTimer(); + $scheduler = $this->container['scheduler']; + $this->container->fireEvent('onSchedulerInitialized', new Event(['scheduler' => $scheduler])); + $this->stopTimer(); + + return $handler->handle($request); + } +} diff --git a/system/src/Grav/Common/Processors/TasksProcessor.php b/system/src/Grav/Common/Processors/TasksProcessor.php new file mode 100644 index 0000000..ab5caf9 --- /dev/null +++ b/system/src/Grav/Common/Processors/TasksProcessor.php @@ -0,0 +1,71 @@ +startTimer(); + + $task = $this->container['task']; + $action = $this->container['action']; + if ($task || $action) { + $attributes = $request->getAttribute('controller'); + + $controllerClass = $attributes['class'] ?? null; + if ($controllerClass) { + /** @var RequestHandlerInterface $controller */ + $controller = new $controllerClass($attributes['path'] ?? '', $attributes['params'] ?? []); + try { + $response = $controller->handle($request); + + if ($response->getStatusCode() === 418) { + $response = $handler->handle($request); + } + + $this->stopTimer(); + + return $response; + } catch (NotFoundException $e) { + // Task not found: Let it pass through. + } + } + + if ($task) { + $this->container->fireEvent('onTask.' . $task); + } elseif ($action) { + $this->container->fireEvent('onAction.' . $action); + } + } + $this->stopTimer(); + + return $handler->handle($request); + } +} diff --git a/system/src/Grav/Common/Processors/ThemesProcessor.php b/system/src/Grav/Common/Processors/ThemesProcessor.php new file mode 100644 index 0000000..a035f29 --- /dev/null +++ b/system/src/Grav/Common/Processors/ThemesProcessor.php @@ -0,0 +1,40 @@ +startTimer(); + $this->container['themes']->init(); + $this->stopTimer(); + + return $handler->handle($request); + } +} diff --git a/system/src/Grav/Common/Processors/TwigProcessor.php b/system/src/Grav/Common/Processors/TwigProcessor.php new file mode 100644 index 0000000..513add0 --- /dev/null +++ b/system/src/Grav/Common/Processors/TwigProcessor.php @@ -0,0 +1,40 @@ +startTimer(); + $this->container['twig']->init(); + $this->stopTimer(); + + return $handler->handle($request); + } +} diff --git a/system/src/Grav/Common/Scheduler/Cron.php b/system/src/Grav/Common/Scheduler/Cron.php new file mode 100644 index 0000000..d50d100 --- /dev/null +++ b/system/src/Grav/Common/Scheduler/Cron.php @@ -0,0 +1,577 @@ + modified for Grav integration + * @copyright Copyright (c) 2015 - 2024 Trilby Media, LLC. All rights reserved. + * @license MIT License; see LICENSE file for details. + */ + +namespace Grav\Common\Scheduler; + +/* + * Usage examples : + * ---------------- + * + * $cron = new Cron('10-30/5 12 * * *'); + * + * var_dump($cron->getMinutes()); + * // array(5) { + * // [0]=> int(10) + * // [1]=> int(15) + * // [2]=> int(20) + * // [3]=> int(25) + * // [4]=> int(30) + * // } + * + * var_dump($cron->getText('fr')); + * // string(32) "Chaque jour à 12:10,15,20,25,30" + * + * var_dump($cron->getText('en')); + * // string(30) "Every day at 12:10,15,20,25,30" + * + * var_dump($cron->getType()); + * // string(3) "day" + * + * var_dump($cron->getCronHours()); + * // string(2) "12" + * + * var_dump($cron->matchExact(new \DateTime('2012-07-01 13:25:10'))); + * // bool(false) + * + * var_dump($cron->matchExact(new \DateTime('2012-07-01 12:15:20'))); + * // bool(true) + * + * var_dump($cron->matchWithMargin(new \DateTime('2012-07-01 12:32:50'), -3, 5)); + * // bool(true) + */ + +use DateInterval; +use DateTime; +use RuntimeException; +use function count; +use function in_array; +use function is_array; +use function is_string; + +class Cron +{ + public const TYPE_UNDEFINED = ''; + public const TYPE_MINUTE = 'minute'; + public const TYPE_HOUR = 'hour'; + public const TYPE_DAY = 'day'; + public const TYPE_WEEK = 'week'; + public const TYPE_MONTH = 'month'; + public const TYPE_YEAR = 'year'; + /** + * + * @var array + */ + protected $texts = [ + 'fr' => [ + 'empty' => '-tout-', + 'name_minute' => 'minute', + 'name_hour' => 'heure', + 'name_day' => 'jour', + 'name_week' => 'semaine', + 'name_month' => 'mois', + 'name_year' => 'année', + 'text_period' => 'Chaque %s', + 'text_mins' => 'à %s minutes', + 'text_time' => 'à %02s:%02s', + 'text_dow' => 'le %s', + 'text_month' => 'de %s', + 'text_dom' => 'le %s', + 'weekdays' => ['lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche'], + 'months' => ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'], + ], + 'en' => [ + 'empty' => '-all-', + 'name_minute' => 'minute', + 'name_hour' => 'hour', + 'name_day' => 'day', + 'name_week' => 'week', + 'name_month' => 'month', + 'name_year' => 'year', + 'text_period' => 'Every %s', + 'text_mins' => 'at %s minutes past the hour', + 'text_time' => 'at %02s:%02s', + 'text_dow' => 'on %s', + 'text_month' => 'of %s', + 'text_dom' => 'on the %s', + 'weekdays' => ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'], + 'months' => ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'], + ], + ]; + + /** + * min hour dom month dow + * @var string + */ + protected $cron = ''; + /** + * + * @var array + */ + protected $minutes = []; + /** + * + * @var array + */ + protected $hours = []; + /** + * + * @var array + */ + protected $months = []; + /** + * 0-7 : sunday, monday, ... saturday, sunday + * @var array + */ + protected $dow = []; + /** + * + * @var array + */ + protected $dom = []; + + /** + * @param string|null $cron + */ + public function __construct($cron = null) + { + if (null !== $cron) { + $this->setCron($cron); + } + } + + /** + * @return string + */ + public function getCron() + { + return implode(' ', [ + $this->getCronMinutes(), + $this->getCronHours(), + $this->getCronDaysOfMonth(), + $this->getCronMonths(), + $this->getCronDaysOfWeek(), + ]); + } + + /** + * @param string $lang 'fr' or 'en' + * @return string + */ + public function getText($lang) + { + // check lang + if (!isset($this->texts[$lang])) { + return $this->getCron(); + } + + $texts = $this->texts[$lang]; + // check type + + $type = $this->getType(); + if ($type === self::TYPE_UNDEFINED) { + return $this->getCron(); + } + + // init + $elements = []; + $elements[] = sprintf($texts['text_period'], $texts['name_' . $type]); + + // hour + if ($type === self::TYPE_HOUR) { + $elements[] = sprintf($texts['text_mins'], $this->getCronMinutes()); + } + + // week + if ($type === self::TYPE_WEEK) { + $dow = $this->getCronDaysOfWeek(); + foreach ($texts['weekdays'] as $i => $wd) { + $dow = str_replace((string) ($i + 1), $wd, $dow); + } + $elements[] = sprintf($texts['text_dow'], $dow); + } + + // month + year + if (in_array($type, [self::TYPE_MONTH, self::TYPE_YEAR], true)) { + $elements[] = sprintf($texts['text_dom'], $this->getCronDaysOfMonth()); + } + + // year + if ($type === self::TYPE_YEAR) { + $months = $this->getCronMonths(); + for ($i = count($texts['months']) - 1; $i >= 0; $i--) { + $months = str_replace((string) ($i + 1), $texts['months'][$i], $months); + } + $elements[] = sprintf($texts['text_month'], $months); + } + + // day + week + month + year + if (in_array($type, [self::TYPE_DAY, self::TYPE_WEEK, self::TYPE_MONTH, self::TYPE_YEAR], true)) { + $elements[] = sprintf($texts['text_time'], $this->getCronHours(), $this->getCronMinutes()); + } + + return str_replace('*', $texts['empty'], implode(' ', $elements)); + } + + /** + * @return string + */ + public function getType() + { + $mask = preg_replace('/[^\* ]/', '-', $this->getCron()); + $mask = preg_replace('/-+/', '-', $mask); + $mask = preg_replace('/[^-\*]/', '', $mask); + + if ($mask === '*****') { + return self::TYPE_MINUTE; + } + + if ($mask === '-****') { + return self::TYPE_HOUR; + } + + if (substr($mask, -3) === '***') { + return self::TYPE_DAY; + } + + if (substr($mask, -3) === '-**') { + return self::TYPE_MONTH; + } + + if (substr($mask, -3) === '**-') { + return self::TYPE_WEEK; + } + + if (substr($mask, -2) === '-*') { + return self::TYPE_YEAR; + } + + return self::TYPE_UNDEFINED; + } + + /** + * @param string $cron + * @return $this + */ + public function setCron($cron) + { + // sanitize + $cron = trim($cron); + $cron = preg_replace('/\s+/', ' ', $cron); + // explode + $elements = explode(' ', $cron); + if (count($elements) !== 5) { + throw new RuntimeException('Bad number of elements'); + } + + $this->cron = $cron; + $this->setMinutes($elements[0]); + $this->setHours($elements[1]); + $this->setDaysOfMonth($elements[2]); + $this->setMonths($elements[3]); + $this->setDaysOfWeek($elements[4]); + + return $this; + } + + /** + * @return string + */ + public function getCronMinutes() + { + return $this->arrayToCron($this->minutes); + } + + /** + * @return string + */ + public function getCronHours() + { + return $this->arrayToCron($this->hours); + } + + /** + * @return string + */ + public function getCronDaysOfMonth() + { + return $this->arrayToCron($this->dom); + } + + /** + * @return string + */ + public function getCronMonths() + { + return $this->arrayToCron($this->months); + } + + /** + * @return string + */ + public function getCronDaysOfWeek() + { + return $this->arrayToCron($this->dow); + } + + /** + * @return array + */ + public function getMinutes() + { + return $this->minutes; + } + + /** + * @return array + */ + public function getHours() + { + return $this->hours; + } + + /** + * @return array + */ + public function getDaysOfMonth() + { + return $this->dom; + } + + /** + * @return array + */ + public function getMonths() + { + return $this->months; + } + + /** + * @return array + */ + public function getDaysOfWeek() + { + return $this->dow; + } + + /** + * @param string|string[] $minutes + * @return $this + */ + public function setMinutes($minutes) + { + $this->minutes = $this->cronToArray($minutes, 0, 59); + + return $this; + } + + /** + * @param string|string[] $hours + * @return $this + */ + public function setHours($hours) + { + $this->hours = $this->cronToArray($hours, 0, 23); + + return $this; + } + + /** + * @param string|string[] $months + * @return $this + */ + public function setMonths($months) + { + $this->months = $this->cronToArray($months, 1, 12); + + return $this; + } + + /** + * @param string|string[] $dow + * @return $this + */ + public function setDaysOfWeek($dow) + { + $this->dow = $this->cronToArray($dow, 0, 7); + + return $this; + } + + /** + * @param string|string[] $dom + * @return $this + */ + public function setDaysOfMonth($dom) + { + $this->dom = $this->cronToArray($dom, 1, 31); + + return $this; + } + + /** + * @param mixed $date + * @param int $min + * @param int $hour + * @param int $day + * @param int $month + * @param int $weekday + * @return DateTime + */ + protected function parseDate($date, &$min, &$hour, &$day, &$month, &$weekday) + { + if (is_numeric($date) && (int)$date == $date) { + $date = new DateTime('@' . $date); + } elseif (is_string($date)) { + $date = new DateTime('@' . strtotime($date)); + } + if ($date instanceof DateTime) { + $min = (int)$date->format('i'); + $hour = (int)$date->format('H'); + $day = (int)$date->format('d'); + $month = (int)$date->format('m'); + $weekday = (int)$date->format('w'); // 0-6 + } else { + throw new RuntimeException('Date format not supported'); + } + + return new DateTime($date->format('Y-m-d H:i:sP')); + } + + /** + * @param int|string|DateTime $date + */ + public function matchExact($date) + { + $date = $this->parseDate($date, $min, $hour, $day, $month, $weekday); + + return + (empty($this->minutes) || in_array($min, $this->minutes, true)) && + (empty($this->hours) || in_array($hour, $this->hours, true)) && + (empty($this->dom) || in_array($day, $this->dom, true)) && + (empty($this->months) || in_array($month, $this->months, true)) && + (empty($this->dow) || in_array($weekday, $this->dow, true) || ($weekday == 0 && in_array(7, $this->dow, true)) || ($weekday == 7 && in_array(0, $this->dow, true)) + ); + } + + /** + * @param int|string|DateTime $date + * @param int $minuteBefore + * @param int $minuteAfter + */ + public function matchWithMargin($date, $minuteBefore = 0, $minuteAfter = 0) + { + if ($minuteBefore > 0) { + throw new RuntimeException('MinuteBefore parameter cannot be positive !'); + } + if ($minuteAfter < 0) { + throw new RuntimeException('MinuteAfter parameter cannot be negative !'); + } + + $date = $this->parseDate($date, $min, $hour, $day, $month, $weekday); + $interval = new DateInterval('PT1M'); // 1 min + if ($minuteBefore !== 0) { + $date->sub(new DateInterval('PT' . abs($minuteBefore) . 'M')); + } + $n = $minuteAfter - $minuteBefore + 1; + for ($i = 0; $i < $n; $i++) { + if ($this->matchExact($date)) { + return true; + } + $date->add($interval); + } + + return false; + } + + /** + * @param array $array + * @return string + */ + protected function arrayToCron($array) + { + $n = count($array); + if (!is_array($array) || $n === 0) { + return '*'; + } + + $cron = [$array[0]]; + $s = $c = $array[0]; + for ($i = 1; $i < $n; $i++) { + if ($array[$i] == $c + 1) { + $c = $array[$i]; + $cron[count($cron) - 1] = $s . '-' . $c; + } else { + $s = $c = $array[$i]; + $cron[] = $c; + } + } + + return implode(',', $cron); + } + + /** + * + * @param array|string $string + * @param int $min + * @param int $max + * @return array + */ + protected function cronToArray($string, $min, $max) + { + $array = []; + if (is_array($string)) { + foreach ($string as $val) { + if (is_numeric($val) && (int)$val == $val && $val >= $min && $val <= $max) { + $array[] = (int)$val; + } + } + } elseif ($string !== '*') { + while ($string !== '') { + // test "*/n" expression + if (preg_match('/^\*\/([0-9]+),?/', $string, $m)) { + for ($i = max(0, $min); $i <= min(59, $max); $i += $m[1]) { + $array[] = (int)$i; + } + $string = substr($string, strlen($m[0])); + continue; + } + // test "a-b/n" expression + if (preg_match('/^([0-9]+)-([0-9]+)\/([0-9]+),?/', $string, $m)) { + for ($i = max($m[1], $min); $i <= min($m[2], $max); $i += $m[3]) { + $array[] = (int)$i; + } + $string = substr($string, strlen($m[0])); + continue; + } + // test "a-b" expression + if (preg_match('/^([0-9]+)-([0-9]+),?/', $string, $m)) { + for ($i = max($m[1], $min); $i <= min($m[2], $max); $i++) { + $array[] = (int)$i; + } + $string = substr($string, strlen($m[0])); + continue; + } + // test "c" expression + if (preg_match('/^([0-9]+),?/', $string, $m)) { + if ($m[1] >= $min && $m[1] <= $max) { + $array[] = (int)$m[1]; + } + $string = substr($string, strlen($m[0])); + continue; + } + + // something goes wrong in the expression + return []; + } + } + sort($array, SORT_NUMERIC); + + return $array; + } +} diff --git a/system/src/Grav/Common/Scheduler/IntervalTrait.php b/system/src/Grav/Common/Scheduler/IntervalTrait.php new file mode 100644 index 0000000..edccec5 --- /dev/null +++ b/system/src/Grav/Common/Scheduler/IntervalTrait.php @@ -0,0 +1,404 @@ +at = $expression; + $this->executionTime = CronExpression::factory($expression); + + return $this; + } + + /** + * Set the execution time to every minute. + * + * @return self + */ + public function everyMinute() + { + return $this->at('* * * * *'); + } + + /** + * Set the execution time to every hour. + * + * @param int|string $minute + * @return self + */ + public function hourly($minute = 0) + { + $c = $this->validateCronSequence($minute); + + return $this->at("{$c['minute']} * * * *"); + } + + /** + * Set the execution time to once a day. + * + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function daily($hour = 0, $minute = 0) + { + if (is_string($hour)) { + $parts = explode(':', $hour); + $hour = $parts[0]; + $minute = $parts[1] ?? '0'; + } + $c = $this->validateCronSequence($minute, $hour); + + return $this->at("{$c['minute']} {$c['hour']} * * *"); + } + + /** + * Set the execution time to once a week. + * + * @param int|string $weekday + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function weekly($weekday = 0, $hour = 0, $minute = 0) + { + if (is_string($hour)) { + $parts = explode(':', $hour); + $hour = $parts[0]; + $minute = $parts[1] ?? '0'; + } + $c = $this->validateCronSequence($minute, $hour, null, null, $weekday); + + return $this->at("{$c['minute']} {$c['hour']} * * {$c['weekday']}"); + } + + /** + * Set the execution time to once a month. + * + * @param int|string $month + * @param int|string $day + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function monthly($month = '*', $day = 1, $hour = 0, $minute = 0) + { + if (is_string($hour)) { + $parts = explode(':', $hour); + $hour = $parts[0]; + $minute = $parts[1] ?? '0'; + } + $c = $this->validateCronSequence($minute, $hour, $day, $month); + + return $this->at("{$c['minute']} {$c['hour']} {$c['day']} {$c['month']} *"); + } + + /** + * Set the execution time to every Sunday. + * + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function sunday($hour = 0, $minute = 0) + { + return $this->weekly(0, $hour, $minute); + } + + /** + * Set the execution time to every Monday. + * + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function monday($hour = 0, $minute = 0) + { + return $this->weekly(1, $hour, $minute); + } + + /** + * Set the execution time to every Tuesday. + * + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function tuesday($hour = 0, $minute = 0) + { + return $this->weekly(2, $hour, $minute); + } + + /** + * Set the execution time to every Wednesday. + * + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function wednesday($hour = 0, $minute = 0) + { + return $this->weekly(3, $hour, $minute); + } + + /** + * Set the execution time to every Thursday. + * + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function thursday($hour = 0, $minute = 0) + { + return $this->weekly(4, $hour, $minute); + } + + /** + * Set the execution time to every Friday. + * + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function friday($hour = 0, $minute = 0) + { + return $this->weekly(5, $hour, $minute); + } + + /** + * Set the execution time to every Saturday. + * + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function saturday($hour = 0, $minute = 0) + { + return $this->weekly(6, $hour, $minute); + } + + /** + * Set the execution time to every January. + * + * @param int|string $day + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function january($day = 1, $hour = 0, $minute = 0) + { + return $this->monthly(1, $day, $hour, $minute); + } + + /** + * Set the execution time to every February. + * + * @param int|string $day + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function february($day = 1, $hour = 0, $minute = 0) + { + return $this->monthly(2, $day, $hour, $minute); + } + + /** + * Set the execution time to every March. + * + * @param int|string $day + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function march($day = 1, $hour = 0, $minute = 0) + { + return $this->monthly(3, $day, $hour, $minute); + } + + /** + * Set the execution time to every April. + * + * @param int|string $day + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function april($day = 1, $hour = 0, $minute = 0) + { + return $this->monthly(4, $day, $hour, $minute); + } + + /** + * Set the execution time to every May. + * + * @param int|string $day + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function may($day = 1, $hour = 0, $minute = 0) + { + return $this->monthly(5, $day, $hour, $minute); + } + + /** + * Set the execution time to every June. + * + * @param int|string $day + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function june($day = 1, $hour = 0, $minute = 0) + { + return $this->monthly(6, $day, $hour, $minute); + } + + /** + * Set the execution time to every July. + * + * @param int|string $day + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function july($day = 1, $hour = 0, $minute = 0) + { + return $this->monthly(7, $day, $hour, $minute); + } + + /** + * Set the execution time to every August. + * + * @param int|string $day + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function august($day = 1, $hour = 0, $minute = 0) + { + return $this->monthly(8, $day, $hour, $minute); + } + + /** + * Set the execution time to every September. + * + * @param int|string $day + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function september($day = 1, $hour = 0, $minute = 0) + { + return $this->monthly(9, $day, $hour, $minute); + } + + /** + * Set the execution time to every October. + * + * @param int|string $day + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function october($day = 1, $hour = 0, $minute = 0) + { + return $this->monthly(10, $day, $hour, $minute); + } + + /** + * Set the execution time to every November. + * + * @param int|string $day + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function november($day = 1, $hour = 0, $minute = 0) + { + return $this->monthly(11, $day, $hour, $minute); + } + + /** + * Set the execution time to every December. + * + * @param int|string $day + * @param int|string $hour + * @param int|string $minute + * @return self + */ + public function december($day = 1, $hour = 0, $minute = 0) + { + return $this->monthly(12, $day, $hour, $minute); + } + + /** + * Validate sequence of cron expression. + * + * @param int|string|null $minute + * @param int|string|null $hour + * @param int|string|null $day + * @param int|string|null $month + * @param int|string|null $weekday + * @return array + */ + private function validateCronSequence($minute = null, $hour = null, $day = null, $month = null, $weekday = null) + { + return [ + 'minute' => $this->validateCronRange($minute, 0, 59), + 'hour' => $this->validateCronRange($hour, 0, 23), + 'day' => $this->validateCronRange($day, 1, 31), + 'month' => $this->validateCronRange($month, 1, 12), + 'weekday' => $this->validateCronRange($weekday, 0, 6), + ]; + } + + /** + * Validate sequence of cron expression. + * + * @param int|string|null $value + * @param int $min + * @param int $max + * @return mixed + */ + private function validateCronRange($value, $min, $max) + { + if ($value === null || $value === '*') { + return '*'; + } + + if (! is_numeric($value) || + ! ($value >= $min && $value <= $max) + ) { + throw new InvalidArgumentException( + "Invalid value: it should be '*' or between {$min} and {$max}." + ); + } + + return $value; + } +} diff --git a/system/src/Grav/Common/Scheduler/Job.php b/system/src/Grav/Common/Scheduler/Job.php new file mode 100644 index 0000000..3b119f4 --- /dev/null +++ b/system/src/Grav/Common/Scheduler/Job.php @@ -0,0 +1,566 @@ +id = Grav::instance()['inflector']->hyphenize($id); + } else { + if (is_string($command)) { + $this->id = md5($command); + } else { + /* @var object $command */ + $this->id = spl_object_hash($command); + } + } + $this->creationTime = new DateTime('now'); + // initialize the directory path for lock files + $this->tempDir = sys_get_temp_dir(); + $this->command = $command; + $this->args = $args; + // Set enabled state + $status = Grav::instance()['config']->get('scheduler.status'); + $this->enabled = !(isset($status[$id]) && $status[$id] === 'disabled'); + } + + /** + * Get the command + * + * @return Closure|string + */ + public function getCommand() + { + return $this->command; + } + + /** + * Get the cron 'at' syntax for this job + * + * @return string + */ + public function getAt() + { + return $this->at; + } + + /** + * Get the status of this job + * + * @return bool + */ + public function getEnabled() + { + return $this->enabled; + } + + /** + * Get optional arguments + * + * @return string|null + */ + public function getArguments() + { + if (is_string($this->args)) { + return $this->args; + } + + return null; + } + + /** + * @return CronExpression + */ + public function getCronExpression() + { + return CronExpression::factory($this->at); + } + + /** + * Get the status of the last run for this job + * + * @return bool + */ + public function isSuccessful() + { + return $this->successful; + } + + /** + * Get the Job id. + * + * @return string + */ + public function getId() + { + return $this->id; + } + + /** + * Check if the Job is due to run. + * It accepts as input a DateTime used to check if + * the job is due. Defaults to job creation time. + * It also default the execution time if not previously defined. + * + * @param DateTime|null $date + * @return bool + */ + public function isDue(DateTime $date = null) + { + // The execution time is being defaulted if not defined + if (!$this->executionTime) { + $this->at('* * * * *'); + } + + $date = $date ?? $this->creationTime; + + return $this->executionTime->isDue($date); + } + + /** + * Check if the Job is overlapping. + * + * @return bool + */ + public function isOverlapping() + { + return $this->lockFile && + file_exists($this->lockFile) && + call_user_func($this->whenOverlapping, filemtime($this->lockFile)) === false; + } + + /** + * Force the Job to run in foreground. + * + * @return $this + */ + public function inForeground() + { + $this->runInBackground = false; + + return $this; + } + + /** + * Sets/Gets an option backlink + * + * @param string|null $link + * @return string|null + */ + public function backlink($link = null) + { + if ($link) { + $this->backlink = $link; + } + return $this->backlink; + } + + + /** + * Check if the Job can run in background. + * + * @return bool + */ + public function runInBackground() + { + return !(is_callable($this->command) || $this->runInBackground === false); + } + + /** + * This will prevent the Job from overlapping. + * It prevents another instance of the same Job of + * being executed if the previous is still running. + * The job id is used as a filename for the lock file. + * + * @param string|null $tempDir The directory path for the lock files + * @param callable|null $whenOverlapping A callback to ignore job overlapping + * @return self + */ + public function onlyOne($tempDir = null, callable $whenOverlapping = null) + { + if ($tempDir === null || !is_dir($tempDir)) { + $tempDir = $this->tempDir; + } + $this->lockFile = implode('/', [ + trim($tempDir), + trim($this->id) . '.lock', + ]); + if ($whenOverlapping) { + $this->whenOverlapping = $whenOverlapping; + } else { + $this->whenOverlapping = static function () { + return false; + }; + } + + return $this; + } + + /** + * Configure the job. + * + * @param array $config + * @return self + */ + public function configure(array $config = []) + { + // Check if config has defined a tempDir + if (isset($config['tempDir']) && is_dir($config['tempDir'])) { + $this->tempDir = $config['tempDir']; + } + + return $this; + } + + /** + * Truth test to define if the job should run if due. + * + * @param callable $fn + * @return self + */ + public function when(callable $fn) + { + $this->truthTest = $fn(); + + return $this; + } + + /** + * Run the job. + * + * @return bool + */ + public function run() + { + // If the truthTest failed, don't run + if ($this->truthTest !== true) { + return false; + } + + // If overlapping, don't run + if ($this->isOverlapping()) { + return false; + } + + // Write lock file if necessary + $this->createLockFile(); + + // Call before if required + if (is_callable($this->before)) { + call_user_func($this->before); + } + + // If command is callable... + if (is_callable($this->command)) { + $this->output = $this->exec(); + } else { + $args = is_string($this->args) ? explode(' ', $this->args) : $this->args; + $command = array_merge([$this->command], $args); + $process = new Process($command); + + $this->process = $process; + + if ($this->runInBackground()) { + $process->start(); + } else { + $process->run(); + $this->finalize(); + } + } + + return true; + } + + /** + * Finish up processing the job + * + * @return void + */ + public function finalize() + { + $process = $this->process; + + if ($process) { + $process->wait(); + + if ($process->isSuccessful()) { + $this->successful = true; + $this->output = $process->getOutput(); + } else { + $this->successful = false; + $this->output = $process->getErrorOutput(); + } + + $this->postRun(); + + unset($this->process); + } + } + + /** + * Things to run after job has run + * + * @return void + */ + private function postRun() + { + if (count($this->outputTo) > 0) { + foreach ($this->outputTo as $file) { + $output_mode = $this->outputMode === 'append' ? FILE_APPEND | LOCK_EX : LOCK_EX; + $timestamp = (new DateTime('now'))->format('c'); + $output = $timestamp . "\n" . str_pad('', strlen($timestamp), '>') . "\n" . $this->output; + file_put_contents($file, $output, $output_mode); + } + } + + // Send output to email + $this->emailOutput(); + + // Call any callback defined + if (is_callable($this->after)) { + call_user_func($this->after, $this->output, $this->returnCode); + } + + $this->removeLockFile(); + } + + /** + * Create the job lock file. + * + * @param mixed $content + * @return void + */ + private function createLockFile($content = null) + { + if ($this->lockFile) { + if ($content === null || !is_string($content)) { + $content = $this->getId(); + } + file_put_contents($this->lockFile, $content); + } + } + + /** + * Remove the job lock file. + * + * @return void + */ + private function removeLockFile() + { + if ($this->lockFile && file_exists($this->lockFile)) { + unlink($this->lockFile); + } + } + + /** + * Execute a callable job. + * + * @return string + * @throws RuntimeException + */ + private function exec() + { + $return_data = ''; + ob_start(); + try { + $return_data = call_user_func_array($this->command, $this->args); + $this->successful = true; + } catch (RuntimeException $e) { + $return_data = $e->getMessage(); + $this->successful = false; + } + $this->output = ob_get_clean() . (is_string($return_data) ? $return_data : ''); + + $this->postRun(); + + return $this->output; + } + + /** + * Set the file/s where to write the output of the job. + * + * @param string|array $filename + * @param bool $append + * @return self + */ + public function output($filename, $append = false) + { + $this->outputTo = is_array($filename) ? $filename : [$filename]; + $this->outputMode = $append === false ? 'overwrite' : 'append'; + + return $this; + } + + /** + * Get the job output. + * + * @return mixed + */ + public function getOutput() + { + return $this->output; + } + + /** + * Set the emails where the output should be sent to. + * The Job should be set to write output to a file + * for this to work. + * + * @param string|array $email + * @return self + */ + public function email($email) + { + if (!is_string($email) && !is_array($email)) { + throw new InvalidArgumentException('The email can be only string or array'); + } + + $this->emailTo = is_array($email) ? $email : [$email]; + // Force the job to run in foreground + $this->inForeground(); + + return $this; + } + + /** + * Email the output of the job, if any. + * + * @return bool + */ + private function emailOutput() + { + if (!count($this->outputTo) || !count($this->emailTo)) { + return false; + } + + if (is_callable('Grav\Plugin\Email\Utils::sendEmail')) { + $subject ='Grav Scheduled Job [' . $this->getId() . ']'; + $content = "

Output from Job ID: {$this->getId()}

\n

Command: {$this->getCommand()}


\n".$this->getOutput()."\n
"; + $to = $this->emailTo; + + \Grav\Plugin\Email\Utils::sendEmail($subject, $content, $to); + } + + return true; + } + + /** + * Set function to be called before job execution + * Job object is injected as a parameter to callable function. + * + * @param callable $fn + * @return self + */ + public function before(callable $fn) + { + $this->before = $fn; + + return $this; + } + + /** + * Set a function to be called after job execution. + * By default this will force the job to run in foreground + * because the output is injected as a parameter of this + * function, but it could be avoided by passing true as a + * second parameter. The job will run in background if it + * meets all the other criteria. + * + * @param callable $fn + * @param bool $runInBackground + * @return self + */ + public function then(callable $fn, $runInBackground = false) + { + $this->after = $fn; + // Force the job to run in foreground + if ($runInBackground === false) { + $this->inForeground(); + } + + return $this; + } +} diff --git a/system/src/Grav/Common/Scheduler/Scheduler.php b/system/src/Grav/Common/Scheduler/Scheduler.php new file mode 100644 index 0000000..d3cefb0 --- /dev/null +++ b/system/src/Grav/Common/Scheduler/Scheduler.php @@ -0,0 +1,447 @@ +get('scheduler.defaults', []); + $this->config = $config; + + $this->status_path = Grav::instance()['locator']->findResource('user-data://scheduler', true, true); + if (!file_exists($this->status_path)) { + Folder::create($this->status_path); + } + } + + /** + * Load saved jobs from config/scheduler.yaml file + * + * @return $this + */ + public function loadSavedJobs() + { + $this->saved_jobs = []; + $saved_jobs = (array) Grav::instance()['config']->get('scheduler.custom_jobs', []); + + foreach ($saved_jobs as $id => $j) { + $args = $j['args'] ?? []; + $id = Grav::instance()['inflector']->hyphenize($id); + $job = $this->addCommand($j['command'], $args, $id); + + if (isset($j['at'])) { + $job->at($j['at']); + } + + if (isset($j['output'])) { + $mode = isset($j['output_mode']) && $j['output_mode'] === 'append'; + $job->output($j['output'], $mode); + } + + if (isset($j['email'])) { + $job->email($j['email']); + } + + // store in saved_jobs + $this->saved_jobs[] = $job; + } + + return $this; + } + + /** + * Get the queued jobs as background/foreground + * + * @param bool $all + * @return array + */ + public function getQueuedJobs($all = false) + { + $background = []; + $foreground = []; + foreach ($this->jobs as $job) { + if ($all || $job->getEnabled()) { + if ($job->runInBackground()) { + $background[] = $job; + } else { + $foreground[] = $job; + } + } + } + return [$background, $foreground]; + } + + /** + * Get all jobs if they are disabled or not as one array + * + * @return Job[] + */ + public function getAllJobs() + { + [$background, $foreground] = $this->loadSavedJobs()->getQueuedJobs(true); + + return array_merge($background, $foreground); + } + + /** + * Get a specific Job based on id + * + * @param string $jobid + * @return Job|null + */ + public function getJob($jobid) + { + $all = $this->getAllJobs(); + foreach ($all as $job) { + if ($jobid == $job->getId()) { + return $job; + } + } + return null; + } + + /** + * Queues a PHP function execution. + * + * @param callable $fn The function to execute + * @param array $args Optional arguments to pass to the php script + * @param string|null $id Optional custom identifier + * @return Job + */ + public function addFunction(callable $fn, $args = [], $id = null) + { + $job = new Job($fn, $args, $id); + $this->queueJob($job->configure($this->config)); + + return $job; + } + + /** + * Queue a raw shell command. + * + * @param string $command The command to execute + * @param array $args Optional arguments to pass to the command + * @param string|null $id Optional custom identifier + * @return Job + */ + public function addCommand($command, $args = [], $id = null) + { + $job = new Job($command, $args, $id); + $this->queueJob($job->configure($this->config)); + + return $job; + } + + /** + * Run the scheduler. + * + * @param DateTime|null $runTime Optional, run at specific moment + * @param bool $force force run even if not due + */ + public function run(DateTime $runTime = null, $force = false) + { + $this->loadSavedJobs(); + + [$background, $foreground] = $this->getQueuedJobs(false); + $alljobs = array_merge($background, $foreground); + + if (null === $runTime) { + $runTime = new DateTime('now'); + } + + // Star processing jobs + foreach ($alljobs as $job) { + if ($job->isDue($runTime) || $force) { + $job->run(); + $this->jobs_run[] = $job; + } + } + + // Finish handling any background jobs + foreach ($background as $job) { + $job->finalize(); + } + + // Store states + $this->saveJobStates(); + + // Store run date + file_put_contents("logs/lastcron.run", (new DateTime("now"))->format("Y-m-d H:i:s"), LOCK_EX); + } + + /** + * Reset all collected data of last run. + * + * Call before run() if you call run() multiple times. + * + * @return $this + */ + public function resetRun() + { + // Reset collected data of last run + $this->executed_jobs = []; + $this->failed_jobs = []; + $this->output_schedule = []; + + return $this; + } + + /** + * Get the scheduler verbose output. + * + * @param string $type Allowed: text, html, array + * @return string|array The return depends on the requested $type + */ + public function getVerboseOutput($type = 'text') + { + switch ($type) { + case 'text': + return implode("\n", $this->output_schedule); + case 'html': + return implode('
', $this->output_schedule); + case 'array': + return $this->output_schedule; + default: + throw new InvalidArgumentException('Invalid output type'); + } + } + + /** + * Remove all queued Jobs. + * + * @return $this + */ + public function clearJobs() + { + $this->jobs = []; + + return $this; + } + + /** + * Helper to get the full Cron command + * + * @return string + */ + public function getCronCommand() + { + $command = $this->getSchedulerCommand(); + + return "(crontab -l; echo \"* * * * * {$command} 1>> /dev/null 2>&1\") | crontab -"; + } + + /** + * @param string|null $php + * @return string + */ + public function getSchedulerCommand($php = null) + { + $phpBinaryFinder = new PhpExecutableFinder(); + $php = $php ?? $phpBinaryFinder->find(); + $command = 'cd ' . str_replace(' ', '\ ', GRAV_ROOT) . ';' . $php . ' bin/grav scheduler'; + + return $command; + } + + /** + * Helper to determine if cron-like job is setup + * 0 - Crontab Not found + * 1 - Crontab Found + * 2 - Error + * + * @return int + */ + public function isCrontabSetup() + { + // Check for external triggers + $last_run = @file_get_contents("logs/lastcron.run"); + if (time() - strtotime($last_run) < 120){ + return 1; + } + + // No external triggers found, so do legacy cron checks + $process = new Process(['crontab', '-l']); + $process->run(); + + if ($process->isSuccessful()) { + $output = $process->getOutput(); + $command = str_replace('/', '\/', $this->getSchedulerCommand('.*')); + $full_command = '/^(?!#).* .* .* .* .* ' . $command . '/m'; + + return preg_match($full_command, $output) ? 1 : 0; + } + + $error = $process->getErrorOutput(); + + return Utils::startsWith($error, 'crontab: no crontab') ? 0 : 2; + } + + /** + * Get the Job states file + * + * @return YamlFile + */ + public function getJobStates() + { + return YamlFile::instance($this->status_path . '/status.yaml'); + } + + /** + * Save job states to statys file + * + * @return void + */ + private function saveJobStates() + { + $now = time(); + $new_states = []; + + foreach ($this->jobs_run as $job) { + if ($job->isSuccessful()) { + $new_states[$job->getId()] = ['state' => 'success', 'last-run' => $now]; + $this->pushExecutedJob($job); + } else { + $new_states[$job->getId()] = ['state' => 'failure', 'last-run' => $now, 'error' => $job->getOutput()]; + $this->pushFailedJob($job); + } + } + + $saved_states = $this->getJobStates(); + $saved_states->save(array_merge($saved_states->content(), $new_states)); + } + + /** + * Try to determine who's running the process + * + * @return false|string + */ + public function whoami() + { + $process = new Process(['whoami']); + $process->run(); + + if ($process->isSuccessful()) { + return trim($process->getOutput()); + } + + return $process->getErrorOutput(); + } + + + /** + * Queue a job for execution in the correct queue. + * + * @param Job $job + * @return void + */ + private function queueJob(Job $job) + { + $this->jobs[] = $job; + + // Store jobs + } + + /** + * Add an entry to the scheduler verbose output array. + * + * @param string $string + * @return void + */ + private function addSchedulerVerboseOutput($string) + { + $now = '[' . (new DateTime('now'))->format('c') . '] '; + $this->output_schedule[] = $now . $string; + // Print to stdoutput in light gray + // echo "\033[37m{$string}\033[0m\n"; + } + + /** + * Push a succesfully executed job. + * + * @param Job $job + * @return Job + */ + private function pushExecutedJob(Job $job) + { + $this->executed_jobs[] = $job; + $command = $job->getCommand(); + $args = $job->getArguments(); + // If callable, log the string Closure + if (is_callable($command)) { + $command = is_string($command) ? $command : 'Closure'; + } + $this->addSchedulerVerboseOutput("Success: {$command} {$args}"); + + return $job; + } + + /** + * Push a failed job. + * + * @param Job $job + * @return Job + */ + private function pushFailedJob(Job $job) + { + $this->failed_jobs[] = $job; + $command = $job->getCommand(); + // If callable, log the string Closure + if (is_callable($command)) { + $command = is_string($command) ? $command : 'Closure'; + } + $output = trim($job->getOutput()); + $this->addSchedulerVerboseOutput("Error: {$command}{$output}"); + + return $job; + } +} diff --git a/system/src/Grav/Common/Security.php b/system/src/Grav/Common/Security.php new file mode 100644 index 0000000..6fabf4e --- /dev/null +++ b/system/src/Grav/Common/Security.php @@ -0,0 +1,287 @@ +get('security.sanitize_svg')) { + $content = file_get_contents($filepath); + + return static::detectXss($content, $options); + } + + return null; + } + + /** + * Sanitize SVG string for XSS code + * + * @param string $svg + * @return string + */ + public static function sanitizeSvgString(string $svg): string + { + if (Grav::instance()['config']->get('security.sanitize_svg')) { + $sanitizer = new DOMSanitizer(DOMSanitizer::SVG); + $sanitized = $sanitizer->sanitize($svg); + if (is_string($sanitized)) { + $svg = $sanitized; + } + } + + return $svg; + } + + /** + * Sanitize SVG for XSS code + * + * @param string $file + * @return void + */ + public static function sanitizeSVG(string $file): void + { + if (file_exists($file) && Grav::instance()['config']->get('security.sanitize_svg')) { + $sanitizer = new DOMSanitizer(DOMSanitizer::SVG); + $original_svg = file_get_contents($file); + $clean_svg = $sanitizer->sanitize($original_svg); + + // Quarantine bad SVG files and throw exception + if ($clean_svg !== false ) { + file_put_contents($file, $clean_svg); + } else { + $quarantine_file = Utils::basename($file); + $quarantine_dir = 'log://quarantine'; + Folder::mkdir($quarantine_dir); + file_put_contents("$quarantine_dir/$quarantine_file", $original_svg); + unlink($file); + throw new Exception('SVG could not be sanitized, it has been moved to the logs/quarantine folder'); + } + } + } + + /** + * Detect XSS code in Grav pages + * + * @param Pages $pages + * @param bool $route + * @param callable|null $status + * @return array + */ + public static function detectXssFromPages(Pages $pages, $route = true, callable $status = null) + { + $routes = $pages->getList(null, 0, true); + + // Remove duplicate for homepage + unset($routes['/']); + + $list = []; + + // This needs Symfony 4.1 to work + $status && $status([ + 'type' => 'count', + 'steps' => count($routes), + ]); + + foreach (array_keys($routes) as $route) { + $status && $status([ + 'type' => 'progress', + ]); + + try { + $page = $pages->find($route); + if ($page->exists()) { + // call the content to load/cache it + $header = (array) $page->header(); + $content = $page->value('content'); + + $data = ['header' => $header, 'content' => $content]; + $results = static::detectXssFromArray($data); + + if (!empty($results)) { + $list[$page->rawRoute()] = $results; + } + } + } catch (Exception $e) { + continue; + } + } + + return $list; + } + + /** + * Detect XSS in an array or strings such as $_POST or $_GET + * + * @param array $array Array such as $_POST or $_GET + * @param array|null $options Extra options to be passed. + * @param string $prefix Prefix for returned values. + * @return array Returns flatten list of potentially dangerous input values, such as 'data.content'. + */ + public static function detectXssFromArray(array $array, string $prefix = '', array $options = null) + { + if (null === $options) { + $options = static::getXssDefaults(); + } + + $list = [[]]; + foreach ($array as $key => $value) { + if (is_array($value)) { + $list[] = static::detectXssFromArray($value, $prefix . $key . '.', $options); + } + if ($result = static::detectXss($value, $options)) { + $list[] = [$prefix . $key => $result]; + } + } + + return array_merge(...$list); + } + + /** + * Determine if string potentially has a XSS attack. This simple function does not catch all XSS and it is likely to + * + * return false positives because of it tags all potentially dangerous HTML tags and attributes without looking into + * their content. + * + * @param string|null $string The string to run XSS detection logic on + * @param array|null $options + * @return string|null Type of XSS vector if the given `$string` may contain XSS, false otherwise. + * + * Copies the code from: https://github.com/symphonycms/xssfilter/blob/master/extension.driver.php#L138 + */ + public static function detectXss($string, array $options = null): ?string + { + // Skip any null or non string values + if (null === $string || !is_string($string) || empty($string)) { + return null; + } + + if (null === $options) { + $options = static::getXssDefaults(); + } + + $enabled_rules = (array)($options['enabled_rules'] ?? null); + $dangerous_tags = (array)($options['dangerous_tags'] ?? null); + if (!$dangerous_tags) { + $enabled_rules['dangerous_tags'] = false; + } + $invalid_protocols = (array)($options['invalid_protocols'] ?? null); + if (!$invalid_protocols) { + $enabled_rules['invalid_protocols'] = false; + } + $enabled_rules = array_filter($enabled_rules, static function ($val) { return !empty($val); }); + if (!$enabled_rules) { + return null; + } + + // Keep a copy of the original string before cleaning up + $orig = $string; + + // URL decode + $string = urldecode($string); + + // Convert Hexadecimals + $string = (string)preg_replace_callback('!(&#|\\\)[xX]([0-9a-fA-F]+);?!u', static function ($m) { + return chr(hexdec($m[2])); + }, $string); + + // Clean up entities + $string = preg_replace('!(&#[0-9]+);?!u', '$1;', $string); + + // Decode entities + $string = html_entity_decode($string, ENT_NOQUOTES | ENT_HTML5, 'UTF-8'); + + // Strip whitespace characters + $string = preg_replace('!\s!u', ' ', $string); + $stripped = preg_replace('!\s!u', '', $string); + + // Set the patterns we'll test against + $patterns = [ + // Match any attribute starting with "on" or xmlns + 'on_events' => '#(<[^>]+[a-z\x00-\x20\"\'\/])(on[a-z]+|xmlns)\s*=[\s|\'\"].*[\s|\'\"]>#iUu', + + // Match javascript:, livescript:, vbscript:, mocha:, feed: and data: protocols + 'invalid_protocols' => '#(' . implode('|', array_map('preg_quote', $invalid_protocols, ['#'])) . ')(:|\&\#58)\S.*?#iUu', + + // Match -moz-bindings + 'moz_binding' => '#-moz-binding[a-z\x00-\x20]*:#u', + + // Match style attributes + 'html_inline_styles' => '#(<[^>]+[a-z\x00-\x20\"\'\/])(style=[^>]*(url\:|x\:expression).*)>?#iUu', + + // Match potentially dangerous tags + 'dangerous_tags' => '#]*>?#ui' + ]; + + // Iterate over rules and return label if fail + foreach ($patterns as $name => $regex) { + if (!empty($enabled_rules[$name])) { + if (preg_match($regex, $string) || preg_match($regex, $stripped) || preg_match($regex, $orig)) { + return $name; + } + } + } + + return null; + } + + public static function getXssDefaults(): array + { + /** @var Config $config */ + $config = Grav::instance()['config']; + + return [ + 'enabled_rules' => $config->get('security.xss_enabled'), + 'dangerous_tags' => array_map('trim', $config->get('security.xss_dangerous_tags')), + 'invalid_protocols' => array_map('trim', $config->get('security.xss_invalid_protocols')), + ]; + } + + public static function cleanDangerousTwig(string $string): string + { + if ($string === '') { + return $string; + } + + $bad_twig = [ + 'twig_array_map', + 'twig_array_filter', + 'call_user_func', + 'registerUndefinedFunctionCallback', + 'undefined_functions', + 'twig.getFunction', + 'core.setEscaper', + 'twig.safe_functions', + 'read_file', + ]; + $string = preg_replace('/(({{\s*|{%\s*)[^}]*?(' . implode('|', $bad_twig) . ')[^}]*?(\s*}}|\s*%}))/i', '{# $1 #}', $string); + return $string; + } +} diff --git a/system/src/Grav/Common/Service/AccountsServiceProvider.php b/system/src/Grav/Common/Service/AccountsServiceProvider.php new file mode 100644 index 0000000..d0e0e68 --- /dev/null +++ b/system/src/Grav/Common/Service/AccountsServiceProvider.php @@ -0,0 +1,157 @@ +addTypes($config->get('permissions.types', [])); + + $array = $config->get('permissions.actions'); + if (is_array($array)) { + $actions = PermissionsReader::fromArray($array, $permissions->getTypes()); + $permissions->addActions($actions); + } + + $event = new PermissionsRegisterEvent($permissions); + $container->dispatchEvent($event); + + return $permissions; + }; + + $container['accounts'] = function (Container $container) { + $type = $this->initialize($container); + + return $type === 'flex' ? $this->flexAccounts($container) : $this->regularAccounts($container); + }; + + $container['user_groups'] = static function (Container $container) { + /** @var Flex $flex */ + $flex = $container['flex']; + $directory = $flex->getDirectory('user-groups'); + + return $directory ? $directory->getIndex() : null; + }; + + $container['users'] = $container->factory(static function (Container $container) { + user_error('Grav::instance()[\'users\'] is deprecated since Grav 1.6, use Grav::instance()[\'accounts\'] instead', E_USER_DEPRECATED); + + return $container['accounts']; + }); + } + + /** + * @param Container $container + * @return string + */ + protected function initialize(Container $container): string + { + $isDefined = defined('GRAV_USER_INSTANCE'); + $type = strtolower($isDefined ? GRAV_USER_INSTANCE : $container['config']->get('system.accounts.type', 'regular')); + + if ($type === 'flex') { + if (!$isDefined) { + define('GRAV_USER_INSTANCE', 'FLEX'); + } + + /** @var EventDispatcher $dispatcher */ + $dispatcher = $container['events']; + + // Stop /admin/user from working, display error instead. + $dispatcher->addListener( + 'onAdminPage', + static function (Event $event) { + $grav = Grav::instance(); + $admin = $grav['admin']; + [$base,$location,] = $admin->getRouteDetails(); + if ($location !== 'user' || isset($grav['flex_objects'])) { + return; + } + + /** @var PageInterface $page */ + $page = $event['page']; + $page->init(new SplFileInfo('plugin://admin/pages/admin/error.md')); + $page->routable(true); + $header = $page->header(); + $header->title = 'Please install missing plugin'; + $page->content("## Please install and enable **[Flex Objects]({$base}/plugins/flex-objects)** plugin. It is required to edit **Flex User Accounts**."); + + /** @var Header $header */ + $header = $page->header(); + $directory = $grav['accounts']->getFlexDirectory(); + $menu = $directory->getConfig('admin.menu.list'); + $header->access = $menu['authorize'] ?? ['admin.super']; + }, + 100000 + ); + } elseif (!$isDefined) { + define('GRAV_USER_INSTANCE', 'REGULAR'); + } + + return $type; + } + + /** + * @param Container $container + * @return DataUser\UserCollection + */ + protected function regularAccounts(Container $container) + { + // Use User class for backwards compatibility. + return new DataUser\UserCollection(User::class); + } + + /** + * @param Container $container + * @return FlexIndexInterface|null + */ + protected function flexAccounts(Container $container) + { + /** @var Flex $flex */ + $flex = $container['flex']; + $directory = $flex->getDirectory('user-accounts'); + + return $directory ? $directory->getIndex() : null; + } +} diff --git a/system/src/Grav/Common/Service/AssetsServiceProvider.php b/system/src/Grav/Common/Service/AssetsServiceProvider.php new file mode 100644 index 0000000..54bb2f4 --- /dev/null +++ b/system/src/Grav/Common/Service/AssetsServiceProvider.php @@ -0,0 +1,32 @@ +setup(); + + return $backups; + }; + } +} diff --git a/system/src/Grav/Common/Service/ConfigServiceProvider.php b/system/src/Grav/Common/Service/ConfigServiceProvider.php new file mode 100644 index 0000000..6f0ffae --- /dev/null +++ b/system/src/Grav/Common/Service/ConfigServiceProvider.php @@ -0,0 +1,206 @@ +init(); + + return $setup; + }; + + $container['blueprints'] = function ($c) { + return static::blueprints($c); + }; + + $container['config'] = function ($c) { + $config = static::load($c); + + // After configuration has been loaded, we can disable YAML compatibility if strict mode has been enabled. + if (!$config->get('system.strict_mode.yaml_compat', true)) { + YamlFile::globalSettings(['compat' => false, 'native' => true]); + } + + return $config; + }; + + $container['mime'] = function ($c) { + /** @var Config $config */ + $config = $c['config']; + $mimes = $config->get('mime.types', []); + foreach ($config->get('media.types', []) as $ext => $media) { + if (!empty($media['mime'])) { + $mimes[$ext] = array_unique(array_merge([$media['mime']], $mimes[$ext] ?? [])); + } + } + + return MimeTypes::createFromMimes($mimes); + }; + + $container['languages'] = function ($c) { + return static::languages($c); + }; + + $container['language'] = function ($c) { + return new Language($c); + }; + } + + /** + * @param Container $container + * @return mixed + */ + public static function blueprints(Container $container) + { + /** Setup $setup */ + $setup = $container['setup']; + + /** @var UniformResourceLocator $locator */ + $locator = $container['locator']; + + $cache = $locator->findResource('cache://compiled/blueprints', true, true); + + $files = []; + $paths = $locator->findResources('blueprints://config'); + $files += (new ConfigFileFinder)->locateFiles($paths); + $paths = $locator->findResources('plugins://'); + $files += (new ConfigFileFinder)->setBase('plugins')->locateInFolders($paths, 'blueprints'); + $paths = $locator->findResources('themes://'); + $files += (new ConfigFileFinder)->setBase('themes')->locateInFolders($paths, 'blueprints'); + + $blueprints = new CompiledBlueprints($cache, $files, GRAV_ROOT); + + return $blueprints->name("master-{$setup->environment}")->load(); + } + + /** + * @param Container $container + * @return Config + */ + public static function load(Container $container) + { + /** Setup $setup */ + $setup = $container['setup']; + + /** @var UniformResourceLocator $locator */ + $locator = $container['locator']; + + $cache = $locator->findResource('cache://compiled/config', true, true); + + $files = []; + $paths = $locator->findResources('config://'); + $files += (new ConfigFileFinder)->locateFiles($paths); + $paths = $locator->findResources('plugins://'); + $files += (new ConfigFileFinder)->setBase('plugins')->locateInFolders($paths); + $paths = $locator->findResources('themes://'); + $files += (new ConfigFileFinder)->setBase('themes')->locateInFolders($paths); + + $compiled = new CompiledConfig($cache, $files, GRAV_ROOT); + $compiled->setBlueprints(function () use ($container) { + return $container['blueprints']; + }); + + $config = $compiled->name("master-{$setup->environment}")->load(); + $config->environment = $setup->environment; + + return $config; + } + + /** + * @param Container $container + * @return mixed + */ + public static function languages(Container $container) + { + /** @var Setup $setup */ + $setup = $container['setup']; + + /** @var Config $config */ + $config = $container['config']; + + /** @var UniformResourceLocator $locator */ + $locator = $container['locator']; + + $cache = $locator->findResource('cache://compiled/languages', true, true); + $files = []; + + // Process languages only if enabled in configuration. + if ($config->get('system.languages.translations', true)) { + $paths = $locator->findResources('languages://'); + $files += (new ConfigFileFinder)->locateFiles($paths); + $paths = $locator->findResources('plugins://'); + $files += (new ConfigFileFinder)->setBase('plugins')->locateInFolders($paths, 'languages'); + $paths = static::pluginFolderPaths($paths, 'languages'); + $files += (new ConfigFileFinder)->locateFiles($paths); + } + + $languages = new CompiledLanguages($cache, $files, GRAV_ROOT); + + return $languages->name("master-{$setup->environment}")->load(); + } + + /** + * Find specific paths in plugins + * + * @param array $plugins + * @param string $folder_path + * @return array + */ + protected static function pluginFolderPaths($plugins, $folder_path) + { + $paths = []; + + foreach ($plugins as $path) { + $iterator = new DirectoryIterator($path); + + /** @var DirectoryIterator $directory */ + foreach ($iterator as $directory) { + if (!$directory->isDir() || $directory->isDot()) { + continue; + } + + // Path to the languages folder + $lang_path = $directory->getPathName() . '/' . $folder_path; + + // If this folder exists, add it to the list of paths + if (file_exists($lang_path)) { + $paths []= $lang_path; + } + } + } + return $paths; + } +} diff --git a/system/src/Grav/Common/Service/ErrorServiceProvider.php b/system/src/Grav/Common/Service/ErrorServiceProvider.php new file mode 100644 index 0000000..6f6f568 --- /dev/null +++ b/system/src/Grav/Common/Service/ErrorServiceProvider.php @@ -0,0 +1,30 @@ + $config->get('system.flex', [])]); + FlexFormFlash::setFlex($flex); + + $accountsEnabled = $config->get('system.accounts.type', 'regular') === 'flex'; + $pagesEnabled = $config->get('system.pages.type', 'regular') === 'flex'; + + // Add built-in types from Grav. + if ($pagesEnabled) { + $flex->addDirectoryType( + 'pages', + 'blueprints://flex/pages.yaml', + [ + 'enabled' => $pagesEnabled + ] + ); + } + if ($accountsEnabled) { + $flex->addDirectoryType( + 'user-accounts', + 'blueprints://flex/user-accounts.yaml', + [ + 'enabled' => $accountsEnabled, + 'data' => [ + 'storage' => $this->getFlexAccountsStorage($config), + ] + ] + ); + $flex->addDirectoryType( + 'user-groups', + 'blueprints://flex/user-groups.yaml', + [ + 'enabled' => $accountsEnabled + ] + ); + } + + // Call event to register Flex Directories. + $event = new FlexRegisterEvent($flex); + $container->dispatchEvent($event); + + return $flex; + }; + } + + /** + * @param Config $config + * @return array + */ + private function getFlexAccountsStorage(Config $config): array + { + $value = $config->get('system.accounts.storage', 'file'); + if (is_array($value)) { + return $value; + } + + if ($value === 'folder') { + return [ + 'class' => UserFolderStorage::class, + 'options' => [ + 'file' => 'user', + 'pattern' => '{FOLDER}/{KEY:2}/{KEY}/{FILE}{EXT}', + 'key' => 'storage_key', + 'indexed' => true, + 'case_sensitive' => false + ], + ]; + } + + if ($value === 'file') { + return [ + 'class' => UserFileStorage::class, + 'options' => [ + 'pattern' => '{FOLDER}/{KEY}{EXT}', + 'key' => 'username', + 'indexed' => true, + 'case_sensitive' => false + ], + ]; + } + + return []; + } +} diff --git a/system/src/Grav/Common/Service/InflectorServiceProvider.php b/system/src/Grav/Common/Service/InflectorServiceProvider.php new file mode 100644 index 0000000..fcb49aa --- /dev/null +++ b/system/src/Grav/Common/Service/InflectorServiceProvider.php @@ -0,0 +1,32 @@ +findResource('log://grav.log', true, true); + $log->pushHandler(new StreamHandler($log_file, Logger::DEBUG)); + + return $log; + }; + } +} diff --git a/system/src/Grav/Common/Service/OutputServiceProvider.php b/system/src/Grav/Common/Service/OutputServiceProvider.php new file mode 100644 index 0000000..91f507b --- /dev/null +++ b/system/src/Grav/Common/Service/OutputServiceProvider.php @@ -0,0 +1,39 @@ +processSite($page->templateFormat()); + }; + } +} diff --git a/system/src/Grav/Common/Service/PagesServiceProvider.php b/system/src/Grav/Common/Service/PagesServiceProvider.php new file mode 100644 index 0000000..dd1be13 --- /dev/null +++ b/system/src/Grav/Common/Service/PagesServiceProvider.php @@ -0,0 +1,140 @@ +findResource('system://pages/notfound.md'); + $page = new Page(); + $page->init(new SplFileInfo($path)); + $page->routable(false); + + return $page; + }; + + return; + } + + $container['page'] = static function (Grav $grav) { + /** @var Pages $pages */ + $pages = $grav['pages']; + + /** @var Config $config */ + $config = $grav['config']; + + /** @var Uri $uri */ + $uri = $grav['uri']; + + $path = $uri->path() ? urldecode($uri->path()) : '/'; // Don't trim to support trailing slash default routes + $page = $pages->dispatch($path); + + // Redirection tests + if ($page) { + // some debugger override logic + if ($page->debugger() === false) { + $grav['debugger']->enabled(false); + } + + if ($config->get('system.force_ssl')) { + $scheme = $uri->scheme(true); + if ($scheme !== 'https') { + $url = 'https://' . $uri->host() . $uri->uri(); + $grav->redirect($url); + } + } + + $route = $page->route(); + if ($route && \in_array($uri->method(), ['GET', 'HEAD'], true)) { + $pageExtension = $page->urlExtension(); + $url = $pages->route($route) . $pageExtension; + + if ($uri->params()) { + if ($url === '/') { //Avoid double slash + $url = $uri->params(); + } else { + $url .= $uri->params(); + } + } + if ($uri->query()) { + $url .= '?' . $uri->query(); + } + if ($uri->fragment()) { + $url .= '#' . $uri->fragment(); + } + + /** @var Language $language */ + $language = $grav['language']; + + $redirect_default_route = $page->header()->redirect_default_route ?? $config->get('system.pages.redirect_default_route', 0); + $redirectCode = (int) $redirect_default_route; + + // Language-specific redirection scenarios + if ($language->enabled() && ($language->isLanguageInUrl() xor $language->isIncludeDefaultLanguage())) { + $grav->redirect($url, $redirectCode); + } + + // Default route test and redirect + if ($redirectCode) { + $uriExtension = $uri->extension(); + $uriExtension = null !== $uriExtension ? '.' . $uriExtension : ''; + + if ($route !== $path || ($pageExtension !== $uriExtension + && \in_array($pageExtension, ['', '.htm', '.html'], true) + && \in_array($uriExtension, ['', '.htm', '.html'], true))) { + $grav->redirect($url, $redirectCode); + } + } + } + } + + // if page is not found, try some fallback stuff + if (!$page || !$page->routable()) { + // Try fallback URL stuff... + $page = $grav->fallbackUrl($path); + + if (!$page) { + $path = $grav['locator']->findResource('system://pages/notfound.md'); + $page = new Page(); + $page->init(new SplFileInfo($path)); + $page->routable(false); + } + } + + return $page; + }; + } +} diff --git a/system/src/Grav/Common/Service/RequestServiceProvider.php b/system/src/Grav/Common/Service/RequestServiceProvider.php new file mode 100644 index 0000000..ad9858f --- /dev/null +++ b/system/src/Grav/Common/Service/RequestServiceProvider.php @@ -0,0 +1,103 @@ + $headerValue) { + if ('content-type' !== strtolower($headerName)) { + continue; + } + + $contentType = strtolower(trim(explode(';', $headerValue, 2)[0])); + switch ($contentType) { + case 'application/x-www-form-urlencoded': + case 'multipart/form-data': + $post = $_POST; + break 2; + case 'application/json': + case 'application/vnd.api+json': + try { + $json = file_get_contents('php://input'); + $post = json_decode($json, true, 512, JSON_THROW_ON_ERROR); + if (!is_array($post)) { + $post = null; + } + } catch (JsonException $e) { + $post = null; + } + break 2; + } + } + } + + // Remove _url from ngnix routes. + $get = $_GET; + unset($get['_url']); + if (isset($server['QUERY_STRING'])) { + $query = $server['QUERY_STRING']; + if (strpos($query, '_url=') !== false) { + parse_str($query, $query); + unset($query['_url']); + $server['QUERY_STRING'] = http_build_query($query); + } + } + + return $creator->fromArrays($server, $headers, $_COOKIE, $get, $post, $_FILES, fopen('php://input', 'rb') ?: null); + }; + + $container['route'] = $container->factory(function () { + return clone Uri::getCurrentRoute(); + }); + } +} diff --git a/system/src/Grav/Common/Service/SchedulerServiceProvider.php b/system/src/Grav/Common/Service/SchedulerServiceProvider.php new file mode 100644 index 0000000..2fbe417 --- /dev/null +++ b/system/src/Grav/Common/Service/SchedulerServiceProvider.php @@ -0,0 +1,32 @@ +get('system.session.enabled', false); + $cookie_secure = $config->get('system.session.secure', false) + || ($config->get('system.session.secure_https', true) && $uri->scheme(true) === 'https'); + $cookie_httponly = (bool)$config->get('system.session.httponly', true); + $cookie_lifetime = (int)$config->get('system.session.timeout', 1800); + $cookie_domain = $config->get('system.session.domain'); + $cookie_path = $config->get('system.session.path'); + $cookie_samesite = $config->get('system.session.samesite', 'Lax'); + + if (null === $cookie_domain) { + $cookie_domain = $uri->host(); + if ($cookie_domain === 'localhost') { + $cookie_domain = ''; + } + } + + if (null === $cookie_path) { + $cookie_path = '/' . trim(Uri::filterPath($uri->rootUrl(false)), '/'); + } + // Session cookie path requires trailing slash. + $cookie_path = rtrim($cookie_path, '/') . '/'; + + // Activate admin if we're inside the admin path. + $is_admin = false; + if ($config->get('plugins.admin.enabled')) { + $admin_base = '/' . trim($config->get('plugins.admin.route'), '/'); + + // Uri::route() is not processed yet, let's quickly get what we need. + $current_route = str_replace(Uri::filterPath($uri->rootUrl(false)), '', parse_url($uri->url(true), PHP_URL_PATH)); + + // Test to see if path starts with a supported language + admin base + $lang = Utils::pathPrefixedByLangCode($current_route); + $lang_admin_base = '/' . $lang . $admin_base; + + // Check no language, simple language prefix (en) and region specific language prefix (en-US). + if (Utils::startsWith($current_route, $admin_base) || Utils::startsWith($current_route, $lang_admin_base)) { + $cookie_lifetime = $config->get('plugins.admin.session.timeout', 1800); + $enabled = $is_admin = true; + } + } + + // Fix for HUGE session timeouts. + if ($cookie_lifetime > 99999999999) { + $cookie_lifetime = 9999999999; + } + + $session_prefix = $c['inflector']->hyphenize($config->get('system.session.name', 'grav-site')); + $session_uniqueness = $config->get('system.session.uniqueness', 'path') === 'path' ? substr(md5(GRAV_ROOT), 0, 7) : md5($config->get('security.salt')); + + $session_name = $session_prefix . '-' . $session_uniqueness; + + if ($is_admin && $config->get('system.session.split', true)) { + $session_name .= '-admin'; + } + + // Define session service. + $options = [ + 'name' => $session_name, + 'cookie_lifetime' => $cookie_lifetime, + 'cookie_path' => $cookie_path, + 'cookie_domain' => $cookie_domain, + 'cookie_secure' => $cookie_secure, + 'cookie_httponly' => $cookie_httponly, + 'cookie_samesite' => $cookie_samesite + ] + (array) $config->get('system.session.options'); + + $session = new Session($options); + $session->setAutoStart($enabled); + + return $session; + }; + + // Define session message service. + $container['messages'] = function ($c) { + if (!isset($c['session']) || !$c['session']->isStarted()) { + /** @var Debugger $debugger */ + $debugger = $c['debugger']; + $debugger->addMessage('Inactive session: session messages may disappear', 'warming'); + + return new Messages(); + } + + /** @var Session $session */ + $session = $c['session']; + + if (!$session->messages instanceof Messages) { + $session->messages = new Messages(); + } + + return $session->messages; + }; + } +} diff --git a/system/src/Grav/Common/Service/StreamsServiceProvider.php b/system/src/Grav/Common/Service/StreamsServiceProvider.php new file mode 100644 index 0000000..a13ea40 --- /dev/null +++ b/system/src/Grav/Common/Service/StreamsServiceProvider.php @@ -0,0 +1,56 @@ +initializeLocator($locator); + + return $locator; + }; + + $container['streams'] = function (Container $container) { + /** @var Setup $setup */ + $setup = $container['setup']; + + /** @var UniformResourceLocator $locator */ + $locator = $container['locator']; + + // Set locator to both streams. + Stream::setLocator($locator); + ReadOnlyStream::setLocator($locator); + + return new StreamBuilder($setup->getStreams()); + }; + } +} diff --git a/system/src/Grav/Common/Service/TaskServiceProvider.php b/system/src/Grav/Common/Service/TaskServiceProvider.php new file mode 100644 index 0000000..46ab704 --- /dev/null +++ b/system/src/Grav/Common/Service/TaskServiceProvider.php @@ -0,0 +1,55 @@ +getParsedBody(); + + $task = $body['task'] ?? $c['uri']->param('task'); + if (null !== $task) { + $task = htmlspecialchars(strip_tags($task), ENT_QUOTES, 'UTF-8'); + } + + return $task ?: null; + }; + + $container['action'] = function (Grav $c) { + /** @var ServerRequestInterface $request */ + $request = $c['request']; + $body = $request->getParsedBody(); + + $action = $body['action'] ?? $c['uri']->param('action'); + if (null !== $action) { + $action = htmlspecialchars(strip_tags($action), ENT_QUOTES, 'UTF-8'); + } + + return $action ?: null; + }; + } +} diff --git a/system/src/Grav/Common/Session.php b/system/src/Grav/Common/Session.php new file mode 100644 index 0000000..a75e083 --- /dev/null +++ b/system/src/Grav/Common/Session.php @@ -0,0 +1,202 @@ +getInstance() method instead. + */ + public static function instance() + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use ->getInstance() method instead', E_USER_DEPRECATED); + + return static::getInstance(); + } + + /** + * Initialize session. + * + * Code in this function has been moved into SessionServiceProvider class. + * + * @return void + */ + public function init() + { + if ($this->autoStart && !$this->isStarted()) { + $this->start(); + + $this->autoStart = false; + } + } + + /** + * @param bool $auto + * @return $this + */ + public function setAutoStart($auto) + { + $this->autoStart = (bool)$auto; + + return $this; + } + + /** + * Returns attributes. + * + * @return array Attributes + * @deprecated 1.5 Use ->getAll() method instead. + */ + public function all() + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use ->getAll() method instead', E_USER_DEPRECATED); + + return $this->getAll(); + } + + /** + * Checks if the session was started. + * + * @return bool + * @deprecated 1.5 Use ->isStarted() method instead. + */ + public function started() + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use ->isStarted() method instead', E_USER_DEPRECATED); + + return $this->isStarted(); + } + + /** + * Store something in session temporarily. + * + * @param string $name + * @param mixed $object + * @return $this + */ + public function setFlashObject($name, $object) + { + $this->__set($name, serialize($object)); + + return $this; + } + + /** + * Return object and remove it from session. + * + * @param string $name + * @return mixed + */ + public function getFlashObject($name) + { + $serialized = $this->__get($name); + + $object = is_string($serialized) ? unserialize($serialized, ['allowed_classes' => true]) : $serialized; + + $this->__unset($name); + + if ($name === 'files-upload') { + $grav = Grav::instance(); + + // Make sure that Forms 3.0+ has been installed. + if (null === $object && isset($grav['forms'])) { +// user_error( +// __CLASS__ . '::' . __FUNCTION__ . '(\'files-upload\') is deprecated since Grav 1.6, use $form->getFlash()->getLegacyFiles() instead', +// E_USER_DEPRECATED +// ); + + /** @var Uri $uri */ + $uri = $grav['uri']; + /** @var Forms|null $form */ + $form = $grav['forms']->getActiveForm(); // @phpstan-ignore-line (form plugin) + + $sessionField = base64_encode($uri->url); + + /** @var FormFlash|null $flash */ + $flash = $form ? $form->getFlash() : null; // @phpstan-ignore-line (form plugin) + $object = $flash && method_exists($flash, 'getLegacyFiles') ? [$sessionField => $flash->getLegacyFiles()] : null; + } + } + + return $object; + } + + /** + * Store something in cookie temporarily. + * + * @param string $name + * @param mixed $object + * @param int $time + * @return $this + * @throws JsonException + */ + public function setFlashCookieObject($name, $object, $time = 60) + { + setcookie($name, json_encode($object, JSON_THROW_ON_ERROR), $this->getCookieOptions($time)); + + return $this; + } + + /** + * Return object and remove it from the cookie. + * + * @param string $name + * @return mixed|null + * @throws JsonException + */ + public function getFlashCookieObject($name) + { + if (isset($_COOKIE[$name])) { + $cookie = $_COOKIE[$name]; + setcookie($name, '', $this->getCookieOptions(-42000)); + + return json_decode($cookie, false, 512, JSON_THROW_ON_ERROR); + } + + return null; + } + + /** + * @return void + */ + protected function onBeforeSessionStart(): void + { + $event = new BeforeSessionStartEvent($this); + + $grav = Grav::instance(); + $grav->dispatchEvent($event); + } + + /** + * @return void + */ + protected function onSessionStart(): void + { + $event = new SessionStartEvent($this); + + $grav = Grav::instance(); + $grav->dispatchEvent($event); + } +} diff --git a/system/src/Grav/Common/Taxonomy.php b/system/src/Grav/Common/Taxonomy.php new file mode 100644 index 0000000..3ce2173 --- /dev/null +++ b/system/src/Grav/Common/Taxonomy.php @@ -0,0 +1,181 @@ +grav = $grav; + $this->language = $grav['language']; + $this->taxonomy_map[$this->language->getLanguage()] = []; + } + + /** + * Takes an individual page and processes the taxonomies configured in its header. It + * then adds those taxonomies to the map + * + * @param PageInterface $page the page to process + * @param array|null $page_taxonomy + */ + public function addTaxonomy(PageInterface $page, $page_taxonomy = null) + { + if (!$page->published()) { + return; + } + + if (!$page_taxonomy) { + $page_taxonomy = $page->taxonomy(); + } + + if (empty($page_taxonomy)) { + return; + } + + /** @var Config $config */ + $config = $this->grav['config']; + $taxonomies = (array)$config->get('site.taxonomies'); + foreach ($taxonomies as $taxonomy) { + // Skip invalid taxonomies. + if (!\is_string($taxonomy)) { + continue; + } + $current = $page_taxonomy[$taxonomy] ?? null; + foreach ((array)$current as $item) { + $this->iterateTaxonomy($page, $taxonomy, '', $item); + } + } + } + + /** + * Iterate through taxonomy fields + * + * Reduces [taxonomy_type] to dot-notation where necessary + * + * @param PageInterface $page The Page to process + * @param string $taxonomy Taxonomy type to add + * @param string $key Taxonomy type to concatenate + * @param iterable|string $value Taxonomy value to add or iterate + * @return void + */ + public function iterateTaxonomy(PageInterface $page, string $taxonomy, string $key, $value) + { + if (is_iterable($value)) { + foreach ($value as $identifier => $item) { + $identifier = "{$key}.{$identifier}"; + $this->iterateTaxonomy($page, $taxonomy, $identifier, $item); + } + } elseif (is_string($value)) { + if (!empty($key)) { + $taxonomy .= $key; + } + $active = $this->language->getLanguage(); + $this->taxonomy_map[$active][$taxonomy][(string) $value][$page->path()] = ['slug' => $page->slug()]; + } + } + + /** + * Returns a new Page object with the sub-pages containing all the values set for a + * particular taxonomy. + * + * @param array $taxonomies taxonomies to search, eg ['tag'=>['animal','cat']] + * @param string $operator can be 'or' or 'and' (defaults to 'and') + * @return Collection Collection object set to contain matches found in the taxonomy map + */ + public function findTaxonomy($taxonomies, $operator = 'and') + { + $matches = []; + $results = []; + $active = $this->language->getLanguage(); + + foreach ((array)$taxonomies as $taxonomy => $items) { + foreach ((array)$items as $item) { + $matches[] = $this->taxonomy_map[$active][$taxonomy][$item] ?? []; + } + } + + if (strtolower($operator) === 'or') { + foreach ($matches as $match) { + $results = array_merge($results, $match); + } + } else { + $results = $matches ? array_pop($matches) : []; + foreach ($matches as $match) { + $results = array_intersect_key($results, $match); + } + } + + return new Collection($results, ['taxonomies' => $taxonomies]); + } + + /** + * Gets and Sets the taxonomy map + * + * @param array|null $var the taxonomy map + * @return array the taxonomy map + */ + public function taxonomy($var = null) + { + $active = $this->language->getLanguage(); + + if ($var) { + $this->taxonomy_map[$active] = $var; + } + + return $this->taxonomy_map[$active] ?? []; + } + + /** + * Gets item keys per taxonomy + * + * @param string $taxonomy taxonomy name + * @return array keys of this taxonomy + */ + public function getTaxonomyItemKeys($taxonomy) + { + $active = $this->language->getLanguage(); + return isset($this->taxonomy_map[$active][$taxonomy]) ? array_keys($this->taxonomy_map[$active][$taxonomy]) : []; + } +} diff --git a/system/src/Grav/Common/Theme.php b/system/src/Grav/Common/Theme.php new file mode 100644 index 0000000..e800245 --- /dev/null +++ b/system/src/Grav/Common/Theme.php @@ -0,0 +1,87 @@ +config["themes.{$this->name}"] ?? []; + } + + /** + * Persists to disk the theme parameters currently stored in the Grav Config object + * + * @param string $name The name of the theme whose config it should store. + * @return bool + */ + public static function saveConfig($name) + { + if (!$name) { + return false; + } + + $grav = Grav::instance(); + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + + $filename = 'config://themes/' . $name . '.yaml'; + $file = YamlFile::instance((string)$locator->findResource($filename, true, true)); + $content = $grav['config']->get('themes.' . $name); + $file->save($content); + $file->free(); + unset($file); + + return true; + } + + /** + * Load blueprints. + * + * @return void + */ + protected function loadBlueprint() + { + if (!$this->blueprint) { + $grav = Grav::instance(); + /** @var Themes $themes */ + $themes = $grav['themes']; + $data = $themes->get($this->name); + \assert($data !== null); + $this->blueprint = $data->blueprints(); + } + } +} diff --git a/system/src/Grav/Common/Themes.php b/system/src/Grav/Common/Themes.php new file mode 100644 index 0000000..75bd8b1 --- /dev/null +++ b/system/src/Grav/Common/Themes.php @@ -0,0 +1,417 @@ +grav = $grav; + $this->config = $grav['config']; + + // Register instance as autoloader for theme inheritance + spl_autoload_register([$this, 'autoloadTheme']); + } + + /** + * @return void + */ + public function init() + { + /** @var Themes $themes */ + $themes = $this->grav['themes']; + $themes->configure(); + + $this->initTheme(); + } + + /** + * @return void + */ + public function initTheme() + { + if ($this->inited === false) { + /** @var Themes $themes */ + $themes = $this->grav['themes']; + + try { + $instance = $themes->load(); + } catch (InvalidArgumentException $e) { + throw new RuntimeException($this->current() . ' theme could not be found'); + } + + // Register autoloader. + if (method_exists($instance, 'autoload')) { + $instance->autoload(); + } + + // Register event listeners. + if ($instance instanceof EventSubscriberInterface) { + /** @var EventDispatcher $events */ + $events = $this->grav['events']; + $events->addSubscriber($instance); + } + + // Register blueprints. + if (is_dir('theme://blueprints/pages')) { + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + $locator->addPath('blueprints', '', ['theme://blueprints'], ['user', 'blueprints']); + } + + // Register form fields. + if (method_exists($instance, 'getFormFieldTypes')) { + /** @var Plugins $plugins */ + $plugins = $this->grav['plugins']; + $plugins->formFieldTypes = $instance->getFormFieldTypes() + $plugins->formFieldTypes; + } + + $this->grav['theme'] = $instance; + + $this->grav->fireEvent('onThemeInitialized'); + + $this->inited = true; + } + } + + /** + * Return list of all theme data with their blueprints. + * + * @return array + */ + public function all() + { + $list = []; + + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + $iterator = $locator->getIterator('themes://'); + + /** @var DirectoryIterator $directory */ + foreach ($iterator as $directory) { + if (!$directory->isDir() || $directory->isDot()) { + continue; + } + + $theme = $directory->getFilename(); + + try { + $result = $this->get($theme); + } catch (Exception $e) { + $exception = new RuntimeException(sprintf('Theme %s: %s', $theme, $e->getMessage()), $e->getCode(), $e); + + /** @var Debugger $debugger */ + $debugger = $this->grav['debugger']; + $debugger->addMessage("Theme {$theme} cannot be loaded, please check Exceptions tab", 'error'); + $debugger->addException($exception); + + continue; + } + + if ($result) { + $list[$theme] = $result; + } + } + ksort($list, SORT_NATURAL | SORT_FLAG_CASE); + + return $list; + } + + /** + * Get theme configuration or throw exception if it cannot be found. + * + * @param string $name + * @return Data|null + * @throws RuntimeException + */ + public function get($name) + { + if (!$name) { + throw new RuntimeException('Theme name not provided.'); + } + + $blueprints = new Blueprints('themes://'); + $blueprint = $blueprints->get("{$name}/blueprints"); + + // Load default configuration. + $file = CompiledYamlFile::instance("themes://{$name}/{$name}" . YAML_EXT); + + // ensure this is a valid theme + if (!$file->exists()) { + return null; + } + + // Find thumbnail. + $thumb = "themes://{$name}/thumbnail.jpg"; + $path = $this->grav['locator']->findResource($thumb, false); + + if ($path) { + $blueprint->set('thumbnail', $this->grav['base_url'] . '/' . $path); + } + + $obj = new Data((array)$file->content(), $blueprint); + + // Override with user configuration. + $obj->merge($this->config->get('themes.' . $name) ?: []); + + // Save configuration always to user/config. + $file = CompiledYamlFile::instance("config://themes/{$name}" . YAML_EXT); + $obj->file($file); + + return $obj; + } + + /** + * Return name of the current theme. + * + * @return string + */ + public function current() + { + return (string)$this->config->get('system.pages.theme'); + } + + /** + * Load current theme. + * + * @return Theme + */ + public function load() + { + // NOTE: ALL THE LOCAL VARIABLES ARE USED INSIDE INCLUDED FILE, DO NOT REMOVE THEM! + $grav = $this->grav; + $config = $this->config; + $name = $this->current(); + $class = null; + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + + // Start by attempting to load the theme.php file. + $file = $locator('theme://theme.php') ?: $locator("theme://{$name}.php"); + if ($file) { + // Local variables available in the file: $grav, $config, $name, $file + $class = include $file; + if (!\is_object($class) || !is_subclass_of($class, Theme::class, true)) { + $class = null; + } + } elseif (!$locator('theme://') && !defined('GRAV_CLI')) { + $response = new Response(500, [], "Theme '$name' does not exist, unable to display page."); + + $grav->close($response); + } + + // If the class hasn't been initialized yet, guess the class name and create a new instance. + if (null === $class) { + $themeClassFormat = [ + 'Grav\\Theme\\' . Inflector::camelize($name), + 'Grav\\Theme\\' . ucfirst($name) + ]; + + foreach ($themeClassFormat as $themeClass) { + if (is_subclass_of($themeClass, Theme::class, true)) { + $class = new $themeClass($grav, $config, $name); + break; + } + } + } + + // Finally if everything else fails, just create a new instance from the default Theme class. + if (null === $class) { + $class = new Theme($grav, $config, $name); + } + + $this->config->set('theme', $config->get('themes.' . $name)); + + return $class; + } + + /** + * Configure and prepare streams for current template. + * + * @return void + * @throws InvalidArgumentException + */ + public function configure() + { + $name = $this->current(); + $config = $this->config; + + $this->loadConfiguration($name, $config); + + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + $registered = stream_get_wrappers(); + + $schemes = $config->get("themes.{$name}.streams.schemes", []); + $schemes += [ + 'theme' => [ + 'type' => 'ReadOnlyStream', + 'paths' => $locator->findResources("themes://{$name}", false) + ] + ]; + + foreach ($schemes as $scheme => $config) { + if (isset($config['paths'])) { + $locator->addPath($scheme, '', $config['paths']); + } + if (isset($config['prefixes'])) { + foreach ($config['prefixes'] as $prefix => $paths) { + $locator->addPath($scheme, $prefix, $paths); + } + } + + if (in_array($scheme, $registered, true)) { + stream_wrapper_unregister($scheme); + } + $type = !empty($config['type']) ? $config['type'] : 'ReadOnlyStream'; + if ($type[0] !== '\\') { + $type = '\\RocketTheme\\Toolbox\\StreamWrapper\\' . $type; + } + + if (!stream_wrapper_register($scheme, $type)) { + throw new InvalidArgumentException("Stream '{$type}' could not be initialized."); + } + } + + // Load languages after streams has been properly initialized + $this->loadLanguages($this->config); + } + + /** + * Load theme configuration. + * + * @param string $name Theme name + * @param Config $config Configuration class + * @return void + */ + protected function loadConfiguration($name, Config $config) + { + $themeConfig = CompiledYamlFile::instance("themes://{$name}/{$name}" . YAML_EXT)->content(); + $config->joinDefaults("themes.{$name}", $themeConfig); + } + + /** + * Load theme languages. + * Reads ALL language files from theme stream and merges them. + * + * @param Config $config Configuration class + * @return void + */ + protected function loadLanguages(Config $config) + { + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + if ($config->get('system.languages.translations', true)) { + $language_files = array_reverse($locator->findResources('theme://languages' . YAML_EXT)); + foreach ($language_files as $language_file) { + $language = CompiledYamlFile::instance($language_file)->content(); + $this->grav['languages']->mergeRecursive($language); + } + $languages_folders = array_reverse($locator->findResources('theme://languages')); + foreach ($languages_folders as $languages_folder) { + $languages = []; + $iterator = new DirectoryIterator($languages_folder); + foreach ($iterator as $file) { + if ($file->getExtension() !== 'yaml') { + continue; + } + $languages[$file->getBasename('.yaml')] = CompiledYamlFile::instance($file->getPathname())->content(); + } + $this->grav['languages']->mergeRecursive($languages); + } + } + } + + /** + * Autoload theme classes for inheritance + * + * @param string $class Class name + * @return mixed|false FALSE if unable to load $class; Class name if + * $class is successfully loaded + */ + protected function autoloadTheme($class) + { + $prefix = 'Grav\\Theme\\'; + if (false !== strpos($class, $prefix)) { + // Remove prefix from class + $class = substr($class, strlen($prefix)); + $locator = $this->grav['locator']; + + // First try lowercase version of the classname. + $path = strtolower($class); + $file = $locator("themes://{$path}/theme.php") ?: $locator("themes://{$path}/{$path}.php"); + + if ($file) { + return include_once $file; + } + + // Replace namespace tokens to directory separators + $path = $this->grav['inflector']->hyphenize($class); + $file = $locator("themes://{$path}/theme.php") ?: $locator("themes://{$path}/{$path}.php"); + + // Load class + if ($file) { + return include_once $file; + } + + // Try Old style theme classes + $path = preg_replace('#\\\|_(?!.+\\\)#', '/', $class); + \assert(null !== $path); + + $path = strtolower($path); + $file = $locator("themes://{$path}/theme.php") ?: $locator("themes://{$path}/{$path}.php"); + + // Load class + if ($file) { + return include_once $file; + } + } + + return false; + } +} diff --git a/system/src/Grav/Common/Twig/Exception/TwigException.php b/system/src/Grav/Common/Twig/Exception/TwigException.php new file mode 100644 index 0000000..19e0529 --- /dev/null +++ b/system/src/Grav/Common/Twig/Exception/TwigException.php @@ -0,0 +1,21 @@ +locator = Grav::instance()['locator']; + } + + /** + * @return TwigFilter[] + */ + public function getFilters() + { + return [ + new TwigFilter('file_exists', [$this, 'file_exists']), + new TwigFilter('fileatime', [$this, 'fileatime']), + new TwigFilter('filectime', [$this, 'filectime']), + new TwigFilter('filemtime', [$this, 'filemtime']), + new TwigFilter('filesize', [$this, 'filesize']), + new TwigFilter('filetype', [$this, 'filetype']), + new TwigFilter('is_dir', [$this, 'is_dir']), + new TwigFilter('is_file', [$this, 'is_file']), + new TwigFilter('is_link', [$this, 'is_link']), + new TwigFilter('is_readable', [$this, 'is_readable']), + new TwigFilter('is_writable', [$this, 'is_writable']), + new TwigFilter('is_writeable', [$this, 'is_writable']), + new TwigFilter('lstat', [$this, 'lstat']), + new TwigFilter('getimagesize', [$this, 'getimagesize']), + new TwigFilter('exif_read_data', [$this, 'exif_read_data']), + new TwigFilter('read_exif_data', [$this, 'exif_read_data']), + new TwigFilter('exif_imagetype', [$this, 'exif_imagetype']), + new TwigFilter('hash_file', [$this, 'hash_file']), + new TwigFilter('hash_hmac_file', [$this, 'hash_hmac_file']), + new TwigFilter('md5_file', [$this, 'md5_file']), + new TwigFilter('sha1_file', [$this, 'sha1_file']), + new TwigFilter('get_meta_tags', [$this, 'get_meta_tags']), + new TwigFilter('pathinfo', [$this, 'pathinfo']), + ]; + } + + /** + * Return a list of all functions. + * + * @return TwigFunction[] + */ + public function getFunctions() + { + return [ + new TwigFunction('file_exists', [$this, 'file_exists']), + new TwigFunction('fileatime', [$this, 'fileatime']), + new TwigFunction('filectime', [$this, 'filectime']), + new TwigFunction('filemtime', [$this, 'filemtime']), + new TwigFunction('filesize', [$this, 'filesize']), + new TwigFunction('filetype', [$this, 'filetype']), + new TwigFunction('is_dir', [$this, 'is_dir']), + new TwigFunction('is_file', [$this, 'is_file']), + new TwigFunction('is_link', [$this, 'is_link']), + new TwigFunction('is_readable', [$this, 'is_readable']), + new TwigFunction('is_writable', [$this, 'is_writable']), + new TwigFunction('is_writeable', [$this, 'is_writable']), + new TwigFunction('lstat', [$this, 'lstat']), + new TwigFunction('getimagesize', [$this, 'getimagesize']), + new TwigFunction('exif_read_data', [$this, 'exif_read_data']), + new TwigFunction('read_exif_data', [$this, 'exif_read_data']), + new TwigFunction('exif_imagetype', [$this, 'exif_imagetype']), + new TwigFunction('hash_file', [$this, 'hash_file']), + new TwigFunction('hash_hmac_file', [$this, 'hash_hmac_file']), + new TwigFunction('md5_file', [$this, 'md5_file']), + new TwigFunction('sha1_file', [$this, 'sha1_file']), + new TwigFunction('get_meta_tags', [$this, 'get_meta_tags']), + new TwigFunction('pathinfo', [$this, 'pathinfo']), + ]; + } + + /** + * @param string $filename + * @return bool + */ + public function file_exists($filename): bool + { + if (!$this->checkFilename($filename)) { + return false; + } + + return file_exists($filename); + } + + /** + * @param string $filename + * @return int|false + */ + public function fileatime($filename) + { + if (!$this->checkFilename($filename)) { + return false; + } + + return fileatime($filename); + } + + /** + * @param string $filename + * @return int|false + */ + public function filectime($filename) + { + if (!$this->checkFilename($filename)) { + return false; + } + + return filectime($filename); + } + + /** + * @param string $filename + * @return int|false + */ + public function filemtime($filename) + { + if (!$this->checkFilename($filename)) { + return false; + } + + return filemtime($filename); + } + + /** + * @param string $filename + * @return int|false + */ + public function filesize($filename) + { + if (!$this->checkFilename($filename)) { + return false; + } + + return filesize($filename); + } + + /** + * @param string $filename + * @return string|false + */ + public function filetype($filename) + { + if (!$this->checkFilename($filename)) { + return false; + } + + return filetype($filename); + } + + /** + * @param string $filename + * @return bool + */ + public function is_dir($filename): bool + { + if (!$this->checkFilename($filename)) { + return false; + } + + return is_dir($filename); + } + + /** + * @param string $filename + * @return bool + */ + public function is_file($filename): bool + { + if (!$this->checkFilename($filename)) { + return false; + } + + return is_file($filename); + } + + /** + * @param string $filename + * @return bool + */ + public function is_link($filename): bool + { + if (!$this->checkFilename($filename)) { + return false; + } + + return is_link($filename); + } + + /** + * @param string $filename + * @return bool + */ + public function is_readable($filename): bool + { + if (!$this->checkFilename($filename)) { + return false; + } + + return is_readable($filename); + } + + /** + * @param string $filename + * @return bool + */ + public function is_writable($filename): bool + { + if (!$this->checkFilename($filename)) { + return false; + } + + return is_writable($filename); + } + + /** + * @param string $filename + * @return array|false + */ + public function lstat($filename) + { + if (!$this->checkFilename($filename)) { + return false; + } + + return lstat($filename); + } + + /** + * @param string $filename + * @return array|false + */ + public function getimagesize($filename) + { + if (!$this->checkFilename($filename)) { + return false; + } + + return getimagesize($filename); + } + + /** + * @param string $filename + * @param string|null $required_sections + * @param bool $as_arrays + * @param bool $read_thumbnail + * @return array|false + */ + public function exif_read_data($filename, ?string $required_sections, bool $as_arrays = false, bool $read_thumbnail = false) + { + if (!Utils::functionExists('exif_read_data') || !$this->checkFilename($filename)) { + return false; + } + + return exif_read_data($filename, $required_sections, $as_arrays, $read_thumbnail); + } + + /** + * @param string $filename + * @return int|false + */ + public function exif_imagetype($filename) + { + if (!Utils::functionExists('exif_imagetype') || !$this->checkFilename($filename)) { + return false; + } + + return @exif_imagetype($filename); + } + + /** + * @param string $algo + * @param string $filename + * @param bool $binary + * @return string|false + */ + public function hash_file(string $algo, string $filename, bool $binary = false) + { + if (!$this->checkFilename($filename)) { + return false; + } + + return hash_file($algo, $filename, $binary); + } + + /** + * @param string $algo + * @param string $filename + * @param string $key + * @param bool $binary + * @return string|false + */ + public function hash_hmac_file(string $algo, string $filename, string $key, bool $binary = false) + { + if (!$this->checkFilename($filename)) { + return false; + } + + return hash_hmac_file($algo, $filename, $key, $binary); + } + + /** + * @param string $filename + * @param bool $binary + * @return string|false + */ + public function md5_file($filename, bool $binary = false) + { + if (!$this->checkFilename($filename)) { + return false; + } + + return md5_file($filename, $binary); + } + + /** + * @param string $filename + * @param bool $binary + * @return string|false + */ + public function sha1_file($filename, bool $binary = false) + { + if (!$this->checkFilename($filename)) { + return false; + } + + return sha1_file($filename, $binary); + } + + /** + * @param string $filename + * @return array|false + */ + public function get_meta_tags($filename) + { + if (!$this->checkFilename($filename)) { + return false; + } + + return get_meta_tags($filename); + } + + /** + * @param string $path + * @param int|null $flags + * @return string|string[] + */ + public function pathinfo($path, $flags = null) + { + return Utils::pathinfo($path, $flags); + } + + /** + * @param string $filename + * @return bool + */ + private function checkFilename($filename): bool + { + return is_string($filename) && (!str_contains($filename, '://') || $this->locator->isStream($filename)); + } +} diff --git a/system/src/Grav/Common/Twig/Extension/GravExtension.php b/system/src/Grav/Common/Twig/Extension/GravExtension.php new file mode 100644 index 0000000..3e30a02 --- /dev/null +++ b/system/src/Grav/Common/Twig/Extension/GravExtension.php @@ -0,0 +1,1756 @@ +grav = Grav::instance(); + $this->debugger = $this->grav['debugger'] ?? null; + $this->config = $this->grav['config']; + } + + /** + * Register some standard globals + * + * @return array + */ + public function getGlobals(): array + { + return [ + 'grav' => $this->grav, + ]; + } + + /** + * Return a list of all filters. + * + * @return array + */ + public function getFilters(): array + { + return [ + new TwigFilter('*ize', [$this, 'inflectorFilter']), + new TwigFilter('absolute_url', [$this, 'absoluteUrlFilter']), + new TwigFilter('contains', [$this, 'containsFilter']), + new TwigFilter('chunk_split', [$this, 'chunkSplitFilter']), + new TwigFilter('nicenumber', [$this, 'niceNumberFunc']), + new TwigFilter('nicefilesize', [$this, 'niceFilesizeFunc']), + new TwigFilter('nicetime', [$this, 'nicetimeFunc']), + new TwigFilter('defined', [$this, 'definedDefaultFilter']), + new TwigFilter('ends_with', [$this, 'endsWithFilter']), + new TwigFilter('fieldName', [$this, 'fieldNameFilter']), + new TwigFilter('parent_field', [$this, 'fieldParentFilter']), + new TwigFilter('ksort', [$this, 'ksortFilter']), + new TwigFilter('ltrim', [$this, 'ltrimFilter']), + new TwigFilter('markdown', [$this, 'markdownFunction'], ['needs_context' => true, 'is_safe' => ['html']]), + new TwigFilter('md5', [$this, 'md5Filter']), + new TwigFilter('base32_encode', [$this, 'base32EncodeFilter']), + new TwigFilter('base32_decode', [$this, 'base32DecodeFilter']), + new TwigFilter('base64_encode', [$this, 'base64EncodeFilter']), + new TwigFilter('base64_decode', [$this, 'base64DecodeFilter']), + new TwigFilter('randomize', [$this, 'randomizeFilter']), + new TwigFilter('modulus', [$this, 'modulusFilter']), + new TwigFilter('rtrim', [$this, 'rtrimFilter']), + new TwigFilter('pad', [$this, 'padFilter']), + new TwigFilter('regex_replace', [$this, 'regexReplace']), + new TwigFilter('safe_email', [$this, 'safeEmailFilter'], ['is_safe' => ['html']]), + new TwigFilter('safe_truncate', [Utils::class, 'safeTruncate']), + new TwigFilter('safe_truncate_html', [Utils::class, 'safeTruncateHTML']), + new TwigFilter('sort_by_key', [$this, 'sortByKeyFilter']), + new TwigFilter('starts_with', [$this, 'startsWithFilter']), + new TwigFilter('truncate', [Utils::class, 'truncate']), + new TwigFilter('truncate_html', [Utils::class, 'truncateHTML']), + new TwigFilter('json_decode', [$this, 'jsonDecodeFilter']), + new TwigFilter('array_unique', 'array_unique'), + new TwigFilter('basename', 'basename'), + new TwigFilter('dirname', 'dirname'), + new TwigFilter('print_r', [$this, 'print_r']), + new TwigFilter('yaml_encode', [$this, 'yamlEncodeFilter']), + new TwigFilter('yaml_decode', [$this, 'yamlDecodeFilter']), + new TwigFilter('nicecron', [$this, 'niceCronFilter']), + new TwigFilter('replace_last', [$this, 'replaceLastFilter']), + + // Translations + new TwigFilter('t', [$this, 'translate'], ['needs_environment' => true]), + new TwigFilter('tl', [$this, 'translateLanguage']), + new TwigFilter('ta', [$this, 'translateArray']), + + // Casting values + new TwigFilter('string', [$this, 'stringFilter']), + new TwigFilter('int', [$this, 'intFilter'], ['is_safe' => ['all']]), + new TwigFilter('bool', [$this, 'boolFilter']), + new TwigFilter('float', [$this, 'floatFilter'], ['is_safe' => ['all']]), + new TwigFilter('array', [$this, 'arrayFilter']), + new TwigFilter('yaml', [$this, 'yamlFilter']), + + // Object Types + new TwigFilter('get_type', [$this, 'getTypeFunc']), + new TwigFilter('of_type', [$this, 'ofTypeFunc']), + + // PHP methods + new TwigFilter('count', 'count'), + new TwigFilter('array_diff', 'array_diff'), + + // Security fixes + new TwigFilter('filter', [$this, 'filterFunc'], ['needs_environment' => true]), + new TwigFilter('map', [$this, 'mapFunc'], ['needs_environment' => true]), + new TwigFilter('reduce', [$this, 'reduceFunc'], ['needs_environment' => true]), + ]; + } + + /** + * Return a list of all functions. + * + * @return array + */ + public function getFunctions(): array + { + return [ + new TwigFunction('array', [$this, 'arrayFilter']), + new TwigFunction('array_key_value', [$this, 'arrayKeyValueFunc']), + new TwigFunction('array_key_exists', 'array_key_exists'), + new TwigFunction('array_unique', 'array_unique'), + new TwigFunction('array_intersect', [$this, 'arrayIntersectFunc']), + new TwigFunction('array_diff', 'array_diff'), + new TwigFunction('authorize', [$this, 'authorize']), + new TwigFunction('debug', [$this, 'dump'], ['needs_context' => true, 'needs_environment' => true]), + new TwigFunction('dump', [$this, 'dump'], ['needs_context' => true, 'needs_environment' => true]), + new TwigFunction('vardump', [$this, 'vardumpFunc']), + new TwigFunction('print_r', [$this, 'print_r']), + new TwigFunction('http_response_code', 'http_response_code'), + new TwigFunction('evaluate', [$this, 'evaluateStringFunc'], ['needs_context' => true]), + new TwigFunction('evaluate_twig', [$this, 'evaluateTwigFunc'], ['needs_context' => true]), + new TwigFunction('gist', [$this, 'gistFunc']), + new TwigFunction('nonce_field', [$this, 'nonceFieldFunc']), + new TwigFunction('pathinfo', 'pathinfo'), + new TwigFunction('parseurl', 'parse_url'), + new TwigFunction('random_string', [$this, 'randomStringFunc']), + new TwigFunction('repeat', [$this, 'repeatFunc']), + new TwigFunction('regex_replace', [$this, 'regexReplace']), + new TwigFunction('regex_filter', [$this, 'regexFilter']), + new TwigFunction('regex_match', [$this, 'regexMatch']), + new TwigFunction('regex_split', [$this, 'regexSplit']), + new TwigFunction('string', [$this, 'stringFilter']), + new TwigFunction('url', [$this, 'urlFunc']), + new TwigFunction('json_decode', [$this, 'jsonDecodeFilter']), + new TwigFunction('get_cookie', [$this, 'getCookie']), + new TwigFunction('redirect_me', [$this, 'redirectFunc']), + new TwigFunction('range', [$this, 'rangeFunc']), + new TwigFunction('isajaxrequest', [$this, 'isAjaxFunc']), + new TwigFunction('exif', [$this, 'exifFunc']), + new TwigFunction('media_directory', [$this, 'mediaDirFunc']), + new TwigFunction('body_class', [$this, 'bodyClassFunc'], ['needs_context' => true]), + new TwigFunction('theme_var', [$this, 'themeVarFunc'], ['needs_context' => true]), + new TwigFunction('header_var', [$this, 'pageHeaderVarFunc'], ['needs_context' => true]), + new TwigFunction('read_file', [$this, 'readFileFunc']), + new TwigFunction('nicenumber', [$this, 'niceNumberFunc']), + new TwigFunction('nicefilesize', [$this, 'niceFilesizeFunc']), + new TwigFunction('nicetime', [$this, 'nicetimeFunc']), + new TwigFunction('cron', [$this, 'cronFunc']), + new TwigFunction('svg_image', [$this, 'svgImageFunction']), + new TwigFunction('xss', [$this, 'xssFunc']), + new TwigFunction('unique_id', [$this, 'uniqueId']), + + // Translations + new TwigFunction('t', [$this, 'translate'], ['needs_environment' => true]), + new TwigFunction('tl', [$this, 'translateLanguage']), + new TwigFunction('ta', [$this, 'translateArray']), + + // Object Types + new TwigFunction('get_type', [$this, 'getTypeFunc']), + new TwigFunction('of_type', [$this, 'ofTypeFunc']), + + // PHP methods + new TwigFunction('is_numeric', 'is_numeric'), + new TwigFunction('is_iterable', 'is_iterable'), + new TwigFunction('is_countable', 'is_countable'), + new TwigFunction('is_null', 'is_null'), + new TwigFunction('is_string', 'is_string'), + new TwigFunction('is_array', 'is_array'), + new TwigFunction('is_object', 'is_object'), + new TwigFunction('count', 'count'), + new TwigFunction('array_diff', 'array_diff'), + new TwigFunction('parse_url', 'parse_url'), + + // Security fixes + new TwigFunction('filter', [$this, 'filterFunc'], ['needs_environment' => true]), + new TwigFunction('map', [$this, 'mapFunc'], ['needs_environment' => true]), + new TwigFunction('reduce', [$this, 'reduceFunc'], ['needs_environment' => true]), + ]; + } + + /** + * @return array + */ + public function getTokenParsers(): array + { + return [ + new TwigTokenParserRender(), + new TwigTokenParserThrow(), + new TwigTokenParserTryCatch(), + new TwigTokenParserScript(), + new TwigTokenParserStyle(), + new TwigTokenParserLink(), + new TwigTokenParserMarkdown(), + new TwigTokenParserSwitch(), + new TwigTokenParserCache(), + ]; + } + + /** + * @param mixed $var + * @return string + */ + public function print_r($var) + { + return print_r($var, true); + } + + /** + * Filters field name by changing dot notation into array notation. + * + * @param string $str + * @return string + */ + public function fieldNameFilter($str) + { + $path = explode('.', rtrim($str, '.')); + + return array_shift($path) . ($path ? '[' . implode('][', $path) . ']' : ''); + } + + /** + * Filters field name by changing dot notation into array notation. + * + * @param string $str + * @return string + */ + public function fieldParentFilter($str) + { + $path = explode('.', rtrim($str, '.')); + array_pop($path); + + return implode('.', $path); + } + + /** + * Protects email address. + * + * @param string $str + * @return string + */ + public function safeEmailFilter($str) + { + static $list = [ + '"' => '"', + "'" => ''', + '&' => '&', + '<' => '<', + '>' => '>', + '@' => '@' + ]; + + $characters = mb_str_split($str, 1, 'UTF-8'); + + $encoded = ''; + foreach ($characters as $chr) { + $encoded .= $list[$chr] ?? (random_int(0, 1) ? '&#' . mb_ord($chr) . ';' : $chr); + } + + return $encoded; + } + + /** + * Returns array in a random order. + * + * @param array|Traversable $original + * @param int $offset Can be used to return only slice of the array. + * @return array + */ + public function randomizeFilter($original, $offset = 0) + { + if ($original instanceof Traversable) { + $original = iterator_to_array($original, false); + } + + if (!is_array($original)) { + return $original; + } + + $sorted = []; + $random = array_slice($original, $offset); + shuffle($random); + + $sizeOf = count($original); + for ($x = 0; $x < $sizeOf; $x++) { + if ($x < $offset) { + $sorted[] = $original[$x]; + } else { + $sorted[] = array_shift($random); + } + } + + return $sorted; + } + + /** + * Returns the modulus of an integer + * + * @param string|int $number + * @param int $divider + * @param array|null $items array of items to select from to return + * @return int + */ + public function modulusFilter($number, $divider, $items = null) + { + if (is_string($number)) { + $number = strlen($number); + } + + $remainder = $number % $divider; + + if (is_array($items)) { + return $items[$remainder] ?? $items[0]; + } + + return $remainder; + } + + /** + * Inflector supports following notations: + * + * `{{ 'person'|pluralize }} => people` + * `{{ 'shoes'|singularize }} => shoe` + * `{{ 'welcome page'|titleize }} => "Welcome Page"` + * `{{ 'send_email'|camelize }} => SendEmail` + * `{{ 'CamelCased'|underscorize }} => camel_cased` + * `{{ 'Something Text'|hyphenize }} => something-text` + * `{{ 'something_text_to_read'|humanize }} => "Something text to read"` + * `{{ '181'|monthize }} => 5` + * `{{ '10'|ordinalize }} => 10th` + * + * @param string $action + * @param string $data + * @param int|null $count + * @return string + */ + public function inflectorFilter($action, $data, $count = null) + { + $action .= 'ize'; + + /** @var Inflector $inflector */ + $inflector = $this->grav['inflector']; + + if (in_array( + $action, + ['titleize', 'camelize', 'underscorize', 'hyphenize', 'humanize', 'ordinalize', 'monthize'], + true + )) { + return $inflector->{$action}($data); + } + + if (in_array($action, ['pluralize', 'singularize'], true)) { + return $count ? $inflector->{$action}($data, $count) : $inflector->{$action}($data); + } + + return $data; + } + + /** + * Return MD5 hash from the input. + * + * @param string $str + * @return string + */ + public function md5Filter($str) + { + return md5($str); + } + + /** + * Return Base32 encoded string + * + * @param string $str + * @return string + */ + public function base32EncodeFilter($str) + { + return Base32::encode($str); + } + + /** + * Return Base32 decoded string + * + * @param string $str + * @return string + */ + public function base32DecodeFilter($str) + { + return Base32::decode($str); + } + + /** + * Return Base64 encoded string + * + * @param string $str + * @return string + */ + public function base64EncodeFilter($str) + { + return base64_encode((string) $str); + } + + /** + * Return Base64 decoded string + * + * @param string $str + * @return string|false + */ + public function base64DecodeFilter($str) + { + return base64_decode($str); + } + + /** + * Sorts a collection by key + * + * @param array $input + * @param string $filter + * @param int $direction + * @param int $sort_flags + * @return array + */ + public function sortByKeyFilter($input, $filter, $direction = SORT_ASC, $sort_flags = SORT_REGULAR) + { + return Utils::sortArrayByKey($input, $filter, $direction, $sort_flags); + } + + /** + * Return ksorted collection. + * + * @param array|null $array + * @return array + */ + public function ksortFilter($array) + { + if (null === $array) { + $array = []; + } + ksort($array); + + return $array; + } + + /** + * Wrapper for chunk_split() function + * + * @param string $value + * @param int $chars + * @param string $split + * @return string + */ + public function chunkSplitFilter($value, $chars, $split = '-') + { + return chunk_split($value, $chars, $split); + } + + /** + * determine if a string contains another + * + * @param string $haystack + * @param string $needle + * @return string|bool + * @todo returning $haystack here doesn't make much sense + */ + public function containsFilter($haystack, $needle) + { + if (empty($needle)) { + return $haystack; + } + + return (strpos($haystack, (string) $needle) !== false); + } + + /** + * Gets a human readable output for cron syntax + * + * @param string $at + * @return string + */ + public function niceCronFilter($at) + { + $cron = new Cron($at); + return $cron->getText('en'); + } + + /** + * @param string|mixed $str + * @param string $search + * @param string $replace + * @return string|mixed + */ + public function replaceLastFilter($str, $search, $replace) + { + if (is_string($str) && ($pos = mb_strrpos($str, $search)) !== false) { + $str = mb_substr($str, 0, $pos) . $replace . mb_substr($str, $pos + mb_strlen($search)); + } + + return $str; + } + + /** + * Get Cron object for a crontab 'at' format + * + * @param string $at + * @return CronExpression + */ + public function cronFunc($at) + { + return CronExpression::factory($at); + } + + /** + * displays a facebook style 'time ago' formatted date/time + * + * @param string $date + * @param bool $long_strings + * @param bool $show_tense + * @return string + */ + public function nicetimeFunc($date, $long_strings = true, $show_tense = true) + { + if (empty($date)) { + return $this->grav['language']->translate('GRAV.NICETIME.NO_DATE_PROVIDED'); + } + + if ($long_strings) { + $periods = [ + 'NICETIME.SECOND', + 'NICETIME.MINUTE', + 'NICETIME.HOUR', + 'NICETIME.DAY', + 'NICETIME.WEEK', + 'NICETIME.MONTH', + 'NICETIME.YEAR', + 'NICETIME.DECADE' + ]; + } else { + $periods = [ + 'NICETIME.SEC', + 'NICETIME.MIN', + 'NICETIME.HR', + 'NICETIME.DAY', + 'NICETIME.WK', + 'NICETIME.MO', + 'NICETIME.YR', + 'NICETIME.DEC' + ]; + } + + $lengths = ['60', '60', '24', '7', '4.35', '12', '10']; + + $now = time(); + + // check if unix timestamp + if ((string)(int)$date === (string)$date) { + $unix_date = $date; + } else { + $unix_date = strtotime($date); + } + + // check validity of date + if (empty($unix_date)) { + return $this->grav['language']->translate('GRAV.NICETIME.BAD_DATE'); + } + + // is it future date or past date + if ($now > $unix_date) { + $difference = $now - $unix_date; + $tense = $this->grav['language']->translate('GRAV.NICETIME.AGO'); + } elseif ($now == $unix_date) { + $difference = $now - $unix_date; + $tense = $this->grav['language']->translate('GRAV.NICETIME.JUST_NOW'); + } else { + $difference = $unix_date - $now; + $tense = $this->grav['language']->translate('GRAV.NICETIME.FROM_NOW'); + } + + for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths) - 1; $j++) { + $difference /= $lengths[$j]; + } + + $difference = round($difference); + + if ($difference != 1) { + $periods[$j] .= '_PLURAL'; + } + + if ($this->grav['language']->getTranslation( + $this->grav['language']->getLanguage(), + $periods[$j] . '_MORE_THAN_TWO' + ) + ) { + if ($difference > 2) { + $periods[$j] .= '_MORE_THAN_TWO'; + } + } + + $periods[$j] = $this->grav['language']->translate('GRAV.'.$periods[$j]); + + if ($now == $unix_date) { + return $tense; + } + + $time = "{$difference} {$periods[$j]}"; + $time .= $show_tense ? " {$tense}" : ''; + + return $time; + } + + /** + * Allow quick check of a string for XSS Vulnerabilities + * + * @param string|array $data + * @return bool|string|array + */ + public function xssFunc($data) + { + if (!is_array($data)) { + return Security::detectXss($data); + } + + $results = Security::detectXssFromArray($data); + $results_parts = array_map(static function ($value, $key) { + return $key.': \''.$value . '\''; + }, array_values($results), array_keys($results)); + + return implode(', ', $results_parts); + } + + /** + * Generates a random string with configurable length, prefix and suffix. + * Unlike the built-in `uniqid()`, this string is non-conflicting and safe + * + * @param int $length + * @param array $options + * @return string + * @throws \Exception + */ + public function uniqueId(int $length = 9, array $options = ['prefix' => '', 'suffix' => '']): string + { + return Utils::uniqueId($length, $options); + } + + /** + * @param string $string + * @return string + */ + public function absoluteUrlFilter($string) + { + $url = $this->grav['uri']->base(); + $string = preg_replace('/((?:href|src) *= *[\'"](?!(http|ftp)))/i', "$1$url", $string); + + return $string; + } + + /** + * @param array $context + * @param string $string + * @param bool $block Block or Line processing + * @return string + */ + public function markdownFunction($context, $string, $block = true) + { + $page = $context['page'] ?? null; + return Utils::processMarkdown($string, $block, $page); + } + + /** + * @param string $haystack + * @param string $needle + * @return bool + */ + public function startsWithFilter($haystack, $needle) + { + return Utils::startsWith($haystack, $needle); + } + + /** + * @param string $haystack + * @param string $needle + * @return bool + */ + public function endsWithFilter($haystack, $needle) + { + return Utils::endsWith($haystack, $needle); + } + + /** + * @param mixed $value + * @param null $default + * @return mixed|null + */ + public function definedDefaultFilter($value, $default = null) + { + return $value ?? $default; + } + + /** + * @param string $value + * @param string|null $chars + * @return string + */ + public function rtrimFilter($value, $chars = null) + { + return null !== $chars ? rtrim($value, $chars) : rtrim($value); + } + + /** + * @param string $value + * @param string|null $chars + * @return string + */ + public function ltrimFilter($value, $chars = null) + { + return null !== $chars ? ltrim($value, $chars) : ltrim($value); + } + + /** + * Returns a string from a value. If the value is array, return it json encoded + * + * @param mixed $value + * @return string + */ + public function stringFilter($value) + { + // Format the array as a string + if (is_array($value)) { + return json_encode($value); + } + + // Boolean becomes '1' or '0' + if (is_bool($value)) { + $value = (int)$value; + } + + // Cast the other values to string. + return (string)$value; + } + + /** + * Casts input to int. + * + * @param mixed $input + * @return int + */ + public function intFilter($input) + { + return (int) $input; + } + + /** + * Casts input to bool. + * + * @param mixed $input + * @return bool + */ + public function boolFilter($input) + { + return (bool) $input; + } + + /** + * Casts input to float. + * + * @param mixed $input + * @return float + */ + public function floatFilter($input) + { + return (float) $input; + } + + /** + * Casts input to array. + * + * @param mixed $input + * @return array + */ + public function arrayFilter($input) + { + if (is_array($input)) { + return $input; + } + + if (is_object($input)) { + if (method_exists($input, 'toArray')) { + return $input->toArray(); + } + + if ($input instanceof Iterator) { + return iterator_to_array($input); + } + } + + return (array)$input; + } + + /** + * @param array|object $value + * @param int|null $inline + * @param int|null $indent + * @return string + */ + public function yamlFilter($value, $inline = null, $indent = null): string + { + return Yaml::dump($value, $inline, $indent); + } + + /** + * @param Environment $twig + * @return string + */ + public function translate(Environment $twig, ...$args) + { + // If admin and tu filter provided, use it + if (isset($this->grav['admin'])) { + $numargs = count($args); + $lang = null; + + if (($numargs === 3 && is_array($args[1])) || ($numargs === 2 && !is_array($args[1]))) { + $lang = array_pop($args); + /** @var Language $language */ + $language = $this->grav['language']; + if (is_string($lang) && !$language->getLanguageCode($lang)) { + $args[] = $lang; + $lang = null; + } + } elseif ($numargs === 2 && is_array($args[1])) { + $subs = array_pop($args); + $args = array_merge($args, $subs); + } + + return $this->grav['admin']->translate($args, $lang); + } + + $translation = $this->grav['language']->translate($args); + + if ($this->config->get('system.languages.debug', false)) { + $debugger = $this->grav['debugger']; + $debugger->addMessage("$args[0] -> $translation", 'debug'); + } + + return $translation; + } + + /** + * Translate Strings + * + * @param string|array $args + * @param array|null $languages + * @param bool $array_support + * @param bool $html_out + * @return string + */ + public function translateLanguage($args, array $languages = null, $array_support = false, $html_out = false) + { + /** @var Language $language */ + $language = $this->grav['language']; + + return $language->translate($args, $languages, $array_support, $html_out); + } + + /** + * @param string $key + * @param string $index + * @param array|null $lang + * @return string + */ + public function translateArray($key, $index, $lang = null) + { + /** @var Language $language */ + $language = $this->grav['language']; + + return $language->translateArray($key, $index, $lang); + } + + /** + * Repeat given string x times. + * + * @param string $input + * @param int $multiplier + * + * @return string + */ + public function repeatFunc($input, $multiplier) + { + return str_repeat($input, (int) $multiplier); + } + + /** + * Return URL to the resource. + * + * @example {{ url('theme://images/logo.png')|default('http://www.placehold.it/150x100/f4f4f4') }} + * + * @param string $input Resource to be located. + * @param bool $domain True to include domain name. + * @param bool $failGracefully If true, return URL even if the file does not exist. + * @return string|false Returns url to the resource or null if resource was not found. + */ + public function urlFunc($input, $domain = false, $failGracefully = false) + { + return Utils::url($input, $domain, $failGracefully); + } + + /** + * This function will evaluate Twig $twig through the $environment, and return its results. + * + * @param array $context + * @param string $twig + * @return mixed + */ + public function evaluateTwigFunc($context, $twig) + { + + $loader = new FilesystemLoader('.'); + $env = new Environment($loader); + $env->addExtension($this); + + $template = $env->createTemplate($twig); + + return $template->render($context); + } + + /** + * This function will evaluate a $string through the $environment, and return its results. + * + * @param array $context + * @param string $string + * @return mixed + */ + public function evaluateStringFunc($context, $string) + { + return $this->evaluateTwigFunc($context, "{{ $string }}"); + } + + /** + * Based on Twig\Extension\Debug / twig_var_dump + * (c) 2011 Fabien Potencier + * + * @param Environment $env + * @param array $context + */ + public function dump(Environment $env, $context) + { + if (!$env->isDebug() || !$this->debugger) { + return; + } + + $count = func_num_args(); + if (2 === $count) { + $data = []; + foreach ($context as $key => $value) { + if (is_object($value)) { + if (method_exists($value, 'toArray')) { + $data[$key] = $value->toArray(); + } else { + $data[$key] = 'Object (' . get_class($value) . ')'; + } + } else { + $data[$key] = $value; + } + } + $this->debugger->addMessage($data, 'debug'); + } else { + for ($i = 2; $i < $count; $i++) { + $var = func_get_arg($i); + $this->debugger->addMessage($var, 'debug'); + } + } + } + + /** + * Output a Gist + * + * @param string $id + * @param string|false $file + * @return string + */ + public function gistFunc($id, $file = false) + { + $url = 'https://gist.github.com/' . $id . '.js'; + if ($file) { + $url .= '?file=' . $file; + } + return ''; + } + + /** + * Generate a random string + * + * @param int $count + * @return string + */ + public function randomStringFunc($count = 5) + { + return Utils::generateRandomString($count); + } + + /** + * Pad a string to a certain length with another string + * + * @param string $input + * @param int $pad_length + * @param string $pad_string + * @param int $pad_type + * @return string + */ + public static function padFilter($input, $pad_length, $pad_string = ' ', $pad_type = STR_PAD_RIGHT) + { + return str_pad($input, (int)$pad_length, $pad_string, $pad_type); + } + + /** + * Workaround for twig associative array initialization + * Returns a key => val array + * + * @param string $key key of item + * @param string $val value of item + * @param array|null $current_array optional array to add to + * @return array + */ + public function arrayKeyValueFunc($key, $val, $current_array = null) + { + if (empty($current_array)) { + return array($key => $val); + } + + $current_array[$key] = $val; + + return $current_array; + } + + /** + * Wrapper for array_intersect() method + * + * @param array|Collection $array1 + * @param array|Collection $array2 + * @return array|Collection + */ + public function arrayIntersectFunc($array1, $array2) + { + if ($array1 instanceof Collection && $array2 instanceof Collection) { + return $array1->intersect($array2)->toArray(); + } + + return array_intersect($array1, $array2); + } + + /** + * Translate a string + * + * @return string + */ + public function translateFunc() + { + return $this->grav['language']->translate(func_get_args()); + } + + /** + * Authorize an action. Returns true if the user is logged in and + * has the right to execute $action. + * + * @param string|array $action An action or a list of actions. Each + * entry can be a string like 'group.action' + * or without dot notation an associative + * array. + * @return bool Returns TRUE if the user is authorized to + * perform the action, FALSE otherwise. + */ + public function authorize($action) + { + // Admin can use Flex users even if the site does not; make sure we use the right version of the user. + $admin = $this->grav['admin'] ?? null; + if ($admin) { + $user = $admin->user; + } else { + /** @var UserInterface|null $user */ + $user = $this->grav['user'] ?? null; + } + + if (!$user) { + return false; + } + + if (is_array($action)) { + if (Utils::isAssoc($action)) { + // Handle nested access structure. + $actions = Utils::arrayFlattenDotNotation($action); + } else { + // Handle simple access list. + $actions = array_combine($action, array_fill(0, count($action), true)); + } + } else { + // Handle single action. + $actions = [(string)$action => true]; + } + + $count = count($actions); + foreach ($actions as $act => $authenticated) { + // Ignore 'admin.super' if it's not the only value to be checked. + if ($act === 'admin.super' && $count > 1 && $user instanceof FlexObjectInterface) { + continue; + } + + $auth = $user->authorize($act) ?? false; + if (is_bool($auth) && $auth === Utils::isPositive($authenticated)) { + return true; + } + } + + return false; + } + + /** + * Used to add a nonce to a form. Call {{ nonce_field('action') }} specifying a string representing the action. + * + * For maximum protection, ensure that the string representing the action is as specific as possible + * + * @param string $action the action + * @param string $nonceParamName a custom nonce param name + * @return string the nonce input field + */ + public function nonceFieldFunc($action, $nonceParamName = 'nonce') + { + $string = ''; + + return $string; + } + + /** + * Decodes string from JSON. + * + * @param string $str + * @param bool $assoc + * @param int $depth + * @param int $options + * @return array + */ + public function jsonDecodeFilter($str, $assoc = false, $depth = 512, $options = 0) + { + if ($str === null) { + $str = ''; + } + return json_decode(html_entity_decode($str, ENT_COMPAT | ENT_HTML401, 'UTF-8'), $assoc, $depth, $options); + } + + /** + * Used to retrieve a cookie value + * + * @param string $key The cookie name to retrieve + * @return string + */ + public function getCookie($key) + { + $cookie_value = filter_input(INPUT_COOKIE, $key); + + if ($cookie_value === null) { + return null; + } + + return htmlspecialchars(strip_tags($cookie_value), ENT_QUOTES, 'UTF-8'); + } + + /** + * Twig wrapper for PHP's preg_replace method + * + * @param string|string[] $subject the content to perform the replacement on + * @param string|string[] $pattern the regex pattern to use for matches + * @param string|string[] $replace the replacement value either as a string or an array of replacements + * @param int $limit the maximum possible replacements for each pattern in each subject + * @return string|string[]|null the resulting content + */ + public function regexReplace($subject, $pattern, $replace, $limit = -1) + { + return preg_replace($pattern, $replace, $subject, $limit); + } + + /** + * Twig wrapper for PHP's preg_grep method + * + * @param array $array + * @param string $regex + * @param int $flags + * @return array + */ + public function regexFilter($array, $regex, $flags = 0) + { + return preg_grep($regex, $array, $flags); + } + + /** + * Twig wrapper for PHP's preg_match method + * + * @param string $subject the content to perform the match on + * @param string $pattern the regex pattern to use for match + * @param int $flags + * @param int $offset + * @return array|false returns the matches if there is at least one match in the subject for a given pattern or null if not. + */ + public function regexMatch($subject, $pattern, $flags = 0, $offset = 0) + { + if (preg_match($pattern, $subject, $matches, $flags, $offset) === false) { + return false; + } + + return $matches; + } + + /** + * Twig wrapper for PHP's preg_split method + * + * @param string $subject the content to perform the split on + * @param string $pattern the regex pattern to use for split + * @param int $limit the maximum possible splits for the given pattern + * @param int $flags + * @return array|false the resulting array after performing the split operation + */ + public function regexSplit($subject, $pattern, $limit = -1, $flags = 0) + { + return preg_split($pattern, $subject, $limit, $flags); + } + + /** + * redirect browser from twig + * + * @param string $url the url to redirect to + * @param int $statusCode statusCode, default 303 + * @return void + */ + public function redirectFunc($url, $statusCode = 303) + { + $response = new Response($statusCode, ['location' => $url]); + + $this->grav->close($response); + } + + /** + * Generates an array containing a range of elements, optionally stepped + * + * @param int $start Minimum number, default 0 + * @param int $end Maximum number, default `getrandmax()` + * @param int $step Increment between elements in the sequence, default 1 + * @return array + */ + public function rangeFunc($start = 0, $end = 100, $step = 1) + { + return range($start, $end, $step); + } + + /** + * Check if HTTP_X_REQUESTED_WITH has been set to xmlhttprequest, + * in which case we may unsafely assume ajax. Non critical use only. + * + * @return bool True if HTTP_X_REQUESTED_WITH exists and has been set to xmlhttprequest + */ + public function isAjaxFunc() + { + return ( + !empty($_SERVER['HTTP_X_REQUESTED_WITH']) + && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'); + } + + /** + * Get the Exif data for a file + * + * @param string $image + * @param bool $raw + * @return mixed + */ + public function exifFunc($image, $raw = false) + { + if (isset($this->grav['exif'])) { + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + if ($locator->isStream($image)) { + $image = $locator->findResource($image); + } + + $exif_reader = $this->grav['exif']->getReader(); + + if ($image && file_exists($image) && $this->config->get('system.media.auto_metadata_exif') && $exif_reader) { + $exif_data = $exif_reader->read($image); + + if ($exif_data) { + if ($raw) { + return $exif_data->getRawData(); + } + + return $exif_data->getData(); + } + } + } + + return null; + } + + /** + * Simple function to read a file based on a filepath and output it + * + * @param string $filepath + * @return bool|string + */ + public function readFileFunc($filepath) + { + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + if ($locator->isStream($filepath)) { + $filepath = $locator->findResource($filepath); + } + + if ($filepath && file_exists($filepath)) { + return file_get_contents($filepath); + } + + return false; + } + + /** + * Process a folder as Media and return a media object + * + * @param string $media_dir + * @return Media|null + */ + public function mediaDirFunc($media_dir) + { + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + if ($locator->isStream($media_dir)) { + $media_dir = $locator->findResource($media_dir); + } + + if ($media_dir && file_exists($media_dir)) { + return new Media($media_dir); + } + + return null; + } + + /** + * Dump a variable to the browser + * + * @param mixed $var + * @return void + */ + public function vardumpFunc($var) + { + dump($var); + } + + /** + * Returns a nicer more readable filesize based on bytes + * + * @param int $bytes + * @return string + */ + public function niceFilesizeFunc($bytes) + { + return Utils::prettySize($bytes); + } + + /** + * Returns a nicer more readable number + * + * @param int|float|string $n + * @return string|bool + */ + public function niceNumberFunc($n) + { + if (!is_float($n) && !is_int($n)) { + if (!is_string($n) || $n === '') { + return false; + } + + // Strip any thousand formatting and find the first number. + $list = array_filter(preg_split("/\D+/", str_replace(',', '', $n))); + $n = reset($list); + + if (!is_numeric($n)) { + return false; + } + + $n = (float)$n; + } + + // now filter it; + if ($n > 1000000000000) { + return round($n/1000000000000, 2).' t'; + } + if ($n > 1000000000) { + return round($n/1000000000, 2).' b'; + } + if ($n > 1000000) { + return round($n/1000000, 2).' m'; + } + if ($n > 1000) { + return round($n/1000, 2).' k'; + } + + return number_format($n); + } + + /** + * Get a theme variable + * Will try to get the variable for the current page, if not found, it tries it's parent page on up to root. + * If still not found, will use the theme's configuration value, + * If still not found, will use the $default value passed in + * + * @param array $context Twig Context + * @param string $var variable to be found (using dot notation) + * @param null $default the default value to be used as last resort + * @param PageInterface|null $page an optional page to use for the current page + * @param bool $exists toggle to simply return the page where the variable is set, else null + * @return mixed + */ + public function themeVarFunc($context, $var, $default = null, $page = null, $exists = false) + { + $page = $page ?? $context['page'] ?? Grav::instance()['page'] ?? null; + + // Try to find var in the page headers + if ($page instanceof PageInterface && $page->exists()) { + // Loop over pages and look for header vars + while ($page && !$page->root()) { + $header = new Data((array)$page->header()); + $value = $header->get($var); + if (isset($value)) { + if ($exists) { + return $page; + } + + return $value; + } + $page = $page->parent(); + } + } + + if ($exists) { + return false; + } + + return Grav::instance()['config']->get('theme.' . $var, $default); + } + + /** + * Look for a page header variable in an array of pages working its way through until a value is found + * + * @param array $context + * @param string $var the variable to look for in the page header + * @param string|string[]|null $pages array of pages to check (current page upwards if not null) + * @return mixed + * @deprecated 1.7 Use themeVarFunc() instead + */ + public function pageHeaderVarFunc($context, $var, $pages = null) + { + if (is_array($pages)) { + $page = array_shift($pages); + } else { + $page = null; + } + return $this->themeVarFunc($context, $var, null, $page); + } + + /** + * takes an array of classes, and if they are not set on body_classes + * look to see if they are set in theme config + * + * @param array $context + * @param string|string[] $classes + * @return string + */ + public function bodyClassFunc($context, $classes) + { + + $header = $context['page']->header(); + $body_classes = $header->body_classes ?? ''; + + foreach ((array)$classes as $class) { + if (!empty($body_classes) && Utils::contains($body_classes, $class)) { + continue; + } + + $val = $this->config->get('theme.' . $class, false) ? $class : false; + $body_classes .= $val ? ' ' . $val : ''; + } + + return $body_classes; + } + + /** + * Returns the content of an SVG image and adds extra classes as needed + * + * @param string $path + * @param string|null $classes + * @return string|string[]|null + */ + public static function svgImageFunction($path, $classes = null, $strip_style = false) + { + $path = Utils::fullPath($path); + + $classes = $classes ?: ''; + + if (file_exists($path) && !is_dir($path)) { + $svg = file_get_contents($path); + $classes = " inline-block $classes"; + $matched = false; + + //Remove xml tag if it exists + $svg = preg_replace('/^<\?xml.*\?>/','', $svg); + + //Strip style if needed + if ($strip_style) { + $svg = preg_replace('//s', '', $svg); + } + + //Look for existing class + $svg = preg_replace_callback('/^]*(class=\"([^"]*)\")[^>]*>/', function($matches) use ($classes, &$matched) { + if (isset($matches[2])) { + $new_classes = $matches[2] . $classes; + $matched = true; + return str_replace($matches[1], "class=\"$new_classes\"", $matches[0]); + } + return $matches[0]; + }, $svg + ); + + // no matches found just add the class + if (!$matched) { + $classes = trim($classes); + $svg = str_replace('jsonSerialize(); + } elseif (method_exists($data, 'toArray')) { + $data = $data->toArray(); + } else { + $data = json_decode(json_encode($data), true); + } + } + + return Yaml::dump($data, $inline); + } + + /** + * Decode/Parse data from YAML format + * + * @param string $data + * @return array + */ + public function yamlDecodeFilter($data) + { + return Yaml::parse($data); + } + + /** + * Function/Filter to return the type of variable + * + * @param mixed $var + * @return string + */ + public function getTypeFunc($var) + { + return gettype($var); + } + + /** + * Function/Filter to test type of variable + * + * @param mixed $var + * @param string|null $typeTest + * @param string|null $className + * @return bool + */ + public function ofTypeFunc($var, $typeTest = null, $className = null) + { + + switch ($typeTest) { + default: + return false; + + case 'array': + return is_array($var); + + case 'bool': + return is_bool($var); + + case 'class': + return is_object($var) === true && get_class($var) === $className; + + case 'float': + return is_float($var); + + case 'int': + return is_int($var); + + case 'numeric': + return is_numeric($var); + + case 'object': + return is_object($var); + + case 'scalar': + return is_scalar($var); + + case 'string': + return is_string($var); + } + } + + /** + * @param Environment $env + * @param array $array + * @param callable|string $arrow + * @return array|CallbackFilterIterator + * @throws RuntimeError + */ + function filterFunc(Environment $env, $array, $arrow) + { + if (!$arrow instanceof \Closure && !is_string($arrow) || Utils::isDangerousFunction($arrow)) { + throw new RuntimeError('Twig |filter("' . $arrow . '") is not allowed.'); + } + + return twig_array_filter($env, $array, $arrow); + } + + /** + * @param Environment $env + * @param array $array + * @param callable|string $arrow + * @return array|CallbackFilterIterator + * @throws RuntimeError + */ + function mapFunc(Environment $env, $array, $arrow) + { + if (!$arrow instanceof \Closure && !is_string($arrow) || Utils::isDangerousFunction($arrow)) { + throw new RuntimeError('Twig |map("' . $arrow . '") is not allowed.'); + } + + return twig_array_map($env, $array, $arrow); + } + + /** + * @param Environment $env + * @param array $array + * @param callable|string $arrow + * @return array|CallbackFilterIterator + * @throws RuntimeError + */ + function reduceFunc(Environment $env, $array, $arrow) + { + if (!$arrow instanceof \Closure && !is_string($arrow) || Utils::isDangerousFunction($arrow)) { + throw new RuntimeError('Twig |reduce("' . $arrow . '") is not allowed.'); + } + + return twig_array_map($env, $array, $arrow); + } +} diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeCache.php b/system/src/Grav/Common/Twig/Node/TwigNodeCache.php new file mode 100644 index 0000000..39b3d08 --- /dev/null +++ b/system/src/Grav/Common/Twig/Node/TwigNodeCache.php @@ -0,0 +1,93 @@ + $body]; + + if ($key !== null) { + $nodes['key'] = $key; + } + + if ($lifetime !== null) { + $nodes['lifetime'] = $lifetime; + } + + parent::__construct($nodes, $defaults, $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler->addDebugInfo($this); + + + // Generate the cache key + if ($this->hasNode('key')) { + $compiler + ->write('$key = "twigcache-" . ') + ->subcompile($this->getNode('key')) + ->raw(";\n"); + } else { + $compiler + ->write('$key = ') + ->string($this->getAttribute('key')) + ->raw(";\n"); + } + + // Set the cache timeout + if ($this->hasNode('lifetime')) { + $compiler + ->write('$lifetime = ') + ->subcompile($this->getNode('lifetime')) + ->raw(";\n"); + } else { + $compiler + ->write('$lifetime = ') + ->write($this->getAttribute('lifetime')) + ->raw(";\n"); + } + + $compiler + ->write("\$cache = \\Grav\\Common\\Grav::instance()['cache'];\n") + ->write("\$cache_body = \$cache->fetch(\$key);\n") + ->write("if (\$cache_body === false) {\n") + ->indent() + ->write("\\Grav\\Common\\Grav::instance()['debugger']->addMessage(\"Cache Key: \$key, Lifetime: \$lifetime\");\n") + ->write("ob_start();\n") + ->indent() + ->subcompile($this->getNode('body')) + ->outdent() + ->write("\n") + ->write("\$cache_body = ob_get_clean();\n") + ->write("\$cache->save(\$key, \$cache_body, \$lifetime);\n") + ->outdent() + ->write("}\n") + ->write("echo '' === \$cache_body ? '' : new Markup(\$cache_body, \$this->env->getCharset());\n"); + } +} \ No newline at end of file diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeLink.php b/system/src/Grav/Common/Twig/Node/TwigNodeLink.php new file mode 100644 index 0000000..17a8fd3 --- /dev/null +++ b/system/src/Grav/Common/Twig/Node/TwigNodeLink.php @@ -0,0 +1,114 @@ + $file, 'group' => $group, 'priority' => $priority, 'attributes' => $attributes]; + $nodes = array_filter($nodes); + + parent::__construct($nodes, ['rel' => $rel], $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Compiler $compiler A Twig Compiler instance + * @return void + * @throws LogicException + */ + public function compile(Compiler $compiler): void + { + $compiler->addDebugInfo($this); + if (!$this->hasNode('file')) { + return; + } + + $compiler->write('$attributes = [\'rel\' => \'' . $this->getAttribute('rel') . '\'];' . "\n"); + if ($this->hasNode('attributes')) { + $compiler + ->write('$attributes += ') + ->subcompile($this->getNode('attributes')) + ->raw(';' . PHP_EOL) + ->write('if (!is_array($attributes)) {' . PHP_EOL) + ->indent() + ->write("throw new UnexpectedValueException('{% {$this->tagName} with x %}: x is not an array');" . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); + } + + if ($this->hasNode('group')) { + $compiler + ->write('$group = ') + ->subcompile($this->getNode('group')) + ->raw(';' . PHP_EOL) + ->write('if (!is_string($group)) {' . PHP_EOL) + ->indent() + ->write("throw new UnexpectedValueException('{% {$this->tagName} in x %}: x is not a string');" . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); + } else { + $compiler->write('$group = \'head\';' . PHP_EOL); + } + + if ($this->hasNode('priority')) { + $compiler + ->write('$priority = (int)(') + ->subcompile($this->getNode('priority')) + ->raw(');' . PHP_EOL); + } else { + $compiler->write('$priority = 10;' . PHP_EOL); + } + + $compiler->write("\$assets = \\Grav\\Common\\Grav::instance()['assets'];" . PHP_EOL); + $compiler->write("\$block = \$context['block'] ?? null;" . PHP_EOL); + + $compiler + ->write('$file = (string)(') + ->subcompile($this->getNode('file')) + ->raw(');' . PHP_EOL); + + // Assets support. + $compiler->write('$assets->addLink($file, [\'group\' => $group, \'priority\' => $priority] + $attributes);' . PHP_EOL); + + // HtmlBlock support. + $compiler + ->write('if ($block instanceof \Grav\Framework\ContentBlock\HtmlBlock) {' . PHP_EOL) + ->indent() + ->write('$block->addLink([\'href\'=> $file] + $attributes, $priority, $group);' . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); + } +} diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeMarkdown.php b/system/src/Grav/Common/Twig/Node/TwigNodeMarkdown.php new file mode 100644 index 0000000..f671709 --- /dev/null +++ b/system/src/Grav/Common/Twig/Node/TwigNodeMarkdown.php @@ -0,0 +1,52 @@ + $body], [], $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Compiler $compiler A Twig Compiler instance + * @return void + */ + public function compile(Compiler $compiler): void + { + $compiler + ->addDebugInfo($this) + ->write('ob_start();' . PHP_EOL) + ->subcompile($this->getNode('body')) + ->write('$content = ob_get_clean();' . PHP_EOL) + ->write('preg_match("/^\s*/", $content, $matches);' . PHP_EOL) + ->write('$lines = explode("\n", $content);' . PHP_EOL) + ->write('$content = preg_replace(\'/^\' . $matches[0]. \'/\', "", $lines);' . PHP_EOL) + ->write('$content = join("\n", $content);' . PHP_EOL) + ->write('echo $this->env->getExtension(\'Grav\Common\Twig\Extension\GravExtension\')->markdownFunction($context, $content);' . PHP_EOL); + } +} diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeRender.php b/system/src/Grav/Common/Twig/Node/TwigNodeRender.php new file mode 100644 index 0000000..eca9a66 --- /dev/null +++ b/system/src/Grav/Common/Twig/Node/TwigNodeRender.php @@ -0,0 +1,84 @@ + $object, 'layout' => $layout, 'context' => $context]; + $nodes = array_filter($nodes); + + parent::__construct($nodes, [], $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Compiler $compiler A Twig Compiler instance + * @return void + * @throws LogicException + */ + public function compile(Compiler $compiler): void + { + $compiler->addDebugInfo($this); + $compiler->write('$object = ')->subcompile($this->getNode('object'))->raw(';' . PHP_EOL); + + if ($this->hasNode('layout')) { + $layout = $this->getNode('layout'); + $compiler->write('$layout = ')->subcompile($layout)->raw(';' . PHP_EOL); + } else { + $compiler->write('$layout = null;' . PHP_EOL); + } + + if ($this->hasNode('context')) { + $context = $this->getNode('context'); + $compiler->write('$attributes = ')->subcompile($context)->raw(';' . PHP_EOL); + } else { + $compiler->write('$attributes = null;' . PHP_EOL); + } + + $compiler + ->write('$html = $object->render($layout, $attributes ?? []);' . PHP_EOL) + ->write('$block = $context[\'block\'] ?? null;' . PHP_EOL) + ->write('if ($block instanceof \Grav\Framework\ContentBlock\ContentBlock && $html instanceof \Grav\Framework\ContentBlock\ContentBlock) {' . PHP_EOL) + ->indent() + ->write('$block->addBlock($html);' . PHP_EOL) + ->write('echo $html->getToken();' . PHP_EOL) + ->outdent() + ->write('} else {' . PHP_EOL) + ->indent() + ->write('\Grav\Common\Assets\BlockAssets::registerAssets($html);' . PHP_EOL) + ->write('echo (string)$html;' . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL) + ; + } +} diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeScript.php b/system/src/Grav/Common/Twig/Node/TwigNodeScript.php new file mode 100644 index 0000000..b9172d0 --- /dev/null +++ b/system/src/Grav/Common/Twig/Node/TwigNodeScript.php @@ -0,0 +1,142 @@ + $body, 'file' => $file, 'group' => $group, 'priority' => $priority, 'attributes' => $attributes]; + $nodes = array_filter($nodes); + + parent::__construct($nodes, ['type' => $type], $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Compiler $compiler A Twig Compiler instance + * @return void + * @throws LogicException + */ + public function compile(Compiler $compiler): void + { + $compiler->addDebugInfo($this); + + if ($this->hasNode('attributes')) { + $compiler + ->write('$attributes = ') + ->subcompile($this->getNode('attributes')) + ->raw(';' . PHP_EOL) + ->write('if (!is_array($attributes)) {' . PHP_EOL) + ->indent() + ->write("throw new UnexpectedValueException('{% {$this->tagName} with x %}: x is not an array');" . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); + } else { + $compiler->write('$attributes = [];' . PHP_EOL); + } + + if ($this->hasNode('group')) { + $compiler + ->write('$group = ') + ->subcompile($this->getNode('group')) + ->raw(';' . PHP_EOL) + ->write('if (!is_string($group)) {' . PHP_EOL) + ->indent() + ->write("throw new UnexpectedValueException('{% {$this->tagName} in x %}: x is not a string');" . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); + } else { + $compiler->write('$group = \'head\';' . PHP_EOL); + } + + if ($this->hasNode('priority')) { + $compiler + ->write('$priority = (int)(') + ->subcompile($this->getNode('priority')) + ->raw(');' . PHP_EOL); + } else { + $compiler->write('$priority = 10;' . PHP_EOL); + } + + $compiler->write("\$assets = \\Grav\\Common\\Grav::instance()['assets'];" . PHP_EOL); + $compiler->write("\$block = \$context['block'] ?? null;" . PHP_EOL); + + if ($this->hasNode('file')) { + // JS file. + $compiler + ->write('$file = (string)(') + ->subcompile($this->getNode('file')) + ->raw(');' . PHP_EOL); + + $method = $this->getAttribute('type') === 'module' ? 'addJsModule' : 'addJs'; + + // Assets support. + $compiler->write('$assets->' . $method . '($file, [\'group\' => $group, \'priority\' => $priority] + $attributes);' . PHP_EOL); + + $method = $this->getAttribute('type') === 'module' ? 'addModule' : 'addScript'; + + // HtmlBlock support. + $compiler + ->write('if ($block instanceof \Grav\Framework\ContentBlock\HtmlBlock) {' . PHP_EOL) + ->indent() + ->write('$block->' . $method . '([\'src\'=> $file] + $attributes, $priority, $group);' . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); + + } else { + // Inline script. + $compiler + ->write('ob_start();' . PHP_EOL) + ->subcompile($this->getNode('body')) + ->write('$content = ob_get_clean();' . PHP_EOL); + + $method = $this->getAttribute('type') === 'module' ? 'addInlineJsModule' : 'addInlineJs'; + + // Assets support. + $compiler->write('$assets->' . $method . '($content, [\'group\' => $group, \'priority\' => $priority] + $attributes);' . PHP_EOL); + + $method = $this->getAttribute('type') === 'module' ? 'addInlineModule' : 'addInlineScript'; + + // HtmlBlock support. + $compiler + ->write('if ($block instanceof \Grav\Framework\ContentBlock\HtmlBlock) {' . PHP_EOL) + ->indent() + ->write('$block->' . $method . '([\'content\'=> $content] + $attributes, $priority, $group);' . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); + } + } +} diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeStyle.php b/system/src/Grav/Common/Twig/Node/TwigNodeStyle.php new file mode 100644 index 0000000..4ba112d --- /dev/null +++ b/system/src/Grav/Common/Twig/Node/TwigNodeStyle.php @@ -0,0 +1,133 @@ + $body, 'file' => $file, 'group' => $group, 'priority' => $priority, 'attributes' => $attributes]; + $nodes = array_filter($nodes); + + parent::__construct($nodes, [], $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Compiler $compiler A Twig Compiler instance + * @return void + * @throws LogicException + */ + public function compile(Compiler $compiler): void + { + $compiler->addDebugInfo($this); + + if ($this->hasNode('attributes')) { + $compiler + ->write('$attributes = ') + ->subcompile($this->getNode('attributes')) + ->raw(';' . PHP_EOL) + ->write('if (!is_array($attributes)) {' . PHP_EOL) + ->indent() + ->write("throw new UnexpectedValueException('{% {$this->tagName} with x %}: x is not an array');" . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); + } else { + $compiler->write('$attributes = [];' . PHP_EOL); + } + + if ($this->hasNode('group')) { + $compiler + ->write('$group = ') + ->subcompile($this->getNode('group')) + ->raw(';' . PHP_EOL) + ->write('if (!is_string($group)) {' . PHP_EOL) + ->indent() + ->write("throw new UnexpectedValueException('{% {$this->tagName} in x %}: x is not a string');" . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); + } else { + $compiler->write('$group = \'head\';' . PHP_EOL); + } + + if ($this->hasNode('priority')) { + $compiler + ->write('$priority = (int)(') + ->subcompile($this->getNode('priority')) + ->raw(');' . PHP_EOL); + } else { + $compiler->write('$priority = 10;' . PHP_EOL); + } + + $compiler->write("\$assets = \\Grav\\Common\\Grav::instance()['assets'];" . PHP_EOL); + $compiler->write("\$block = \$context['block'] ?? null;" . PHP_EOL); + + if ($this->hasNode('file')) { + // CSS file. + $compiler + ->write('$file = (string)(') + ->subcompile($this->getNode('file')) + ->raw(');' . PHP_EOL); + + // Assets support. + $compiler->write('$assets->addCss($file, [\'group\' => $group, \'priority\' => $priority] + $attributes);' . PHP_EOL); + + // HtmlBlock support. + $compiler + ->write('if ($block instanceof \Grav\Framework\ContentBlock\HtmlBlock) {' . PHP_EOL) + ->indent() + ->write('$block->addStyle([\'href\'=> $file] + $attributes, $priority, $group);' . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); + + } else { + // Inline style. + $compiler + ->write('ob_start();' . PHP_EOL) + ->subcompile($this->getNode('body')) + ->write('$content = ob_get_clean();' . PHP_EOL); + + // Assets support. + $compiler->write('$assets->addInlineCss($content, [\'group\' => $group, \'priority\' => $priority] + $attributes);' . PHP_EOL); + + // HtmlBlock support. + $compiler + ->write('if ($block instanceof \Grav\Framework\ContentBlock\HtmlBlock) {' . PHP_EOL) + ->indent() + ->write('$block->addInlineStyle([\'content\'=> $content] + $attributes, $priority, $group);' . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); + } + } +} diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeSwitch.php b/system/src/Grav/Common/Twig/Node/TwigNodeSwitch.php new file mode 100644 index 0000000..8dcc9dd --- /dev/null +++ b/system/src/Grav/Common/Twig/Node/TwigNodeSwitch.php @@ -0,0 +1,88 @@ + $value, 'cases' => $cases, 'default' => $default]; + $nodes = array_filter($nodes); + + parent::__construct($nodes, [], $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Compiler $compiler A Twig Compiler instance + * @return void + */ + public function compile(Compiler $compiler): void + { + $compiler + ->addDebugInfo($this) + ->write('switch (') + ->subcompile($this->getNode('value')) + ->raw(") {\n") + ->indent(); + + /** @var Node $case */ + foreach ($this->getNode('cases') as $case) { + if (!$case->hasNode('body')) { + continue; + } + + foreach ($case->getNode('values') as $value) { + $compiler + ->write('case ') + ->subcompile($value) + ->raw(":\n"); + } + + $compiler + ->write("{\n") + ->indent() + ->subcompile($case->getNode('body')) + ->write("break;\n") + ->outdent() + ->write("}\n"); + } + + if ($this->hasNode('default')) { + $compiler + ->write("default:\n") + ->write("{\n") + ->indent() + ->subcompile($this->getNode('default')) + ->outdent() + ->write("}\n"); + } + + $compiler + ->outdent() + ->write("}\n"); + } +} diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeThrow.php b/system/src/Grav/Common/Twig/Node/TwigNodeThrow.php new file mode 100644 index 0000000..fb65c71 --- /dev/null +++ b/system/src/Grav/Common/Twig/Node/TwigNodeThrow.php @@ -0,0 +1,52 @@ + $message], ['code' => $code], $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Compiler $compiler A Twig Compiler instance + * @return void + * @throws LogicException + */ + public function compile(Compiler $compiler): void + { + $compiler->addDebugInfo($this); + + $compiler + ->write('throw new \Grav\Common\Twig\Exception\TwigException(') + ->subcompile($this->getNode('message')) + ->write(', ') + ->write($this->getAttribute('code') ?: 500) + ->write(");\n"); + } +} diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeTryCatch.php b/system/src/Grav/Common/Twig/Node/TwigNodeTryCatch.php new file mode 100644 index 0000000..ddaf49d --- /dev/null +++ b/system/src/Grav/Common/Twig/Node/TwigNodeTryCatch.php @@ -0,0 +1,67 @@ + $try, 'catch' => $catch]; + $nodes = array_filter($nodes); + + parent::__construct($nodes, [], $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Compiler $compiler A Twig Compiler instance + * @return void + * @throws LogicException + */ + public function compile(Compiler $compiler): void + { + $compiler->addDebugInfo($this); + + $compiler->write('try {'); + + $compiler + ->indent() + ->subcompile($this->getNode('try')) + ->outdent() + ->write('} catch (\Exception $e) {' . "\n") + ->indent() + ->write('if (isset($context[\'grav\'][\'debugger\'])) $context[\'grav\'][\'debugger\']->addException($e);' . "\n") + ->write('$context[\'e\'] = $e;' . "\n"); + + if ($this->hasNode('catch')) { + $compiler->subcompile($this->getNode('catch')); + } + + $compiler + ->outdent() + ->write("}\n"); + } +} diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserCache.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserCache.php new file mode 100644 index 0000000..831abf0 --- /dev/null +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserCache.php @@ -0,0 +1,74 @@ +parser->getStream(); + $lineno = $token->getLine(); + + // Parse the optional key and timeout parameters + $defaults = [ + 'key' => $this->parser->getVarName() . $lineno, + 'lifetime' => Grav::instance()['cache']->getLifetime() + ]; + + $key = null; + $lifetime = null; + while (!$stream->test(Token::BLOCK_END_TYPE)) { + if ($stream->test(Token::STRING_TYPE)) { + $key = $this->parser->getExpressionParser()->parseExpression(); + } elseif ($stream->test(Token::NUMBER_TYPE)) { + $lifetime = $this->parser->getExpressionParser()->parseExpression(); + } else { + throw new \Twig\Error\SyntaxError("Unexpected token type in cache tag.", $token->getLine(), $stream->getSourceContext()); + } + } + + $stream->expect(Token::BLOCK_END_TYPE); + + // Parse the content inside the cache block + $body = $this->parser->subparse([$this, 'decideCacheEnd'], true); + + $stream->expect(Token::BLOCK_END_TYPE); + + return new TwigNodeCache($body, $key, $lifetime, $defaults, $lineno, $this->getTag()); + } + + public function decideCacheEnd(Token $token): bool + { + return $token->test('endcache'); + } + + public function getTag(): string + { + return 'cache'; + } +} \ No newline at end of file diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserLink.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserLink.php new file mode 100644 index 0000000..737d05f --- /dev/null +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserLink.php @@ -0,0 +1,109 @@ +getLine(); + + [$rel, $file, $group, $priority, $attributes] = $this->parseArguments($token); + + return new TwigNodeLink($rel, $file, $group, $priority, $attributes, $lineno, $this->getTag()); + } + + /** + * @param Token $token + * @return array + */ + protected function parseArguments(Token $token): array + { + $stream = $this->parser->getStream(); + + + $rel = null; + if ($stream->test(Token::NAME_TYPE, $this->rel)) { + $rel = $stream->getCurrent()->getValue(); + $stream->next(); + } + + $file = null; + if (!$stream->test(Token::NAME_TYPE) && !$stream->test(Token::BLOCK_END_TYPE)) { + $file = $this->parser->getExpressionParser()->parseExpression(); + } + + $group = null; + if ($stream->nextIf(Token::NAME_TYPE, 'at')) { + $group = $this->parser->getExpressionParser()->parseExpression(); + } + + $priority = null; + if ($stream->nextIf(Token::NAME_TYPE, 'priority')) { + $stream->expect(Token::PUNCTUATION_TYPE, ':'); + $priority = $this->parser->getExpressionParser()->parseExpression(); + } + + $attributes = null; + if ($stream->nextIf(Token::NAME_TYPE, 'with')) { + $attributes = $this->parser->getExpressionParser()->parseExpression(); + } + + $stream->expect(Token::BLOCK_END_TYPE); + + return [$rel, $file, $group, $priority, $attributes]; + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag(): string + { + return 'link'; + } +} diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserMarkdown.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserMarkdown.php new file mode 100644 index 0000000..581df50 --- /dev/null +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserMarkdown.php @@ -0,0 +1,59 @@ +getLine(); + $this->parser->getStream()->expect(Token::BLOCK_END_TYPE); + $body = $this->parser->subparse([$this, 'decideMarkdownEnd'], true); + $this->parser->getStream()->expect(Token::BLOCK_END_TYPE); + return new TwigNodeMarkdown($body, $lineno, $this->getTag()); + } + /** + * Decide if current token marks end of Markdown block. + * + * @param Token $token + * @return bool + */ + public function decideMarkdownEnd(Token $token): bool + { + return $token->test('endmarkdown'); + } + /** + * {@inheritdoc} + */ + public function getTag(): string + { + return 'markdown'; + } +} diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserRender.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserRender.php new file mode 100644 index 0000000..f892ea2 --- /dev/null +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserRender.php @@ -0,0 +1,74 @@ +getLine(); + + [$object, $layout, $context] = $this->parseArguments($token); + + return new TwigNodeRender($object, $layout, $context, $lineno, $this->getTag()); + } + + /** + * @param Token $token + * @return array + */ + protected function parseArguments(Token $token): array + { + $stream = $this->parser->getStream(); + + $object = $this->parser->getExpressionParser()->parseExpression(); + + $layout = null; + if ($stream->nextIf(Token::NAME_TYPE, 'layout')) { + $stream->expect(Token::PUNCTUATION_TYPE, ':'); + $layout = $this->parser->getExpressionParser()->parseExpression(); + } + + $context = null; + if ($stream->nextIf(Token::NAME_TYPE, 'with')) { + $context = $this->parser->getExpressionParser()->parseExpression(); + } + + $stream->expect(Token::BLOCK_END_TYPE); + + return [$object, $layout, $context]; + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag(): string + { + return 'render'; + } +} diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserScript.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserScript.php new file mode 100644 index 0000000..073d93d --- /dev/null +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserScript.php @@ -0,0 +1,132 @@ +getLine(); + $stream = $this->parser->getStream(); + + [$type, $file, $group, $priority, $attributes] = $this->parseArguments($token); + + $content = null; + if ($file === null) { + $content = $this->parser->subparse([$this, 'decideBlockEnd'], true); + $stream->expect(Token::BLOCK_END_TYPE); + } + + return new TwigNodeScript($content, $type, $file, $group, $priority, $attributes, $lineno, $this->getTag()); + } + + /** + * @param Token $token + * @return array + */ + protected function parseArguments(Token $token): array + { + $stream = $this->parser->getStream(); + + // Look for deprecated {% script ... in ... %} + if (!$stream->test(Token::BLOCK_END_TYPE) && !$stream->test(Token::OPERATOR_TYPE, 'in')) { + $i = 0; + do { + $token = $stream->look(++$i); + if ($token->test(Token::BLOCK_END_TYPE)) { + break; + } + if ($token->test(Token::OPERATOR_TYPE, 'in') && $stream->look($i+1)->test(Token::STRING_TYPE)) { + user_error("Twig: Using {% script ... in ... %} is deprecated, use {% script ... at ... %} instead", E_USER_DEPRECATED); + + break; + } + } while (true); + } + + $type = null; + if ($stream->test(Token::NAME_TYPE, 'module')) { + $type = $stream->getCurrent()->getValue(); + $stream->next(); + } + + $file = null; + if (!$stream->test(Token::NAME_TYPE) && !$stream->test(Token::OPERATOR_TYPE, 'in') && !$stream->test(Token::BLOCK_END_TYPE)) { + $file = $this->parser->getExpressionParser()->parseExpression(); + } + + $group = null; + if ($stream->nextIf(Token::NAME_TYPE, 'at') || $stream->nextIf(Token::OPERATOR_TYPE, 'in')) { + $group = $this->parser->getExpressionParser()->parseExpression(); + } + + $priority = null; + if ($stream->nextIf(Token::NAME_TYPE, 'priority')) { + $stream->expect(Token::PUNCTUATION_TYPE, ':'); + $priority = $this->parser->getExpressionParser()->parseExpression(); + } + + $attributes = null; + if ($stream->nextIf(Token::NAME_TYPE, 'with')) { + $attributes = $this->parser->getExpressionParser()->parseExpression(); + } + + $stream->expect(Token::BLOCK_END_TYPE); + + return [$type, $file, $group, $priority, $attributes]; + } + + /** + * @param Token $token + * @return bool + */ + public function decideBlockEnd(Token $token): bool + { + return $token->test('endscript'); + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag(): string + { + return 'script'; + } +} diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserStyle.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserStyle.php new file mode 100644 index 0000000..590394d --- /dev/null +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserStyle.php @@ -0,0 +1,119 @@ +getLine(); + $stream = $this->parser->getStream(); + + [$file, $group, $priority, $attributes] = $this->parseArguments($token); + + $content = null; + if (!$file) { + $content = $this->parser->subparse([$this, 'decideBlockEnd'], true); + $stream->expect(Token::BLOCK_END_TYPE); + } + + return new TwigNodeStyle($content, $file, $group, $priority, $attributes, $lineno, $this->getTag()); + } + + /** + * @param Token $token + * @return array + */ + protected function parseArguments(Token $token): array + { + $stream = $this->parser->getStream(); + + // Look for deprecated {% style ... in ... %} + if (!$stream->test(Token::BLOCK_END_TYPE) && !$stream->test(Token::OPERATOR_TYPE, 'in')) { + $i = 0; + do { + $token = $stream->look(++$i); + if ($token->test(Token::BLOCK_END_TYPE)) { + break; + } + if ($token->test(Token::OPERATOR_TYPE, 'in') && $stream->look($i+1)->test(Token::STRING_TYPE)) { + user_error("Twig: Using {% style ... in ... %} is deprecated, use {% style ... at ... %} instead", E_USER_DEPRECATED); + + break; + } + } while (true); + } + + $file = null; + if (!$stream->test(Token::NAME_TYPE) && !$stream->test(Token::OPERATOR_TYPE, 'in') && !$stream->test(Token::BLOCK_END_TYPE)) { + $file = $this->parser->getExpressionParser()->parseExpression(); + } + + $group = null; + if ($stream->nextIf(Token::NAME_TYPE, 'at') || $stream->nextIf(Token::OPERATOR_TYPE, 'in')) { + $group = $this->parser->getExpressionParser()->parseExpression(); + } + + $priority = null; + if ($stream->nextIf(Token::NAME_TYPE, 'priority')) { + $stream->expect(Token::PUNCTUATION_TYPE, ':'); + $priority = $this->parser->getExpressionParser()->parseExpression(); + } + + $attributes = null; + if ($stream->nextIf(Token::NAME_TYPE, 'with')) { + $attributes = $this->parser->getExpressionParser()->parseExpression(); + } + + $stream->expect(Token::BLOCK_END_TYPE); + + return [$file, $group, $priority, $attributes]; + } + + /** + * @param Token $token + * @return bool + */ + public function decideBlockEnd(Token $token): bool + { + return $token->test('endstyle'); + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag(): string + { + return 'style'; + } +} diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserSwitch.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserSwitch.php new file mode 100644 index 0000000..c2806f8 --- /dev/null +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserSwitch.php @@ -0,0 +1,132 @@ +getLine(); + $stream = $this->parser->getStream(); + + $name = $this->parser->getExpressionParser()->parseExpression(); + $stream->expect(Token::BLOCK_END_TYPE); + + // There can be some whitespace between the {% switch %} and first {% case %} tag. + while ($stream->getCurrent()->getType() === Token::TEXT_TYPE && trim($stream->getCurrent()->getValue()) === '') { + $stream->next(); + } + + $stream->expect(Token::BLOCK_START_TYPE); + + $expressionParser = $this->parser->getExpressionParser(); + + $default = null; + $cases = []; + $end = false; + + while (!$end) { + $next = $stream->next(); + + switch ($next->getValue()) { + case 'case': + $values = []; + + while (true) { + $values[] = $expressionParser->parsePrimaryExpression(); + // Multiple allowed values? + if ($stream->test(Token::OPERATOR_TYPE, 'or')) { + $stream->next(); + } else { + break; + } + } + + $stream->expect(Token::BLOCK_END_TYPE); + $body = $this->parser->subparse([$this, 'decideIfFork']); + $cases[] = new Node([ + 'values' => new Node($values), + 'body' => $body + ]); + break; + + case 'default': + $stream->expect(Token::BLOCK_END_TYPE); + $default = $this->parser->subparse([$this, 'decideIfEnd']); + break; + + case 'endswitch': + $end = true; + break; + + default: + throw new SyntaxError(sprintf('Unexpected end of template. Twig was looking for the following tags "case", "default", or "endswitch" to close the "switch" block started at line %d)', $lineno), -1); + } + } + + $stream->expect(Token::BLOCK_END_TYPE); + + return new TwigNodeSwitch($name, new Node($cases), $default, $lineno, $this->getTag()); + } + + /** + * Decide if current token marks switch logic. + * + * @param Token $token + * @return bool + */ + public function decideIfFork(Token $token): bool + { + return $token->test(['case', 'default', 'endswitch']); + } + + /** + * Decide if current token marks end of swtich block. + * + * @param Token $token + * @return bool + */ + public function decideIfEnd(Token $token): bool + { + return $token->test(['endswitch']); + } + + /** + * {@inheritdoc} + */ + public function getTag(): string + { + return 'switch'; + } +} diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserThrow.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserThrow.php new file mode 100644 index 0000000..3b517af --- /dev/null +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserThrow.php @@ -0,0 +1,55 @@ + + * {% throw 404 'Not Found' %} + * + */ +class TwigTokenParserThrow extends AbstractTokenParser +{ + /** + * Parses a token and returns a node. + * + * @param Token $token + * @return TwigNodeThrow + * @throws SyntaxError + */ + public function parse(Token $token) + { + $lineno = $token->getLine(); + $stream = $this->parser->getStream(); + + $code = $stream->expect(Token::NUMBER_TYPE)->getValue(); + $message = $this->parser->getExpressionParser()->parseExpression(); + $stream->expect(Token::BLOCK_END_TYPE); + + return new TwigNodeThrow((int)$code, $message, $lineno, $this->getTag()); + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag(): string + { + return 'throw'; + } +} diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserTryCatch.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserTryCatch.php new file mode 100644 index 0000000..dcb183b --- /dev/null +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserTryCatch.php @@ -0,0 +1,81 @@ + + * {% try %} + *
  • {{ user.get('name') }}
  • + * {% catch %} + * {{ e.message }} + * {% endcatch %} + * + */ +class TwigTokenParserTryCatch extends AbstractTokenParser +{ + /** + * Parses a token and returns a node. + * + * @param Token $token + * @return TwigNodeTryCatch + * @throws SyntaxError + */ + public function parse(Token $token) + { + $lineno = $token->getLine(); + $stream = $this->parser->getStream(); + + $stream->expect(Token::BLOCK_END_TYPE); + $try = $this->parser->subparse([$this, 'decideCatch']); + $stream->next(); + $stream->expect(Token::BLOCK_END_TYPE); + $catch = $this->parser->subparse([$this, 'decideEnd']); + $stream->next(); + $stream->expect(Token::BLOCK_END_TYPE); + + return new TwigNodeTryCatch($try, $catch, $lineno, $this->getTag()); + } + + /** + * @param Token $token + * @return bool + */ + public function decideCatch(Token $token): bool + { + return $token->test(['catch']); + } + + /** + * @param Token $token + * @return bool + */ + public function decideEnd(Token $token): bool + { + return $token->test(['endtry']) || $token->test(['endcatch']); + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag(): string + { + return 'try'; + } +} diff --git a/system/src/Grav/Common/Twig/Twig.php b/system/src/Grav/Common/Twig/Twig.php new file mode 100644 index 0000000..6e50916 --- /dev/null +++ b/system/src/Grav/Common/Twig/Twig.php @@ -0,0 +1,578 @@ +grav = $grav; + $this->twig_paths = []; + } + + /** + * Twig initialization that sets the twig loader chain, then the environment, then extensions + * and also the base set of twig vars + * + * @return $this + */ + public function init() + { + if (null === $this->twig) { + /** @var Config $config */ + $config = $this->grav['config']; + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + /** @var Language $language */ + $language = $this->grav['language']; + + $active_language = $language->getActive(); + + // handle language templates if available + if ($language->enabled()) { + $lang_templates = $locator->findResource('theme://templates/' . ($active_language ?: $language->getDefault())); + if ($lang_templates) { + $this->twig_paths[] = $lang_templates; + } + } + + $this->twig_paths = array_merge($this->twig_paths, $locator->findResources('theme://templates')); + + $this->grav->fireEvent('onTwigTemplatePaths'); + + // Add Grav core templates location + $core_templates = array_merge($locator->findResources('system://templates'), $locator->findResources('system://templates/testing')); + $this->twig_paths = array_merge($this->twig_paths, $core_templates); + + $this->loader = new FilesystemLoader($this->twig_paths); + + // Register all other prefixes as namespaces in twig + foreach ($locator->getPaths('theme') as $prefix => $_) { + if ($prefix === '') { + continue; + } + + $twig_paths = []; + + // handle language templates if available + if ($language->enabled()) { + $lang_templates = $locator->findResource('theme://'.$prefix.'templates/' . ($active_language ?: $language->getDefault())); + if ($lang_templates) { + $twig_paths[] = $lang_templates; + } + } + + $twig_paths = array_merge($twig_paths, $locator->findResources('theme://'.$prefix.'templates')); + + $namespace = trim($prefix, '/'); + $this->loader->setPaths($twig_paths, $namespace); + } + + $this->grav->fireEvent('onTwigLoader'); + + $this->loaderArray = new ArrayLoader([]); + $loader_chain = new ChainLoader([$this->loaderArray, $this->loader]); + + $params = $config->get('system.twig'); + if (!empty($params['cache'])) { + $cachePath = $locator->findResource('cache://twig', true, true); + $params['cache'] = new FilesystemCache($cachePath, FilesystemCache::FORCE_BYTECODE_INVALIDATION); + } + + if (!$config->get('system.strict_mode.twig_compat', false)) { + // Force autoescape on for all files if in strict mode. + $params['autoescape'] = 'html'; + } elseif (!empty($this->autoescape)) { + $params['autoescape'] = $this->autoescape ? 'html' : false; + } + + if (empty($params['autoescape'])) { + user_error('Grav 2.0 will have Twig auto-escaping forced on (can be emulated by turning off \'system.strict_mode.twig_compat\' setting in your configuration)', E_USER_DEPRECATED); + } + + $this->twig = new TwigEnvironment($loader_chain, $params); + + $this->twig->registerUndefinedFunctionCallback(function (string $name) use ($config) { + $allowed = $config->get('system.twig.safe_functions'); + if (is_array($allowed) && in_array($name, $allowed, true) && function_exists($name)) { + return new TwigFunction($name, $name); + } + if ($config->get('system.twig.undefined_functions')) { + if (function_exists($name)) { + if (!Utils::isDangerousFunction($name)) { + user_error("PHP function {$name}() was used as Twig function. This is deprecated in Grav 1.7. Please add it to system configuration: `system.twig.safe_functions`", E_USER_DEPRECATED); + + return new TwigFunction($name, $name); + } + + /** @var Debugger $debugger */ + $debugger = $this->grav['debugger']; + $debugger->addException(new RuntimeException("Blocked potentially dangerous PHP function {$name}() being used as Twig function. If you really want to use it, please add it to system configuration: `system.twig.safe_functions`")); + } + + return new TwigFunction($name, static function () {}); + } + + return false; + }); + + $this->twig->registerUndefinedFilterCallback(function (string $name) use ($config) { + $allowed = $config->get('system.twig.safe_filters'); + if (is_array($allowed) && in_array($name, $allowed, true) && function_exists($name)) { + return new TwigFilter($name, $name); + } + if ($config->get('system.twig.undefined_filters')) { + if (function_exists($name)) { + if (!Utils::isDangerousFunction($name)) { + user_error("PHP function {$name}() used as Twig filter. This is deprecated in Grav 1.7. Please add it to system configuration: `system.twig.safe_filters`", E_USER_DEPRECATED); + + return new TwigFilter($name, $name); + } + + /** @var Debugger $debugger */ + $debugger = $this->grav['debugger']; + $debugger->addException(new RuntimeException("Blocked potentially dangerous PHP function {$name}() being used as Twig filter. If you really want to use it, please add it to system configuration: `system.twig.safe_filters`")); + } + + return new TwigFilter($name, static function () {}); + } + + return false; + }); + + $this->grav->fireEvent('onTwigInitialized'); + + // set default date format if set in config + if ($config->get('system.pages.dateformat.long')) { + /** @var CoreExtension $extension */ + $extension = $this->twig->getExtension(CoreExtension::class); + $extension->setDateFormat($config->get('system.pages.dateformat.long')); + } + // enable the debug extension if required + if ($config->get('system.twig.debug')) { + $this->twig->addExtension(new DebugExtension()); + } + $this->twig->addExtension(new GravExtension()); + $this->twig->addExtension(new FilesystemExtension()); + $this->twig->addExtension(new DeferredExtension()); + $this->twig->addExtension(new StringLoaderExtension()); + + /** @var Debugger $debugger */ + $debugger = $this->grav['debugger']; + $debugger->addTwigProfiler($this->twig); + + $this->grav->fireEvent('onTwigExtensions'); + + /** @var Pages $pages */ + $pages = $this->grav['pages']; + + // Set some standard variables for twig + $this->twig_vars += [ + 'config' => $config, + 'system' => $config->get('system'), + 'theme' => $config->get('theme'), + 'site' => $config->get('site'), + 'uri' => $this->grav['uri'], + 'assets' => $this->grav['assets'], + 'taxonomy' => $this->grav['taxonomy'], + 'browser' => $this->grav['browser'], + 'base_dir' => GRAV_ROOT, + 'home_url' => $pages->homeUrl($active_language), + 'base_url' => $pages->baseUrl($active_language), + 'base_url_absolute' => $pages->baseUrl($active_language, true), + 'base_url_relative' => $pages->baseUrl($active_language, false), + 'base_url_simple' => $this->grav['base_url'], + 'theme_dir' => $locator->findResource('theme://'), + 'theme_url' => $this->grav['base_url'] . '/' . $locator->findResource('theme://', false), + 'html_lang' => $this->grav['language']->getActive() ?: $config->get('site.default_lang', 'en'), + 'language_codes' => new LanguageCodes, + ]; + } + + return $this; + } + + /** + * @return Environment + */ + public function twig() + { + return $this->twig; + } + + /** + * @return FilesystemLoader + */ + public function loader() + { + return $this->loader; + } + + /** + * @return Profile + */ + public function profile() + { + return $this->profile; + } + + + /** + * Adds or overrides a template. + * + * @param string $name The template name + * @param string $template The template source + */ + public function setTemplate($name, $template) + { + $this->loaderArray->setTemplate($name, $template); + } + + /** + * Twig process that renders a page item. It supports two variations: + * 1) Handles modular pages by rendering a specific page based on its modular twig template + * 2) Renders individual page items for twig processing before the site rendering + * + * @param PageInterface $item The page item to render + * @param string|null $content Optional content override + * + * @return string The rendered output + */ + public function processPage(PageInterface $item, $content = null) + { + $content = $content ?? $item->content(); + $content = Security::cleanDangerousTwig($content); + + // override the twig header vars for local resolution + $this->grav->fireEvent('onTwigPageVariables', new Event(['page' => $item])); + $twig_vars = $this->twig_vars; + + $twig_vars['page'] = $item; + $twig_vars['media'] = $item->media(); + $twig_vars['header'] = $item->header(); + $local_twig = clone $this->twig; + + $output = ''; + + try { + if ($item->isModule()) { + $twig_vars['content'] = $content; + $template = $this->getPageTwigTemplate($item); + $output = $content = $local_twig->render($template, $twig_vars); + } + + // Process in-page Twig + if ($item->shouldProcess('twig')) { + $name = '@Page:' . $item->path(); + $this->setTemplate($name, $content); + $output = $local_twig->render($name, $twig_vars); + } + + } catch (LoaderError $e) { + throw new RuntimeException($e->getRawMessage(), 400, $e); + } + + return $output; + } + + /** + * Process a Twig template directly by using a template name + * and optional array of variables + * + * @param string $template template to render with + * @param array $vars Optional variables + * + * @return string + */ + public function processTemplate($template, $vars = []) + { + // override the twig header vars for local resolution + $this->grav->fireEvent('onTwigTemplateVariables'); + $vars += $this->twig_vars; + + try { + $output = $this->twig->render($template, $vars); + } catch (LoaderError $e) { + throw new RuntimeException($e->getRawMessage(), 404, $e); + } + + return $output; + } + + + /** + * Process a Twig template directly by using a Twig string + * and optional array of variables + * + * @param string $string string to render. + * @param array $vars Optional variables + * + * @return string + */ + public function processString($string, array $vars = []) + { + // override the twig header vars for local resolution + $this->grav->fireEvent('onTwigStringVariables'); + $vars += $this->twig_vars; + + $string = Security::cleanDangerousTwig($string); + + $name = '@Var:' . $string; + $this->setTemplate($name, $string); + + try { + $output = $this->twig->render($name, $vars); + } catch (LoaderError $e) { + throw new RuntimeException($e->getRawMessage(), 404, $e); + } + + return $output; + } + + /** + * Twig process that renders the site layout. This is the main twig process that renders the overall + * page and handles all the layout for the site display. + * + * @param string|null $format Output format (defaults to HTML). + * @param array $vars + * @return string the rendered output + * @throws RuntimeException + */ + public function processSite($format = null, array $vars = []) + { + try { + $grav = $this->grav; + + // set the page now it's been processed + $grav->fireEvent('onTwigSiteVariables'); + + /** @var Pages $pages */ + $pages = $grav['pages']; + + /** @var PageInterface $page */ + $page = $grav['page']; + + $content = Security::cleanDangerousTwig($page->content()); + + $twig_vars = $this->twig_vars; + $twig_vars['theme'] = $grav['config']->get('theme'); + $twig_vars['pages'] = $pages->root(); + $twig_vars['page'] = $page; + $twig_vars['header'] = $page->header(); + $twig_vars['media'] = $page->media(); + $twig_vars['content'] = $content; + + // determine if params are set, if so disable twig cache + $params = $grav['uri']->params(null, true); + if (!empty($params)) { + $this->twig->setCache(false); + } + + // Get Twig template layout + $template = $this->getPageTwigTemplate($page, $format); + $page->templateFormat($format); + + $output = $this->twig->render($template, $vars + $twig_vars); + } catch (LoaderError $e) { + throw new RuntimeException($e->getMessage(), 400, $e); + } catch (RuntimeError $e) { + $prev = $e->getPrevious(); + if ($prev instanceof TwigException) { + $code = $prev->getCode() ?: 500; + // Fire onPageNotFound event. + $event = new Event([ + 'page' => $page, + 'code' => $code, + 'message' => $prev->getMessage(), + 'exception' => $prev, + 'route' => $grav['route'], + 'request' => $grav['request'] + ]); + $event = $grav->fireEvent("onDisplayErrorPage.{$code}", $event); + $newPage = $event['page']; + if ($newPage && $newPage !== $page) { + unset($grav['page']); + $grav['page'] = $newPage; + + return $this->processSite($newPage->templateFormat(), $vars); + } + } + + throw $e; + } + + return $output; + } + + /** + * Wraps the FilesystemLoader addPath method (should be used only in `onTwigLoader()` event + * @param string $template_path + * @param string $namespace + * @throws LoaderError + */ + public function addPath($template_path, $namespace = '__main__') + { + $this->loader->addPath($template_path, $namespace); + } + + /** + * Wraps the FilesystemLoader prependPath method (should be used only in `onTwigLoader()` event + * @param string $template_path + * @param string $namespace + * @throws LoaderError + */ + public function prependPath($template_path, $namespace = '__main__') + { + $this->loader->prependPath($template_path, $namespace); + } + + /** + * Simple helper method to get the twig template if it has already been set, else return + * the one being passed in + * NOTE: Modular pages that are injected should not use this pre-set template as it's usually set at the page level + * + * @param string $template the template name + * @return string the template name + */ + public function template(string $template): string + { + if (isset($this->template)) { + $template = $this->template; + unset($this->template); + } + + return $template; + } + + /** + * @param PageInterface $page + * @param string|null $format + * @return string + */ + public function getPageTwigTemplate($page, &$format = null) + { + $template = $page->template(); + $default = $page->isModule() ? 'modular/default' : 'default'; + $extension = $format ?: $page->templateFormat(); + $twig_extension = $extension ? '.'. $extension .TWIG_EXT : TEMPLATE_EXT; + $template_file = $this->template($template . $twig_extension); + + // TODO: no longer needed in Twig 3. + /** @var ExistsLoaderInterface $loader */ + $loader = $this->twig->getLoader(); + if ($loader->exists($template_file)) { + // template.xxx.twig + $page_template = $template_file; + } elseif ($twig_extension !== TEMPLATE_EXT && $loader->exists($template . TEMPLATE_EXT)) { + // template.html.twig + $page_template = $template . TEMPLATE_EXT; + $format = 'html'; + } elseif ($loader->exists($default . $twig_extension)) { + // default.xxx.twig + $page_template = $default . $twig_extension; + } else { + // default.html.twig + $page_template = $default . TEMPLATE_EXT; + $format = 'html'; + } + + return $page_template; + + } + + /** + * Overrides the autoescape setting + * + * @param bool $state + * @return void + * @deprecated 1.5 Auto-escape should always be turned on to protect against XSS issues (can be disabled per template file). + */ + public function setAutoescape($state) + { + if (!$state) { + user_error(__CLASS__ . '::' . __FUNCTION__ . '(false) is deprecated since Grav 1.5', E_USER_DEPRECATED); + } + + $this->autoescape = (bool) $state; + } + +} diff --git a/system/src/Grav/Common/Twig/TwigClockworkDataSource.php b/system/src/Grav/Common/Twig/TwigClockworkDataSource.php new file mode 100644 index 0000000..ef1888e --- /dev/null +++ b/system/src/Grav/Common/Twig/TwigClockworkDataSource.php @@ -0,0 +1,58 @@ +twig = $twig; + } + + /** + * Register the Twig profiler extension + */ + public function listenToEvents(): void + { + $this->twig->addExtension(new ProfilerExtension($this->profile = new Profile())); + } + + /** + * Adds rendered views to the request + * + * @param Request $request + * @return Request + */ + public function resolve(Request $request) + { + $timeline = (new TwigClockworkDumper())->dump($this->profile); + + $request->viewsData = array_merge($request->viewsData, $timeline->finalize()); + + return $request; + } +} diff --git a/system/src/Grav/Common/Twig/TwigClockworkDumper.php b/system/src/Grav/Common/Twig/TwigClockworkDumper.php new file mode 100644 index 0000000..904c457 --- /dev/null +++ b/system/src/Grav/Common/Twig/TwigClockworkDumper.php @@ -0,0 +1,72 @@ +dumpProfile($profile, $timeline); + + return $timeline; + } + + /** + * @param Profile $profile + * @param Timeline $timeline + * @param null $parent + */ + public function dumpProfile(Profile $profile, Timeline $timeline, $parent = null) + { + $id = $this->lastId++; + + if ($profile->isRoot()) { + $name = $profile->getName(); + } elseif ($profile->isTemplate()) { + $name = $profile->getTemplate(); + } else { + $name = $profile->getTemplate() . '::' . $profile->getType() . '(' . $profile->getName() . ')'; + } + + foreach ($profile as $p) { + $this->dumpProfile($p, $timeline, $id); + } + + $data = $profile->__serialize(); + + $timeline->event($name, [ + 'name' => $id, + 'start' => $data[3]['wt'] ?? null, + 'end' => $data[4]['wt'] ?? null, + 'data' => [ + 'data' => [], + 'memoryUsage' => $data[4]['mu'] ?? null, + 'parent' => $parent + ] + ]); + } +} diff --git a/system/src/Grav/Common/Twig/TwigEnvironment.php b/system/src/Grav/Common/Twig/TwigEnvironment.php new file mode 100644 index 0000000..9de7929 --- /dev/null +++ b/system/src/Grav/Common/Twig/TwigEnvironment.php @@ -0,0 +1,60 @@ +getLoader(); + if (!$loader->exists($name)) { + continue; + } + } + + // Throws LoaderError: Unable to find template "%s". + return $this->loadTemplate($name); + } + + throw new LoaderError(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names))); + } +} diff --git a/system/src/Grav/Common/Twig/TwigExtension.php b/system/src/Grav/Common/Twig/TwigExtension.php new file mode 100644 index 0000000..14310e7 --- /dev/null +++ b/system/src/Grav/Common/Twig/TwigExtension.php @@ -0,0 +1,21 @@ +get('system.twig.umask_fix', false); + } + + if (self::$umask) { + $dir = dirname($file); + if (!is_dir($dir)) { + $old = umask(0002); + Folder::create($dir); + umask($old); + } + parent::writeCacheFile($file, $content); + chmod($file, 0775); + } else { + parent::writeCacheFile($file, $content); + } + } +} diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php new file mode 100644 index 0000000..dcd9c27 --- /dev/null +++ b/system/src/Grav/Common/Uri.php @@ -0,0 +1,1527 @@ +createFromString($env); + } else { + $this->createFromEnvironment(is_array($env) ? $env : $_SERVER); + } + } + + /** + * Initialize the URI class with a url passed via parameter. + * Used for testing purposes. + * + * @param string $url the URL to use in the class + * @return $this + */ + public function initializeWithUrl($url = '') + { + if ($url) { + $this->createFromString($url); + } + + return $this; + } + + /** + * Initialize the URI class by providing url and root_path arguments + * + * @param string $url + * @param string $root_path + * @return $this + */ + public function initializeWithUrlAndRootPath($url, $root_path) + { + $this->initializeWithUrl($url); + $this->root_path = $root_path; + + return $this; + } + + /** + * Validate a hostname + * + * @param string $hostname The hostname + * @return bool + */ + public function validateHostname($hostname) + { + return (bool)preg_match(static::HOSTNAME_REGEX, $hostname); + } + + /** + * Initializes the URI object based on the url set on the object + * + * @return void + */ + public function init() + { + $grav = Grav::instance(); + + /** @var Config $config */ + $config = $grav['config']; + + /** @var Language $language */ + $language = $grav['language']; + + // add the port to the base for non-standard ports + if ($this->port && $config->get('system.reverse_proxy_setup') === false) { + $this->base .= ':' . $this->port; + } + + // Handle custom base + $custom_base = rtrim($grav['config']->get('system.custom_base_url', ''), '/'); + if ($custom_base) { + $custom_parts = parse_url($custom_base); + if ($custom_parts === false) { + throw new RuntimeException('Bad configuration: system.custom_base_url'); + } + $orig_root_path = $this->root_path; + $this->root_path = isset($custom_parts['path']) ? rtrim($custom_parts['path'], '/') : ''; + if (isset($custom_parts['scheme'])) { + $this->base = $custom_parts['scheme'] . '://' . $custom_parts['host']; + $this->port = $custom_parts['port'] ?? null; + if ($this->port && $config->get('system.reverse_proxy_setup') === false) { + $this->base .= ':' . $this->port; + } + $this->root = $custom_base; + } else { + $this->root = $this->base . $this->root_path; + } + $this->uri = Utils::replaceFirstOccurrence($orig_root_path, $this->root_path, $this->uri); + } else { + $this->root = $this->base . $this->root_path; + } + + $this->url = $this->base . $this->uri; + + $uri = Utils::replaceFirstOccurrence(static::filterPath($this->root), '', $this->url); + + // remove the setup.php based base if set: + $setup_base = $grav['pages']->base(); + if ($setup_base) { + $uri = preg_replace('|^' . preg_quote($setup_base, '|') . '|', '', $uri); + } + $this->setup_base = $setup_base; + + // process params + $uri = $this->processParams($uri, $config->get('system.param_sep')); + + // set active language + $uri = $language->setActiveFromUri($uri); + + // split the URL and params (and make sure that the path isn't seen as domain) + $bits = static::parseUrl('http://domain.com' . $uri); + + //process fragment + if (isset($bits['fragment'])) { + $this->fragment = $bits['fragment']; + } + + // Get the path. If there's no path, make sure pathinfo() still returns dirname variable + $path = $bits['path'] ?? '/'; + + // remove the extension if there is one set + $parts = Utils::pathinfo($path); + + // set the original basename + $this->basename = $parts['basename']; + + // set the extension + if (isset($parts['extension'])) { + $this->extension = $parts['extension']; + } + + // Strip the file extension for valid page types + if ($this->isValidExtension($this->extension)) { + $path = Utils::replaceLastOccurrence(".{$this->extension}", '', $path); + } + + // set the new url + $this->url = $this->root . $path; + $this->path = static::cleanPath($path); + $this->content_path = trim(Utils::replaceFirstOccurrence($this->base, '', $this->path), '/'); + if ($this->content_path !== '') { + $this->paths = explode('/', $this->content_path); + } + + // Set some Grav stuff + $grav['base_url_absolute'] = $config->get('system.custom_base_url') ?: $this->rootUrl(true); + $grav['base_url_relative'] = $this->rootUrl(false); + $grav['base_url'] = $config->get('system.absolute_urls') ? $grav['base_url_absolute'] : $grav['base_url_relative']; + + RouteFactory::setRoot($this->root_path . $setup_base); + RouteFactory::setLanguage($language->getLanguageURLPrefix()); + RouteFactory::setParamValueDelimiter($config->get('system.param_sep')); + } + + /** + * Return URI path. + * + * @param int|null $id + * @return string|string[] + */ + public function paths($id = null) + { + if ($id !== null) { + return $this->paths[$id]; + } + + return $this->paths; + } + + + /** + * Return route to the current URI. By default route doesn't include base path. + * + * @param bool $absolute True to include full path. + * @param bool $domain True to include domain. Works only if first parameter is also true. + * @return string + */ + public function route($absolute = false, $domain = false) + { + return ($absolute ? $this->rootUrl($domain) : '') . '/' . implode('/', $this->paths); + } + + /** + * Return full query string or a single query attribute. + * + * @param string|null $id Optional attribute. Get a single query attribute if set + * @param bool $raw If true and $id is not set, return the full query array. Otherwise return the query string + * + * @return string|array Returns an array if $id = null and $raw = true + */ + public function query($id = null, $raw = false) + { + if ($id !== null) { + return $this->queries[$id] ?? null; + } + + if ($raw) { + return $this->queries; + } + + if (!$this->queries) { + return ''; + } + + return http_build_query($this->queries); + } + + /** + * Return all or a single query parameter as a URI compatible string. + * + * @param string|null $id Optional parameter name. + * @param boolean $array return the array format or not + * @return null|string|array + */ + public function params($id = null, $array = false) + { + $config = Grav::instance()['config']; + $sep = $config->get('system.param_sep'); + + $params = null; + if ($id === null) { + if ($array) { + return $this->params; + } + $output = []; + foreach ($this->params as $key => $value) { + $output[] = "{$key}{$sep}{$value}"; + $params = '/' . implode('/', $output); + } + } elseif (isset($this->params[$id])) { + if ($array) { + return $this->params[$id]; + } + $params = "/{$id}{$sep}{$this->params[$id]}"; + } + + return $params; + } + + /** + * Get URI parameter. + * + * @param string $id + * @param string|false|null $default + * @return string|false|null + */ + public function param($id, $default = false) + { + if (isset($this->params[$id])) { + return html_entity_decode(rawurldecode($this->params[$id]), ENT_COMPAT | ENT_HTML401, 'UTF-8'); + } + + return $default; + } + + /** + * Gets the Fragment portion of a URI (eg #target) + * + * @param string|null $fragment + * @return string|null + */ + public function fragment($fragment = null) + { + if ($fragment !== null) { + $this->fragment = $fragment; + } + return $this->fragment; + } + + /** + * Return URL. + * + * @param bool $include_host Include hostname. + * @return string + */ + public function url($include_host = false) + { + if ($include_host) { + return $this->url; + } + + $url = Utils::replaceFirstOccurrence($this->base, '', rtrim($this->url, '/')); + + return $url ?: '/'; + } + + /** + * Return the Path + * + * @return string The path of the URI + */ + public function path() + { + return $this->path; + } + + /** + * Return the Extension of the URI + * + * @param string|null $default + * @return string|null The extension of the URI + */ + public function extension($default = null) + { + if (!$this->extension) { + $this->extension = $default; + } + + return $this->extension; + } + + /** + * @return string + */ + public function method() + { + $method = isset($_SERVER['REQUEST_METHOD']) ? strtoupper($_SERVER['REQUEST_METHOD']) : 'GET'; + + if ($method === 'POST' && isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) { + $method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']); + } + + return $method; + } + + /** + * Return the scheme of the URI + * + * @param bool|null $raw + * @return string The scheme of the URI + */ + public function scheme($raw = false) + { + if (!$raw) { + $scheme = ''; + if ($this->scheme) { + $scheme = $this->scheme . '://'; + } elseif ($this->host) { + $scheme = '//'; + } + + return $scheme; + } + + return $this->scheme; + } + + + /** + * Return the host of the URI + * + * @return string|null The host of the URI + */ + public function host() + { + return $this->host; + } + + /** + * Return the port number if it can be figured out + * + * @param bool $raw + * @return int|null + */ + public function port($raw = false) + { + $port = $this->port; + // If not in raw mode and port is not set or is 0, figure it out from scheme. + if (!$raw && !$port) { + if ($this->scheme === 'http') { + $this->port = 80; + } elseif ($this->scheme === 'https') { + $this->port = 443; + } + } + + return $this->port ?: null; + } + + /** + * Return user + * + * @return string|null + */ + public function user() + { + return $this->user; + } + + /** + * Return password + * + * @return string|null + */ + public function password() + { + return $this->password; + } + + /** + * Gets the environment name + * + * @return string + */ + public function environment() + { + return $this->env; + } + + + /** + * Return the basename of the URI + * + * @return string The basename of the URI + */ + public function basename() + { + return $this->basename; + } + + /** + * Return the full uri + * + * @param bool $include_root + * @return string + */ + public function uri($include_root = true) + { + if ($include_root) { + return $this->uri; + } + + return Utils::replaceFirstOccurrence($this->root_path, '', $this->uri); + } + + /** + * Return the base of the URI + * + * @return string The base of the URI + */ + public function base() + { + return $this->base; + } + + /** + * Return the base relative URL including the language prefix + * or the base relative url if multi-language is not enabled + * + * @return string The base of the URI + */ + public function baseIncludingLanguage() + { + $grav = Grav::instance(); + + /** @var Pages $pages */ + $pages = $grav['pages']; + + return $pages->baseUrl(null, false); + } + + /** + * Return root URL to the site. + * + * @param bool $include_host Include hostname. + * @return string + */ + public function rootUrl($include_host = false) + { + if ($include_host) { + return $this->root; + } + + return Utils::replaceFirstOccurrence($this->base, '', $this->root); + } + + /** + * Return current page number. + * + * @return int + */ + public function currentPage() + { + $page = (int)($this->params['page'] ?? 1); + + return max(1, $page); + } + + /** + * Return relative path to the referrer defaulting to current or given page. + * + * You should set the third parameter to `true` for redirects as long as you came from the same sub-site and language. + * + * @param string|null $default + * @param string|null $attributes + * @param bool $withoutBaseRoute + * @return string + */ + public function referrer($default = null, $attributes = null, bool $withoutBaseRoute = false) + { + $referrer = $_SERVER['HTTP_REFERER'] ?? null; + + // Check that referrer came from our site. + if ($withoutBaseRoute) { + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + $base = $pages->baseUrl(null, true); + } else { + $base = $this->rootUrl(true); + } + + // Referrer should always have host set and it should come from the same base address. + if (!is_string($referrer) || !str_starts_with($referrer, $base)) { + $referrer = $default ?: $this->route(true, true); + } + + // Relative path from grav root. + $referrer = substr($referrer, strlen($base)); + if ($attributes) { + $referrer .= $attributes; + } + + return $referrer; + } + + /** + * @return string + */ + #[\ReturnTypeWillChange] + public function __toString() + { + return static::buildUrl($this->toArray()); + } + + /** + * @return string + */ + public function toOriginalString() + { + return static::buildUrl($this->toArray(true)); + } + + /** + * @param bool $full + * @return array + */ + public function toArray($full = false) + { + if ($full === true) { + $root_path = $this->root_path ?? ''; + $extension = isset($this->extension) && $this->isValidExtension($this->extension) ? '.' . $this->extension : ''; + $path = $root_path . $this->path . $extension; + } else { + $path = $this->path; + } + + return [ + 'scheme' => $this->scheme, + 'host' => $this->host, + 'port' => $this->port ?: null, + 'user' => $this->user, + 'pass' => $this->password, + 'path' => $path, + 'params' => $this->params, + 'query' => $this->query, + 'fragment' => $this->fragment + ]; + } + + /** + * Calculate the parameter regex based on the param_sep setting + * + * @return string + */ + public static function paramsRegex() + { + return '/\/{1,}([^\:\#\/\?]*' . Grav::instance()['config']->get('system.param_sep') . '[^\:\#\/\?]*)/'; + } + + /** + * Return the IP address of the current user + * + * @return string ip address + */ + public static function ip() + { + $ip = 'UNKNOWN'; + + if (getenv('HTTP_CLIENT_IP')) { + $ip = getenv('HTTP_CLIENT_IP'); + } elseif (getenv('HTTP_CF_CONNECTING_IP')) { + $ip = getenv('HTTP_CF_CONNECTING_IP'); + } elseif (getenv('HTTP_X_FORWARDED_FOR') && Grav::instance()['config']->get('system.http_x_forwarded.ip')) { + $ips = array_map('trim', explode(',', getenv('HTTP_X_FORWARDED_FOR'))); + $ip = array_shift($ips); + } elseif (getenv('HTTP_X_FORWARDED') && Grav::instance()['config']->get('system.http_x_forwarded.ip')) { + $ip = getenv('HTTP_X_FORWARDED'); + } elseif (getenv('HTTP_FORWARDED_FOR')) { + $ip = getenv('HTTP_FORWARDED_FOR'); + } elseif (getenv('HTTP_FORWARDED')) { + $ip = getenv('HTTP_FORWARDED'); + } elseif (getenv('REMOTE_ADDR')) { + $ip = getenv('REMOTE_ADDR'); + } + + return $ip; + } + + /** + * Returns current Uri. + * + * @return \Grav\Framework\Uri\Uri + */ + public static function getCurrentUri() + { + if (!static::$currentUri) { + static::$currentUri = UriFactory::createFromEnvironment($_SERVER); + } + + return static::$currentUri; + } + + /** + * Returns current route. + * + * @return Route + */ + public static function getCurrentRoute() + { + if (!static::$currentRoute) { + /** @var Uri $uri */ + $uri = Grav::instance()['uri']; + + static::$currentRoute = RouteFactory::createFromLegacyUri($uri); + } + + return static::$currentRoute; + } + + /** + * Is this an external URL? if it starts with `http` then yes, else false + * + * @param string $url the URL in question + * @return bool is eternal state + */ + public static function isExternal($url) + { + return (0 === strpos($url, 'http://') || 0 === strpos($url, 'https://') || 0 === strpos($url, '//') || 0 === strpos($url, 'mailto:') || 0 === strpos($url, 'tel:') || 0 === strpos($url, 'ftp://') || 0 === strpos($url, 'ftps://') || 0 === strpos($url, 'news:') || 0 === strpos($url, 'irc:') || 0 === strpos($url, 'gopher:') || 0 === strpos($url, 'nntp:') || 0 === strpos($url, 'feed:') || 0 === strpos($url, 'cvs:') || 0 === strpos($url, 'ssh:') || 0 === strpos($url, 'git:') || 0 === strpos($url, 'svn:') || 0 === strpos($url, 'hg:')); + } + + /** + * The opposite of built-in PHP method parse_url() + * + * @param array $parsed_url + * @return string + */ + public static function buildUrl($parsed_url) + { + $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . ':' : ''; + $authority = isset($parsed_url['host']) ? '//' : ''; + $host = $parsed_url['host'] ?? ''; + $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : ''; + $user = $parsed_url['user'] ?? ''; + $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : ''; + $pass = ($user || $pass) ? "{$pass}@" : ''; + $path = $parsed_url['path'] ?? ''; + $path = !empty($parsed_url['params']) ? rtrim($path, '/') . static::buildParams($parsed_url['params']) : $path; + $query = !empty($parsed_url['query']) ? '?' . $parsed_url['query'] : ''; + $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : ''; + + return "{$scheme}{$authority}{$user}{$pass}{$host}{$port}{$path}{$query}{$fragment}"; + } + + /** + * @param array $params + * @return string + */ + public static function buildParams(array $params) + { + if (!$params) { + return ''; + } + + $grav = Grav::instance(); + $sep = $grav['config']->get('system.param_sep'); + + $output = []; + foreach ($params as $key => $value) { + $output[] = "{$key}{$sep}{$value}"; + } + + return '/' . implode('/', $output); + } + + /** + * Converts links from absolute '/' or relative (../..) to a Grav friendly format + * + * @param PageInterface $page the current page to use as reference + * @param string|array $url the URL as it was written in the markdown + * @param string $type the type of URL, image | link + * @param bool $absolute if null, will use system default, if true will use absolute links internally + * @param bool $route_only only return the route, not full URL path + * @return string|array the more friendly formatted url + */ + public static function convertUrl(PageInterface $page, $url, $type = 'link', $absolute = false, $route_only = false) + { + $grav = Grav::instance(); + + $uri = $grav['uri']; + + // Link processing should prepend language + $language = $grav['language']; + $language_append = ''; + if ($type === 'link' && $language->enabled()) { + $language_append = $language->getLanguageURLPrefix(); + } + + // Handle Excerpt style $url array + $url_path = is_array($url) ? $url['path'] : $url; + + $external = false; + $base = $grav['base_url_relative']; + $base_url = rtrim($base . $grav['pages']->base(), '/') . $language_append; + $pages_dir = $grav['locator']->findResource('page://'); + + // if absolute and starts with a base_url move on + if (isset($url['scheme']) && Utils::startsWith($url['scheme'], 'http')) { + $external = true; + } elseif ($url_path === '' && isset($url['fragment'])) { + $external = true; + } elseif ($url_path === '/' || ($base_url !== '' && Utils::startsWith($url_path, $base_url))) { + $url_path = $base_url . $url_path; + } else { + // see if page is relative to this or absolute + if (Utils::startsWith($url_path, '/')) { + $normalized_url = Utils::normalizePath($base_url . $url_path); + $normalized_path = Utils::normalizePath($pages_dir . $url_path); + } else { + $page_route = ($page->home() && !empty($url_path)) ? $page->rawRoute() : $page->route(); + $normalized_url = $base_url . Utils::normalizePath(rtrim($page_route, '/') . '/' . $url_path); + $normalized_path = Utils::normalizePath($page->path() . '/' . $url_path); + } + + // special check to see if path checking is required. + $just_path = Utils::replaceFirstOccurrence($normalized_url, '', $normalized_path); + if ($normalized_url === '/' || $just_path === $page->path()) { + $url_path = $normalized_url; + } else { + $url_bits = static::parseUrl($normalized_path); + $full_path = $url_bits['path']; + $raw_full_path = rawurldecode($full_path); + + if (file_exists($raw_full_path)) { + $full_path = $raw_full_path; + } elseif (!file_exists($full_path)) { + $full_path = false; + } + + if ($full_path) { + $path_info = Utils::pathinfo($full_path); + $page_path = $path_info['dirname']; + $filename = ''; + + if ($url_path === '..') { + $page_path = $full_path; + } else { + // save the filename if a file is part of the path + if (is_file($full_path)) { + if ($path_info['extension'] !== 'md') { + $filename = '/' . $path_info['basename']; + } + } else { + $page_path = $full_path; + } + } + + // get page instances and try to find one that fits + $instances = $grav['pages']->instances(); + if (isset($instances[$page_path])) { + /** @var PageInterface $target */ + $target = $instances[$page_path]; + $url_bits['path'] = $base_url . rtrim($target->route(), '/') . $filename; + + $url_path = Uri::buildUrl($url_bits); + } else { + $url_path = $normalized_url; + } + } else { + $url_path = $normalized_url; + } + } + } + + // handle absolute URLs + if (is_array($url) && !$external && ($absolute === true || $grav['config']->get('system.absolute_urls', false))) { + $url['scheme'] = $uri->scheme(true); + $url['host'] = $uri->host(); + $url['port'] = $uri->port(true); + + // check if page exists for this route, and if so, check if it has SSL enabled + $pages = $grav['pages']; + $routes = $pages->routes(); + + // if this is an image, get the proper path + $url_bits = Utils::pathinfo($url_path); + if (isset($url_bits['extension'])) { + $target_path = $url_bits['dirname']; + } else { + $target_path = $url_path; + } + + // strip base from this path + $target_path = Utils::replaceFirstOccurrence($uri->rootUrl(), '', $target_path); + + // set to / if root + if (empty($target_path)) { + $target_path = '/'; + } + + // look to see if this page exists and has ssl enabled + if (isset($routes[$target_path])) { + $target_page = $pages->get($routes[$target_path]); + if ($target_page) { + $ssl_enabled = $target_page->ssl(); + if ($ssl_enabled !== null) { + if ($ssl_enabled) { + $url['scheme'] = 'https'; + } else { + $url['scheme'] = 'http'; + } + } + } + } + } + + // Handle route only + if ($route_only) { + $url_path = Utils::replaceFirstOccurrence(static::filterPath($base_url), '', $url_path); + } + + // transform back to string/array as needed + if (is_array($url)) { + $url['path'] = $url_path; + } else { + $url = $url_path; + } + + return $url; + } + + /** + * @param string $url + * @return array|false + */ + public static function parseUrl($url) + { + $grav = Grav::instance(); + + // Remove extra slash from streams, parse_url() doesn't like it. + $url = preg_replace('/([^:])(\/{2,})/', '$1/', $url); + + $encodedUrl = preg_replace_callback( + '%[^:/@?&=#]+%usD', + static function ($matches) { + return rawurlencode($matches[0]); + }, + $url + ); + + $parts = parse_url($encodedUrl); + + if (false === $parts) { + return false; + } + + foreach ($parts as $name => $value) { + $parts[$name] = rawurldecode($value); + } + + if (!isset($parts['path'])) { + $parts['path'] = ''; + } + + [$stripped_path, $params] = static::extractParams($parts['path'], $grav['config']->get('system.param_sep')); + + if (!empty($params)) { + $parts['path'] = $stripped_path; + $parts['params'] = $params; + } + + return $parts; + } + + /** + * @param string $uri + * @param string $delimiter + * @return array + */ + public static function extractParams($uri, $delimiter) + { + $params = []; + + if (strpos($uri, $delimiter) !== false) { + preg_match_all(static::paramsRegex(), $uri, $matches, PREG_SET_ORDER); + + foreach ($matches as $match) { + $param = explode($delimiter, $match[1]); + if (count($param) === 2) { + $plain_var = htmlspecialchars(strip_tags(rawurldecode($param[1])), ENT_QUOTES, 'UTF-8'); + $params[$param[0]] = $plain_var; + $uri = str_replace($match[0], '', $uri); + } + } + } + + return [$uri, $params]; + } + + /** + * Converts links from absolute '/' or relative (../..) to a Grav friendly format + * + * @param PageInterface $page the current page to use as reference + * @param string $markdown_url the URL as it was written in the markdown + * @param string $type the type of URL, image | link + * @param bool|null $relative if null, will use system default, if true will use relative links internally + * + * @return string the more friendly formatted url + */ + public static function convertUrlOld(PageInterface $page, $markdown_url, $type = 'link', $relative = null) + { + $grav = Grav::instance(); + + $language = $grav['language']; + + // Link processing should prepend language + $language_append = ''; + if ($type === 'link' && $language->enabled()) { + $language_append = $language->getLanguageURLPrefix(); + } + $pages_dir = $grav['locator']->findResource('page://'); + if ($relative === null) { + $base = $grav['base_url']; + } else { + $base = $relative ? $grav['base_url_relative'] : $grav['base_url_absolute']; + } + + $base_url = rtrim($base . $grav['pages']->base(), '/') . $language_append; + + // if absolute and starts with a base_url move on + if (Utils::pathinfo($markdown_url, PATHINFO_DIRNAME) === '.' && $page->url() === '/') { + return '/' . $markdown_url; + } + // no path to convert + if ($base_url !== '' && Utils::startsWith($markdown_url, $base_url)) { + return $markdown_url; + } + // if contains only a fragment + if (Utils::startsWith($markdown_url, '#')) { + return $markdown_url; + } + + $target = null; + // see if page is relative to this or absolute + if (Utils::startsWith($markdown_url, '/')) { + $normalized_url = Utils::normalizePath($base_url . $markdown_url); + $normalized_path = Utils::normalizePath($pages_dir . $markdown_url); + } else { + $normalized_url = $base_url . Utils::normalizePath($page->route() . '/' . $markdown_url); + $normalized_path = Utils::normalizePath($page->path() . '/' . $markdown_url); + } + + // special check to see if path checking is required. + $just_path = Utils::replaceFirstOccurrence($normalized_url, '', $normalized_path); + if ($just_path === $page->path()) { + return $normalized_url; + } + + $url_bits = parse_url($normalized_path); + $full_path = $url_bits['path']; + + if (file_exists($full_path)) { + // do nothing + } elseif (file_exists(rawurldecode($full_path))) { + $full_path = rawurldecode($full_path); + } else { + return $normalized_url; + } + + $path_info = Utils::pathinfo($full_path); + $page_path = $path_info['dirname']; + $filename = ''; + + if ($markdown_url === '..') { + $page_path = $full_path; + } else { + // save the filename if a file is part of the path + if (is_file($full_path)) { + if ($path_info['extension'] !== 'md') { + $filename = '/' . $path_info['basename']; + } + } else { + $page_path = $full_path; + } + } + + // get page instances and try to find one that fits + $instances = $grav['pages']->instances(); + if (isset($instances[$page_path])) { + /** @var PageInterface $target */ + $target = $instances[$page_path]; + $url_bits['path'] = $base_url . rtrim($target->route(), '/') . $filename; + + return static::buildUrl($url_bits); + } + + return $normalized_url; + } + + /** + * Adds the nonce to a URL for a specific action + * + * @param string $url the url + * @param string $action the action + * @param string $nonceParamName the param name to use + * + * @return string the url with the nonce + */ + public static function addNonce($url, $action, $nonceParamName = 'nonce') + { + $fake = $url && strpos($url, '/') === 0; + + if ($fake) { + $url = 'http://domain.com' . $url; + } + $uri = new static($url); + $parts = $uri->toArray(); + $nonce = Utils::getNonce($action); + $parts['params'] = ($parts['params'] ?? []) + [$nonceParamName => $nonce]; + + if ($fake) { + unset($parts['scheme'], $parts['host']); + } + + return static::buildUrl($parts); + } + + /** + * Is the passed in URL a valid URL? + * + * @param string $url + * @return bool + */ + public static function isValidUrl($url) + { + $regex = '/^(?:(https?|ftp|telnet):)?\/\/((?:[a-z0-9@:.-]|%[0-9A-F]{2}){3,})(?::(\d+))?((?:\/(?:[a-z0-9-._~!$&\'\(\)\*\+\,\;\=\:\@]|%[0-9A-F]{2})*)*)(?:\?((?:[a-z0-9-._~!$&\'\(\)\*\+\,\;\=\:\/?@]|%[0-9A-F]{2})*))?(?:#((?:[a-z0-9-._~!$&\'\(\)\*\+\,\;\=\:\/?@]|%[0-9A-F]{2})*))?/'; + + return (bool)preg_match($regex, $url); + } + + /** + * Removes extra double slashes and fixes back-slashes + * + * @param string $path + * @return string + */ + public static function cleanPath($path) + { + $regex = '/(\/)\/+/'; + $path = str_replace(['\\', '/ /'], '/', $path); + $path = preg_replace($regex, '$1', $path); + + return $path; + } + + /** + * Filters the user info string. + * + * @param string|null $info The raw user or password. + * @return string The percent-encoded user or password string. + */ + public static function filterUserInfo($info) + { + return $info !== null ? UriPartsFilter::filterUserInfo($info) : ''; + } + + /** + * Filter Uri path. + * + * This method percent-encodes all reserved + * characters in the provided path string. This method + * will NOT double-encode characters that are already + * percent-encoded. + * + * @param string|null $path The raw uri path. + * @return string The RFC 3986 percent-encoded uri path. + * @link http://www.faqs.org/rfcs/rfc3986.html + */ + public static function filterPath($path) + { + return $path !== null ? UriPartsFilter::filterPath($path) : ''; + } + + /** + * Filters the query string or fragment of a URI. + * + * @param string|null $query The raw uri query string. + * @return string The percent-encoded query string. + */ + public static function filterQuery($query) + { + return $query !== null ? UriPartsFilter::filterQueryOrFragment($query) : ''; + } + + /** + * @param array $env + * @return void + */ + protected function createFromEnvironment(array $env) + { + // Build scheme. + if (isset($env['HTTP_X_FORWARDED_PROTO']) && Grav::instance()['config']->get('system.http_x_forwarded.protocol')) { + $this->scheme = $env['HTTP_X_FORWARDED_PROTO']; + } elseif (isset($env['X-FORWARDED-PROTO'])) { + $this->scheme = $env['X-FORWARDED-PROTO']; + } elseif (isset($env['HTTP_CLOUDFRONT_FORWARDED_PROTO'])) { + $this->scheme = $env['HTTP_CLOUDFRONT_FORWARDED_PROTO']; + } elseif (isset($env['REQUEST_SCHEME']) && empty($env['HTTPS'])) { + $this->scheme = $env['REQUEST_SCHEME']; + } else { + $https = $env['HTTPS'] ?? ''; + $this->scheme = (empty($https) || strtolower($https) === 'off') ? 'http' : 'https'; + } + + // Build user and password. + $this->user = $env['PHP_AUTH_USER'] ?? null; + $this->password = $env['PHP_AUTH_PW'] ?? null; + + // Build host. + if (isset($env['HTTP_X_FORWARDED_HOST']) && Grav::instance()['config']->get('system.http_x_forwarded.host')) { + $hostname = $env['HTTP_X_FORWARDED_HOST']; + } else if (isset($env['HTTP_HOST'])) { + $hostname = $env['HTTP_HOST']; + } elseif (isset($env['SERVER_NAME'])) { + $hostname = $env['SERVER_NAME']; + } else { + $hostname = 'localhost'; + } + // Remove port from HTTP_HOST generated $hostname + $hostname = Utils::substrToString($hostname, ':'); + // Validate the hostname + $this->host = $this->validateHostname($hostname) ? $hostname : 'unknown'; + + // Build port. + if (isset($env['HTTP_X_FORWARDED_PORT']) && Grav::instance()['config']->get('system.http_x_forwarded.port')) { + $this->port = (int)$env['HTTP_X_FORWARDED_PORT']; + } elseif (isset($env['X-FORWARDED-PORT'])) { + $this->port = (int)$env['X-FORWARDED-PORT']; + } elseif (isset($env['HTTP_CLOUDFRONT_FORWARDED_PROTO'])) { + // Since AWS Cloudfront does not provide a forwarded port header, + // we have to build the port using the scheme. + $this->port = $this->port(); + } elseif (isset($env['SERVER_PORT'])) { + $this->port = (int)$env['SERVER_PORT']; + } else { + $this->port = null; + } + + if ($this->port === 0 || $this->hasStandardPort()) { + $this->port = null; + } + + // Build path. + $request_uri = $env['REQUEST_URI'] ?? ''; + $this->path = rawurldecode(parse_url('http://example.com' . $request_uri, PHP_URL_PATH)); + + // Build query string. + $this->query = $env['QUERY_STRING'] ?? ''; + if ($this->query === '') { + $this->query = parse_url('http://example.com' . $request_uri, PHP_URL_QUERY) ?? ''; + } + + // Support ngnix routes. + if (strpos($this->query, '_url=') === 0) { + parse_str($this->query, $query); + unset($query['_url']); + $this->query = http_build_query($query); + } + + // Build fragment. + $this->fragment = null; + + // Filter userinfo, path and query string. + $this->user = $this->user !== null ? static::filterUserInfo($this->user) : null; + $this->password = $this->password !== null ? static::filterUserInfo($this->password) : null; + $this->path = empty($this->path) ? '/' : static::filterPath($this->path); + $this->query = static::filterQuery($this->query); + + $this->reset(); + } + + /** + * Does this Uri use a standard port? + * + * @return bool + */ + protected function hasStandardPort() + { + return (!$this->port || $this->port === 80 || $this->port === 443); + } + + /** + * @param string $url + */ + protected function createFromString($url) + { + // Set Uri parts. + $parts = parse_url($url); + if ($parts === false) { + throw new RuntimeException('Malformed URL: ' . $url); + } + $port = (int)($parts['port'] ?? 0); + + $this->scheme = $parts['scheme'] ?? null; + $this->user = $parts['user'] ?? null; + $this->password = $parts['pass'] ?? null; + $this->host = $parts['host'] ?? null; + $this->port = $port ?: null; + $this->path = $parts['path'] ?? ''; + $this->query = $parts['query'] ?? ''; + $this->fragment = $parts['fragment'] ?? null; + + // Validate the hostname + if ($this->host) { + $this->host = $this->validateHostname($this->host) ? $this->host : 'unknown'; + } + // Filter userinfo, path, query string and fragment. + $this->user = $this->user !== null ? static::filterUserInfo($this->user) : null; + $this->password = $this->password !== null ? static::filterUserInfo($this->password) : null; + $this->path = empty($this->path) ? '/' : static::filterPath($this->path); + $this->query = static::filterQuery($this->query); + $this->fragment = $this->fragment !== null ? static::filterQuery($this->fragment) : null; + + $this->reset(); + } + + /** + * @return void + */ + protected function reset() + { + // resets + parse_str($this->query, $this->queries); + $this->extension = null; + $this->basename = null; + $this->paths = []; + $this->params = []; + $this->env = $this->buildEnvironment(); + $this->uri = $this->path . (!empty($this->query) ? '?' . $this->query : ''); + + $this->base = $this->buildBaseUrl(); + $this->root_path = $this->buildRootPath(); + $this->root = $this->base . $this->root_path; + $this->url = $this->base . $this->uri; + } + + /** + * Get post from either $_POST or JSON response object + * By default returns all data, or can return a single item + * + * @param string|null $element + * @param string|null $filter_type + * @return array|null + */ + public function post($element = null, $filter_type = null) + { + if (!$this->post) { + $content_type = $this->getContentType(); + if ($content_type === 'application/json') { + $json = file_get_contents('php://input'); + $this->post = json_decode($json, true); + } elseif (!empty($_POST)) { + $this->post = (array)$_POST; + } + + $event = new Event(['post' => &$this->post]); + Grav::instance()->fireEvent('onHttpPostFilter', $event); + } + + if ($this->post && null !== $element) { + $item = Utils::getDotNotation($this->post, $element); + if ($filter_type) { + if ($filter_type === FILTER_SANITIZE_STRING || $filter_type === GRAV_SANITIZE_STRING) { + $item = htmlspecialchars(strip_tags($item), ENT_QUOTES, 'UTF-8'); + } else { + $item = filter_var($item, $filter_type); + } + } + return $item; + } + + return $this->post; + } + + /** + * Get content type from request + * + * @param bool $short + * @return null|string + */ + public function getContentType($short = true) + { + $content_type = $_SERVER['CONTENT_TYPE'] ?? $_SERVER['HTTP_CONTENT_TYPE'] ?? $_SERVER['HTTP_ACCEPT'] ?? null; + if ($content_type) { + if ($short) { + return Utils::substrToString($content_type, ';'); + } + } + return $content_type; + } + + /** + * Check if this is a valid Grav extension + * + * @param string|null $extension + * @return bool + */ + public function isValidExtension($extension): bool + { + $extension = (string)$extension; + + return $extension !== '' && in_array($extension, Utils::getSupportPageTypes(), true); + } + + /** + * Allow overriding of any element (be careful!) + * + * @param array $data + * @return Uri + */ + public function setUriProperties($data) + { + foreach (get_object_vars($this) as $property => $default) { + if (!array_key_exists($property, $data)) { + continue; + } + $this->{$property} = $data[$property]; // assign value to object + } + return $this; + } + + + /** + * Compatibility in case getallheaders() is not available on platform + */ + public static function getAllHeaders() + { + if (!function_exists('getallheaders')) { + $headers = []; + foreach ($_SERVER as $name => $value) { + if (substr($name, 0, 5) == 'HTTP_') { + $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; + } + } + return $headers; + } + return getallheaders(); + } + + /** + * Get the base URI with port if needed + * + * @return string + */ + private function buildBaseUrl() + { + return $this->scheme() . $this->host; + } + + /** + * Get the Grav Root Path + * + * @return string + */ + private function buildRootPath() + { + // In Windows script path uses backslash, convert it: + $scriptPath = str_replace('\\', '/', $_SERVER['PHP_SELF']); + $rootPath = str_replace(' ', '%20', rtrim(substr($scriptPath, 0, strpos($scriptPath, 'index.php')), '/')); + + return $rootPath; + } + + /** + * @return string + */ + private function buildEnvironment() + { + // check for localhost variations + if ($this->host === '127.0.0.1' || $this->host === '::1') { + return 'localhost'; + } + + return $this->host ?: 'unknown'; + } + + /** + * Process any params based in this URL, supports any valid delimiter + * + * @param string $uri + * @param string $delimiter + * @return string + */ + private function processParams(string $uri, string $delimiter = ':'): string + { + if (strpos($uri, $delimiter) !== false) { + preg_match_all(static::paramsRegex(), $uri, $matches, PREG_SET_ORDER); + + foreach ($matches as $match) { + $param = explode($delimiter, $match[1]); + if (count($param) === 2) { + $plain_var = htmlspecialchars(strip_tags($param[1]), ENT_QUOTES, 'UTF-8'); + $this->params[$param[0]] = $plain_var; + $uri = str_replace($match[0], '', $uri); + } + } + } + return $uri; + } +} diff --git a/system/src/Grav/Common/User/Access.php b/system/src/Grav/Common/User/Access.php new file mode 100644 index 0000000..5e24d3f --- /dev/null +++ b/system/src/Grav/Common/User/Access.php @@ -0,0 +1,52 @@ + ['admin.configuration_system'], + 'admin.configuration.site' => ['admin.configuration_site', 'admin.settings'], + 'admin.configuration.media' => ['admin.configuration_media'], + 'admin.configuration.info' => ['admin.configuration_info'], + ]; + + /** + * @param string $action + * @return bool|null + */ + public function get(string $action) + { + $result = parent::get($action); + if (is_bool($result)) { + return $result; + } + + // Get access value. + if (isset($this->aliases[$action])) { + $aliases = $this->aliases[$action]; + foreach ($aliases as $alias) { + $result = parent::get($alias); + if (is_bool($result)) { + return $result; + } + } + } + + return null; + } +} diff --git a/system/src/Grav/Common/User/Authentication.php b/system/src/Grav/Common/User/Authentication.php new file mode 100644 index 0000000..53cbf42 --- /dev/null +++ b/system/src/Grav/Common/User/Authentication.php @@ -0,0 +1,61 @@ +get('user/account'); + } + + parent::__construct($items, $blueprints); + } + + /** + * @param string $offset + * @return bool + */ + #[\ReturnTypeWillChange] + public function offsetExists($offset) + { + $value = parent::offsetExists($offset); + + // Handle special case where user was logged in before 'authorized' was added to the user object. + if (false === $value && $offset === 'authorized') { + $value = $this->offsetExists('authenticated'); + } + + return $value; + } + + /** + * @param string $offset + * @return mixed + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + $value = parent::offsetGet($offset); + + // Handle special case where user was logged in before 'authorized' was added to the user object. + if (null === $value && $offset === 'authorized') { + $value = $this->offsetGet('authenticated'); + $this->offsetSet($offset, $value); + } + + return $value; + } + + /** + * @return bool + */ + public function isValid(): bool + { + return $this->items !== null; + } + + /** + * Update object with data + * + * @param array $data + * @param array $files + * @return $this + */ + public function update(array $data, array $files = []) + { + // Note: $this->merge() would cause infinite loop as it calls this method. + parent::merge($data); + + return $this; + } + + /** + * Save user + * + * @return void + */ + public function save() + { + /** @var CompiledYamlFile|null $file */ + $file = $this->file(); + if (!$file || !$file->filename()) { + user_error(__CLASS__ . ': calling \$user = new ' . __CLASS__ . "() is deprecated since Grav 1.6, use \$grav['accounts']->load(\$username) or \$grav['accounts']->load('') instead", E_USER_DEPRECATED); + } + + if ($file) { + $username = $this->filterUsername((string)$this->get('username')); + + if (!$file->filename()) { + $locator = Grav::instance()['locator']; + $file->filename($locator->findResource('account://' . $username . YAML_EXT, true, true)); + } + + // if plain text password, hash it and remove plain text + $password = $this->get('password') ?? $this->get('password1'); + if (null !== $password && '' !== $password) { + $password2 = $this->get('password2'); + if (!\is_string($password) || ($password2 && $password !== $password2)) { + throw new \RuntimeException('Passwords did not match.'); + } + + $this->set('hashed_password', Authentication::create($password)); + } + $this->undef('password'); + $this->undef('password1'); + $this->undef('password2'); + + $data = $this->items; + if ($username === $data['username']) { + unset($data['username']); + } + unset($data['authenticated'], $data['authorized']); + + $file->save($data); + + // We need to signal Flex Users about the change. + /** @var Flex|null $flex */ + $flex = Grav::instance()['flex'] ?? null; + $users = $flex ? $flex->getDirectory('user-accounts') : null; + if (null !== $users) { + $users->clearCache(); + } + } + } + + /** + * @return MediaCollectionInterface|Media + */ + public function getMedia() + { + if (null === $this->_media) { + // Media object should only contain avatar, nothing else. + $media = new Media($this->getMediaFolder() ?? '', $this->getMediaOrder(), false); + + $path = $this->getAvatarFile(); + if ($path && is_file($path)) { + $medium = MediumFactory::fromFile($path); + if ($medium) { + $media->add(Utils::basename($path), $medium); + } + } + + $this->_media = $media; + } + + return $this->_media; + } + + /** + * @return string + */ + public function getMediaFolder() + { + return $this->blueprints()->fields()['avatar']['destination'] ?? 'account://avatars'; + } + + /** + * @return array + */ + public function getMediaOrder() + { + return []; + } + + /** + * Serialize user. + * + * @return string[] + */ + public function __sleep() + { + return [ + 'items', + 'storage' + ]; + } + + /** + * Unserialize user. + */ + public function __wakeup() + { + $this->gettersVariable = 'items'; + $this->nestedSeparator = '.'; + + if (null === $this->items) { + $this->items = []; + } + + // Always set blueprints. + if (null === $this->blueprints) { + $this->blueprints = (new Blueprints)->get('user/account'); + } + } + + /** + * Merge two configurations together. + * + * @param array $data + * @return $this + * @deprecated 1.6 Use `->update($data)` instead (same but with data validation & filtering, file upload support). + */ + public function merge(array $data) + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use ->update($data) method instead', E_USER_DEPRECATED); + + return $this->update($data); + } + + /** + * Return media object for the User's avatar. + * + * @return Medium|null + * @deprecated 1.6 Use ->getAvatarImage() method instead. + */ + public function getAvatarMedia() + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use getAvatarImage() method instead', E_USER_DEPRECATED); + + return $this->getAvatarImage(); + } + + /** + * Return the User's avatar URL + * + * @return string + * @deprecated 1.6 Use ->getAvatarUrl() method instead. + */ + public function avatarUrl() + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use getAvatarUrl() method instead', E_USER_DEPRECATED); + + return $this->getAvatarUrl(); + } + + /** + * Checks user authorization to the action. + * Ensures backwards compatibility + * + * @param string $action + * @return bool + * @deprecated 1.5 Use ->authorize() method instead. + */ + public function authorise($action) + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use authorize() method instead', E_USER_DEPRECATED); + + return $this->authorize($action) ?? false; + } + + /** + * Implements Countable interface. + * + * @return int + * @deprecated 1.6 Method makes no sense for user account. + */ + #[\ReturnTypeWillChange] + public function count() + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6', E_USER_DEPRECATED); + + return parent::count(); + } + + /** + * @param string $username + * @return string + */ + protected function filterUsername(string $username): string + { + return mb_strtolower($username); + } + + /** + * @return string|null + */ + protected function getAvatarFile(): ?string + { + $avatars = $this->get('avatar'); + if (is_array($avatars) && $avatars) { + $avatar = array_shift($avatars); + return $avatar['path'] ?? null; + } + + return null; + } +} diff --git a/system/src/Grav/Common/User/DataUser/UserCollection.php b/system/src/Grav/Common/User/DataUser/UserCollection.php new file mode 100644 index 0000000..3db16d3 --- /dev/null +++ b/system/src/Grav/Common/User/DataUser/UserCollection.php @@ -0,0 +1,163 @@ +className = $className; + } + + /** + * Load user account. + * + * Always creates user object. To check if user exists, use $this->exists(). + * + * @param string $username + * @return UserInterface + */ + public function load($username): UserInterface + { + $username = (string)$username; + + $grav = Grav::instance(); + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + + // Filter username. + $username = $this->filterUsername($username); + + $filename = 'account://' . $username . YAML_EXT; + $path = $locator->findResource($filename) ?: $locator->findResource($filename, true, true); + if (!is_string($path)) { + throw new RuntimeException('Internal Error'); + } + $file = CompiledYamlFile::instance($path); + $content = (array)$file->content() + ['username' => $username, 'state' => 'enabled']; + + $userClass = $this->className; + $callable = static function () { + $blueprints = new Blueprints; + + return $blueprints->get('user/account'); + }; + + /** @var UserInterface $user */ + $user = new $userClass($content, $callable); + $user->file($file); + + return $user; + } + + /** + * Find a user by username, email, etc + * + * @param string $query the query to search for + * @param array $fields the fields to search + * @return UserInterface + */ + public function find($query, $fields = ['username', 'email']): UserInterface + { + $fields = (array)$fields; + + $grav = Grav::instance(); + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + + $account_dir = $locator->findResource('account://'); + if (!is_string($account_dir)) { + return $this->load(''); + } + + $files = array_diff(scandir($account_dir) ?: [], ['.', '..']); + + // Try with username first, you never know! + if (in_array('username', $fields, true)) { + $user = $this->load($query); + unset($fields[array_search('username', $fields, true)]); + } else { + $user = $this->load(''); + } + + // If not found, try the fields + if (!$user->exists()) { + $query = mb_strtolower($query); + foreach ($files as $file) { + if (Utils::endsWith($file, YAML_EXT)) { + $find_user = $this->load(trim(Utils::pathinfo($file, PATHINFO_FILENAME))); + foreach ($fields as $field) { + if (isset($find_user[$field]) && mb_strtolower($find_user[$field]) === $query) { + return $find_user; + } + } + } + } + } + return $user; + } + + /** + * Remove user account. + * + * @param string $username + * @return bool True if the action was performed + */ + public function delete($username): bool + { + $file_path = Grav::instance()['locator']->findResource('account://' . $username . YAML_EXT); + + return $file_path && unlink($file_path); + } + + /** + * @return int + */ + public function count(): int + { + // check for existence of a user account + $account_dir = $file_path = Grav::instance()['locator']->findResource('account://'); + $accounts = glob($account_dir . '/*.yaml') ?: []; + + return count($accounts); + } + + /** + * @param string $username + * @return string + */ + protected function filterUsername(string $username): string + { + return mb_strtolower($username); + } +} diff --git a/system/src/Grav/Common/User/Group.php b/system/src/Grav/Common/User/Group.php new file mode 100644 index 0000000..7f8ab70 --- /dev/null +++ b/system/src/Grav/Common/User/Group.php @@ -0,0 +1,172 @@ +get('groups', []); + } + + /** + * Get the groups list + * + * @return array + * @deprecated 1.7, use $grav['user_groups'] Flex UserGroupCollection instead + */ + public static function groupNames() + { + user_error(__METHOD__ . '() is deprecated since Grav 1.7, use $grav[\'user_groups\'] Flex UserGroupCollection instead', E_USER_DEPRECATED); + + $groups = []; + + foreach (static::groups() as $groupname => $group) { + $groups[$groupname] = $group['readableName'] ?? $groupname; + } + + return $groups; + } + + /** + * Checks if a group exists + * + * @param string $groupname + * @return bool + * @deprecated 1.7, use $grav['user_groups'] Flex UserGroupCollection instead + */ + public static function groupExists($groupname) + { + user_error(__METHOD__ . '() is deprecated since Grav 1.7, use $grav[\'user_groups\'] Flex UserGroupCollection instead', E_USER_DEPRECATED); + + return isset(self::groups()[$groupname]); + } + + /** + * Get a group by name + * + * @param string $groupname + * @return object + * @deprecated 1.7, use $grav['user_groups'] Flex UserGroupCollection instead + */ + public static function load($groupname) + { + user_error(__METHOD__ . '() is deprecated since Grav 1.7, use $grav[\'user_groups\'] Flex UserGroupCollection instead', E_USER_DEPRECATED); + + $groups = self::groups(); + + $content = $groups[$groupname] ?? []; + $content += ['groupname' => $groupname]; + + $blueprints = new Blueprints(); + $blueprint = $blueprints->get('user/group'); + + return new Group($content, $blueprint); + } + + /** + * Save a group + * + * @return void + */ + public function save() + { + $grav = Grav::instance(); + + /** @var Config $config */ + $config = $grav['config']; + + $blueprints = new Blueprints(); + $blueprint = $blueprints->get('user/group'); + + $config->set("groups.{$this->get('groupname')}", []); + + $fields = $blueprint->fields(); + foreach ($fields as $field) { + if ($field['type'] === 'text') { + $value = $field['name']; + if (isset($this->items['data'][$value])) { + $config->set("groups.{$this->get('groupname')}.{$value}", $this->items['data'][$value]); + } + } + if ($field['type'] === 'array' || $field['type'] === 'permissions') { + $value = $field['name']; + $arrayValues = Utils::getDotNotation($this->items['data'], $field['name']); + + if ($arrayValues) { + foreach ($arrayValues as $arrayIndex => $arrayValue) { + $config->set("groups.{$this->get('groupname')}.{$value}.{$arrayIndex}", $arrayValue); + } + } + } + } + + $type = 'groups'; + $blueprints = $this->blueprints(); + + $filename = CompiledYamlFile::instance($grav['locator']->findResource("config://{$type}.yaml")); + + $obj = new Data($config->get($type), $blueprints); + $obj->file($filename); + $obj->save(); + } + + /** + * Remove a group + * + * @param string $groupname + * @return bool True if the action was performed + * @deprecated 1.7, use $grav['user_groups'] Flex UserGroupCollection instead + */ + public static function remove($groupname) + { + user_error(__METHOD__ . '() is deprecated since Grav 1.7, use $grav[\'user_groups\'] Flex UserGroupCollection instead', E_USER_DEPRECATED); + + $grav = Grav::instance(); + + /** @var Config $config */ + $config = $grav['config']; + + $blueprints = new Blueprints(); + $blueprint = $blueprints->get('user/group'); + + $type = 'groups'; + + $groups = $config->get($type); + unset($groups[$groupname]); + $config->set($type, $groups); + + $filename = CompiledYamlFile::instance($grav['locator']->findResource("config://{$type}.yaml")); + + $obj = new Data($groups, $blueprint); + $obj->file($filename); + $obj->save(); + + return true; + } +} diff --git a/system/src/Grav/Common/User/Interfaces/AuthorizeInterface.php b/system/src/Grav/Common/User/Interfaces/AuthorizeInterface.php new file mode 100644 index 0000000..1045522 --- /dev/null +++ b/system/src/Grav/Common/User/Interfaces/AuthorizeInterface.php @@ -0,0 +1,26 @@ +exists(). + * + * @param string $username + * @return UserInterface + */ + public function load($username): UserInterface; + + /** + * Find a user by username, email, etc + * + * @param string $query the query to search for + * @param array $fields the fields to search + * @return UserInterface + */ + public function find($query, $fields = ['username', 'email']): UserInterface; + + /** + * Delete user account. + * + * @param string $username + * @return bool True if user account was found and was deleted. + */ + public function delete($username): bool; +} diff --git a/system/src/Grav/Common/User/Interfaces/UserGroupInterface.php b/system/src/Grav/Common/User/Interfaces/UserGroupInterface.php new file mode 100644 index 0000000..63e103c --- /dev/null +++ b/system/src/Grav/Common/User/Interfaces/UserGroupInterface.php @@ -0,0 +1,18 @@ +get('this.is.my.nested.variable'); + * + * @param string $name Dot separated path to the requested value. + * @param mixed $default Default value (or null). + * @param string|null $separator Separator, defaults to '.' + * @return mixed Value. + */ + public function get($name, $default = null, $separator = null); + + /** + * Set value by using dot notation for nested arrays/objects. + * + * @example $data->set('this.is.my.nested.variable', $value); + * + * @param string $name Dot separated path to the requested value. + * @param mixed $value New value. + * @param string|null $separator Separator, defaults to '.' + * @return $this + */ + public function set($name, $value, $separator = null); + + /** + * Unset value by using dot notation for nested arrays/objects. + * + * @example $data->undef('this.is.my.nested.variable'); + * + * @param string $name Dot separated path to the requested value. + * @param string|null $separator Separator, defaults to '.' + * @return $this + */ + public function undef($name, $separator = null); + + /** + * Set default value by using dot notation for nested arrays/objects. + * + * @example $data->def('this.is.my.nested.variable', 'default'); + * + * @param string $name Dot separated path to the requested value. + * @param mixed $default Default value (or null). + * @param string|null $separator Separator, defaults to '.' + * @return $this + */ + public function def($name, $default = null, $separator = null); + + /** + * Join nested values together by using blueprints. + * + * @param string $name Dot separated path to the requested value. + * @param mixed $value Value to be joined. + * @param string $separator Separator, defaults to '.' + * @return $this + * @throws RuntimeException + */ + public function join($name, $value, $separator = '.'); + + /** + * Get nested structure containing default values defined in the blueprints. + * + * Fields without default value are ignored in the list. + + * @return array + */ + public function getDefaults(); + + /** + * Set default values by using blueprints. + * + * @param string $name Dot separated path to the requested value. + * @param mixed $value Value to be joined. + * @param string $separator Separator, defaults to '.' + * @return $this + */ + public function joinDefaults($name, $value, $separator = '.'); + + /** + * Get value from the configuration and join it with given data. + * + * @param string $name Dot separated path to the requested value. + * @param array|object $value Value to be joined. + * @param string $separator Separator, defaults to '.' + * @return array + * @throws RuntimeException + */ + public function getJoined($name, $value, $separator = '.'); + + /** + * Set default values to the configuration if variables were not set. + * + * @param array $data + * @return $this + */ + public function setDefaults(array $data); + + /** + * Update object with data + * + * @param array $data + * @param array $files + * @return $this + */ + public function update(array $data, array $files = []); + + /** + * Returns whether the data already exists in the storage. + * + * NOTE: This method does not check if the data is current. + * + * @return bool + */ + public function exists(); + + /** + * Return unmodified data as raw string. + * + * NOTE: This function only returns data which has been saved to the storage. + * + * @return string + */ + public function raw(); + + /** + * Authenticate user. + * + * If user password needs to be updated, new information will be saved. + * + * @param string $password Plaintext password. + * @return bool + */ + public function authenticate(string $password): bool; + + /** + * Return media object for the User's avatar. + * + * Note: if there's no local avatar image for the user, you should call getAvatarUrl() to get the external avatar URL. + * + * @return Medium|null + */ + public function getAvatarImage(): ?Medium; + + /** + * Return the User's avatar URL. + * + * @return string + */ + public function getAvatarUrl(): string; +} diff --git a/system/src/Grav/Common/User/Traits/UserTrait.php b/system/src/Grav/Common/User/Traits/UserTrait.php new file mode 100644 index 0000000..8afcac0 --- /dev/null +++ b/system/src/Grav/Common/User/Traits/UserTrait.php @@ -0,0 +1,233 @@ +get('hashed_password'); + + $isHashed = null !== $hash; + if (!$isHashed) { + // If there is no hashed password, fake verify with default hash. + $hash = Grav::instance()['config']->get('system.security.default_hash'); + } + + // Always execute verify() to protect us from timing attacks, but make the test to fail if hashed password wasn't set. + $result = Authentication::verify($password, $hash) && $isHashed; + + $plaintext_password = $this->get('password'); + if (null !== $plaintext_password) { + // Plain-text password is still stored, check if it matches. + if ($password !== $plaintext_password) { + return false; + } + + // Force hash update to get rid of plaintext password. + $result = 2; + } + + if ($result === 2) { + // Password needs to be updated, save the user. + $this->set('password', $password); + $this->undef('hashed_password'); + $this->save(); + } + + return (bool)$result; + } + + /** + * Checks user authorization to the action. + * + * @param string $action + * @param string|null $scope + * @return bool|null + */ + public function authorize(string $action, string $scope = null): ?bool + { + // User needs to be enabled. + if ($this->get('state', 'enabled') !== 'enabled') { + return false; + } + + // User needs to be logged in. + if (!$this->get('authenticated')) { + return false; + } + + // User needs to be authorized (2FA). + if (strpos($action, 'login') === false && !$this->get('authorized', true)) { + return false; + } + + if (null !== $scope) { + $action = $scope . '.' . $action; + } + + $config = Grav::instance()['config']; + $authorized = false; + + //Check group access level + $groups = (array)$this->get('groups'); + foreach ($groups as $group) { + $permission = $config->get("groups.{$group}.access.{$action}"); + $authorized = Utils::isPositive($permission); + if ($authorized === true) { + break; + } + } + + //Check user access level + $access = $this->get('access'); + if ($access && Utils::getDotNotation($access, $action) !== null) { + $permission = $this->get("access.{$action}"); + $authorized = Utils::isPositive($permission); + } + + return $authorized; + } + + /** + * Return media object for the User's avatar. + * + * Note: if there's no local avatar image for the user, you should call getAvatarUrl() to get the external avatar URL. + * + * @return ImageMedium|StaticImageMedium|null + */ + public function getAvatarImage(): ?Medium + { + $avatars = $this->get('avatar'); + if (is_array($avatars) && $avatars) { + $avatar = array_shift($avatars); + + $media = $this->getMedia(); + $name = $avatar['name'] ?? null; + + $image = $name ? $media[$name] : null; + if ($image instanceof ImageMedium || + $image instanceof StaticImageMedium) { + return $image; + } + } + + return null; + } + + /** + * Return the User's avatar URL + * + * @return string + */ + public function getAvatarUrl(): string + { + // Try to locate avatar image. + $avatar = $this->getAvatarImage(); + if ($avatar) { + return $avatar->url(); + } + + // Try if avatar is a sting (URL). + $avatar = $this->get('avatar'); + if (is_string($avatar)) { + return $avatar; + } + + // Try looking for provider. + $provider = $this->get('provider'); + $provider_options = $this->get($provider); + if (is_array($provider_options)) { + if (isset($provider_options['avatar_url']) && is_string($provider_options['avatar_url'])) { + return $provider_options['avatar_url']; + } + if (isset($provider_options['avatar']) && is_string($provider_options['avatar'])) { + return $provider_options['avatar']; + } + } + + $email = $this->get('email'); + $avatar_generator = Grav::instance()['config']->get('system.accounts.avatar', 'multiavatar'); + if ($avatar_generator === 'gravatar') { + if (!$email) { + return ''; + } + + $hash = md5(strtolower(trim($email))); + + return 'https://www.gravatar.com/avatar/' . $hash; + } + + $hash = $this->get('avatar_hash'); + if (!$hash) { + $username = $this->get('username'); + $hash = md5(strtolower(trim($email ?? $username))); + } + + return $this->generateMultiavatar($hash); + } + + /** + * @param string $hash + * @return string + */ + protected function generateMultiavatar(string $hash): string + { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + + $storage = $locator->findResource('image://multiavatar', true, true); + $avatar_file = "{$storage}/{$hash}.svg"; + + if (!file_exists($storage)) { + Folder::create($storage); + } + + if (!file_exists($avatar_file)) { + $mavatar = new Multiavatar(); + + file_put_contents($avatar_file, $mavatar->generate($hash, null, null)); + } + + $avatar_url = $locator->findResource("image://multiavatar/{$hash}.svg", false, true); + + return Utils::url($avatar_url); + + } + + abstract public function get($name, $default = null, $separator = null); + abstract public function set($name, $value, $separator = null); + abstract public function undef($name, $separator = null); + abstract public function save(); +} diff --git a/system/src/Grav/Common/User/User.php b/system/src/Grav/Common/User/User.php new file mode 100644 index 0000000..e87302e --- /dev/null +++ b/system/src/Grav/Common/User/User.php @@ -0,0 +1,144 @@ +exists(). + * + * @param string $username + * @return UserInterface + * @deprecated 1.6 Use $grav['accounts']->load(...) instead. + */ + public static function load($username) + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use $grav[\'accounts\']->' . __FUNCTION__ . '() instead', E_USER_DEPRECATED); + + return static::getCollection()->load($username); + } + + /** + * Find a user by username, email, etc + * + * Always creates user object. To check if user exists, use $this->exists(). + * + * @param string $query the query to search for + * @param array $fields the fields to search + * @return UserInterface + * @deprecated 1.6 Use $grav['accounts']->find(...) instead. + */ + public static function find($query, $fields = ['username', 'email']) + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use $grav[\'accounts\']->' . __FUNCTION__ . '() instead', E_USER_DEPRECATED); + + return static::getCollection()->find($query, $fields); + } + + /** + * Remove user account. + * + * @param string $username + * @return bool True if the action was performed + * @deprecated 1.6 Use $grav['accounts']->delete(...) instead. + */ + public static function remove($username) + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use $grav[\'accounts\']->delete() instead', E_USER_DEPRECATED); + + return static::getCollection()->delete($username); + } + + /** + * @return UserCollectionInterface + */ + protected static function getCollection() + { + return Grav::instance()['accounts']; + } + } +} else { + /** + * @deprecated 1.6 Use $grav['accounts'] instead of static calls. In type hints, use UserInterface. + */ + class User extends DataUser\User + { + /** + * Load user account. + * + * Always creates user object. To check if user exists, use $this->exists(). + * + * @param string $username + * @return UserInterface + * @deprecated 1.6 Use $grav['accounts']->load(...) instead. + */ + public static function load($username) + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use $grav[\'accounts\']->' . __FUNCTION__ . '() instead', E_USER_DEPRECATED); + + return static::getCollection()->load($username); + } + + /** + * Find a user by username, email, etc + * + * Always creates user object. To check if user exists, use $this->exists(). + * + * @param string $query the query to search for + * @param array $fields the fields to search + * @return UserInterface + * @deprecated 1.6 Use $grav['accounts']->find(...) instead. + */ + public static function find($query, $fields = ['username', 'email']) + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use $grav[\'accounts\']->' . __FUNCTION__ . '() instead', E_USER_DEPRECATED); + + return static::getCollection()->find($query, $fields); + } + + /** + * Remove user account. + * + * @param string $username + * @return bool True if the action was performed + * @deprecated 1.6 Use $grav['accounts']->delete(...) instead. + */ + public static function remove($username) + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use $grav[\'accounts\']->delete() instead', E_USER_DEPRECATED); + + return static::getCollection()->delete($username); + } + + /** + * @return UserCollectionInterface + */ + protected static function getCollection() + { + return Grav::instance()['accounts']; + } + } +} diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php new file mode 100644 index 0000000..582fe5e --- /dev/null +++ b/system/src/Grav/Common/Utils.php @@ -0,0 +1,2227 @@ +schemeExists($scheme)) { + // If scheme does not exists as a stream, assume it's external. + return str_replace(' ', '%20', $input); + } + + // Attempt to find the resource (because of parse_url() we need to put host back to path). + $resource = $locator->findResource("{$scheme}://{$host}{$path}", false); + + if ($resource === false) { + if (!$fail_gracefully) { + return false; + } + + // Return location where the file would be if it was saved. + $resource = $locator->findResource("{$scheme}://{$host}{$path}", false, true); + } + } elseif ($host || $port) { + // If URL doesn't have scheme but has host or port, it is external. + return str_replace(' ', '%20', $input); + } + + if (!empty($resource)) { + // Add query string back. + if (isset($parts['query'])) { + $resource .= '?' . $parts['query']; + } + + // Add fragment back. + if (isset($parts['fragment'])) { + $resource .= '#' . $parts['fragment']; + } + } + } else { + // Not a valid URL (can still be a stream). + $resource = $locator->findResource($input, false); + } + } else { + // Just a path. + /** @var Pages $pages */ + $pages = $grav['pages']; + + // Is this a page? + $page = $pages->find($input, true); + if ($page && $page->routable()) { + return $page->url($domain); + } + + $root = preg_quote($uri->rootUrl(), '#'); + $pattern = '#(' . $root . '$|' . $root . '/)#'; + if (!empty($root) && preg_match($pattern, $input, $matches)) { + $input = static::replaceFirstOccurrence($matches[0], '', $input); + } + + $input = ltrim($input, '/'); + $resource = $input; + } + + if (!$fail_gracefully && $resource === false) { + return false; + } + + $domain = $domain ?: $grav['config']->get('system.absolute_urls', false); + + return rtrim($uri->rootUrl($domain), '/') . '/' . ($resource ?: ''); + } + + /** + * Helper method to find the full path to a file, be it a stream, a relative path, or + * already a full path + * + * @param string $path + * @return string + */ + public static function fullPath($path) + { + $locator = Grav::instance()['locator']; + + if ($locator->isStream($path)) { + $path = $locator->findResource($path, true); + } elseif (!static::startsWith($path, GRAV_ROOT)) { + $base_url = Grav::instance()['base_url']; + $path = GRAV_ROOT . '/' . ltrim(static::replaceFirstOccurrence($base_url, '', $path), '/'); + } + + return $path; + } + + + /** + * Check if the $haystack string starts with the substring $needle + * + * @param string $haystack + * @param string|string[] $needle + * @param bool $case_sensitive + * @return bool + */ + public static function startsWith($haystack, $needle, $case_sensitive = true) + { + $status = false; + + $compare_func = $case_sensitive ? 'mb_strpos' : 'mb_stripos'; + + foreach ((array)$needle as $each_needle) { + $status = $each_needle === '' || $compare_func((string) $haystack, $each_needle) === 0; + if ($status) { + break; + } + } + + return $status; + } + + /** + * Check if the $haystack string ends with the substring $needle + * + * @param string $haystack + * @param string|string[] $needle + * @param bool $case_sensitive + * @return bool + */ + public static function endsWith($haystack, $needle, $case_sensitive = true) + { + $status = false; + + $compare_func = $case_sensitive ? 'mb_strrpos' : 'mb_strripos'; + + foreach ((array)$needle as $each_needle) { + $expectedPosition = mb_strlen((string) $haystack) - mb_strlen($each_needle); + $status = $each_needle === '' || $compare_func((string) $haystack, $each_needle, 0) === $expectedPosition; + if ($status) { + break; + } + } + + return $status; + } + + /** + * Check if the $haystack string contains the substring $needle + * + * @param string $haystack + * @param string|string[] $needle + * @param bool $case_sensitive + * @return bool + */ + public static function contains($haystack, $needle, $case_sensitive = true) + { + $status = false; + + $compare_func = $case_sensitive ? 'mb_strpos' : 'mb_stripos'; + + foreach ((array)$needle as $each_needle) { + $status = $each_needle === '' || $compare_func((string) $haystack, $each_needle) !== false; + if ($status) { + break; + } + } + + return $status; + } + + /** + * Function that can match wildcards + * + * match_wildcard('foo*', $test), // TRUE + * match_wildcard('bar*', $test), // FALSE + * match_wildcard('*bar*', $test), // TRUE + * match_wildcard('**blob**', $test), // TRUE + * match_wildcard('*a?d*', $test), // TRUE + * match_wildcard('*etc**', $test) // TRUE + * + * @param string $wildcard_pattern + * @param string $haystack + * @return false|int + */ + public static function matchWildcard($wildcard_pattern, $haystack) + { + $regex = str_replace( + array("\*", "\?"), // wildcard chars + array('.*', '.'), // regexp chars + preg_quote($wildcard_pattern, '/') + ); + + return preg_match('/^' . $regex . '$/is', $haystack); + } + + /** + * Render simple template filling up the variables in it. If value is not defined, leave it as it was. + * + * @param string $template Template string + * @param array $variables Variables with values + * @param array $brackets Optional array of opening and closing brackets or symbols + * @return string Final string filled with values + */ + public static function simpleTemplate(string $template, array $variables, array $brackets = ['{', '}']): string + { + $opening = $brackets[0] ?? '{'; + $closing = $brackets[1] ?? '}'; + $expression = '/' . preg_quote($opening, '/') . '(.*?)' . preg_quote($closing, '/') . '/'; + $callback = static function ($match) use ($variables) { + return $variables[$match[1]] ?? $match[0]; + }; + + return preg_replace_callback($expression, $callback, $template); + } + + /** + * Returns the substring of a string up to a specified needle. if not found, return the whole haystack + * + * @param string $haystack + * @param string $needle + * @param bool $case_sensitive + * + * @return string + */ + public static function substrToString($haystack, $needle, $case_sensitive = true) + { + $compare_func = $case_sensitive ? 'mb_strpos' : 'mb_stripos'; + + if (static::contains($haystack, $needle, $case_sensitive)) { + return mb_substr($haystack, 0, $compare_func($haystack, $needle, $case_sensitive)); + } + + return $haystack; + } + + /** + * Utility method to replace only the first occurrence in a string + * + * @param string $search + * @param string $replace + * @param string $subject + * + * @return string + */ + public static function replaceFirstOccurrence($search, $replace, $subject) + { + if (!$search) { + return $subject; + } + + $pos = mb_strpos($subject, $search); + if ($pos !== false) { + $subject = static::mb_substr_replace($subject, $replace, $pos, mb_strlen($search)); + } + + + return $subject; + } + + /** + * Utility method to replace only the last occurrence in a string + * + * @param string $search + * @param string $replace + * @param string $subject + * @return string + */ + public static function replaceLastOccurrence($search, $replace, $subject) + { + $pos = strrpos($subject, $search); + + if ($pos !== false) { + $subject = static::mb_substr_replace($subject, $replace, $pos, mb_strlen($search)); + } + + return $subject; + } + + /** + * Multibyte compatible substr_replace + * + * @param string $original + * @param string $replacement + * @param int $position + * @param int $length + * @return string + */ + public static function mb_substr_replace($original, $replacement, $position, $length) + { + $startString = mb_substr($original, 0, $position, 'UTF-8'); + $endString = mb_substr($original, $position + $length, mb_strlen($original), 'UTF-8'); + + return $startString . $replacement . $endString; + } + + /** + * Merge two objects into one. + * + * @param object $obj1 + * @param object $obj2 + * + * @return object + */ + public static function mergeObjects($obj1, $obj2) + { + return (object)array_merge((array)$obj1, (array)$obj2); + } + + /** + * @param array $array + * @return bool + */ + public static function isAssoc(array $array) + { + return (array_values($array) !== $array); + } + + /** + * Lowercase an entire array. Useful when combined with `in_array()` + * + * @param array $a + * @return array|false + */ + public static function arrayLower(array $a) + { + return array_map('mb_strtolower', $a); + } + + /** + * Simple function to remove item/s in an array by value + * + * @param array $search + * @param string|array $value + * @return array + */ + public static function arrayRemoveValue(array $search, $value) + { + foreach ((array)$value as $val) { + $key = array_search($val, $search); + if ($key !== false) { + unset($search[$key]); + } + } + return $search; + } + + /** + * Recursive Merge with uniqueness + * + * @param array $array1 + * @param array $array2 + * @return array + */ + public static function arrayMergeRecursiveUnique($array1, $array2) + { + if (empty($array1)) { + // Optimize the base case + return $array2; + } + + foreach ($array2 as $key => $value) { + if (is_array($value) && isset($array1[$key]) && is_array($array1[$key])) { + $value = static::arrayMergeRecursiveUnique($array1[$key], $value); + } + $array1[$key] = $value; + } + + return $array1; + } + + /** + * Returns an array with the differences between $array1 and $array2 + * + * @param array $array1 + * @param array $array2 + * @return array + */ + public static function arrayDiffMultidimensional($array1, $array2) + { + $result = array(); + foreach ($array1 as $key => $value) { + if (!is_array($array2) || !array_key_exists($key, $array2)) { + $result[$key] = $value; + continue; + } + if (is_array($value)) { + $recursiveArrayDiff = static::ArrayDiffMultidimensional($value, $array2[$key]); + if (count($recursiveArrayDiff)) { + $result[$key] = $recursiveArrayDiff; + } + continue; + } + if ($value != $array2[$key]) { + $result[$key] = $value; + } + } + + return $result; + } + + /** + * Array combine but supports different array lengths + * + * @param array $arr1 + * @param array $arr2 + * @return array|false + */ + public static function arrayCombine($arr1, $arr2) + { + $count = min(count($arr1), count($arr2)); + + return array_combine(array_slice($arr1, 0, $count), array_slice($arr2, 0, $count)); + } + + /** + * Array is associative or not + * + * @param array $arr + * @return bool + */ + public static function arrayIsAssociative($arr) + { + if ([] === $arr) { + return false; + } + + return array_keys($arr) !== range(0, count($arr) - 1); + } + + /** + * Return the Grav date formats allowed + * + * @return array + */ + public static function dateFormats() + { + $now = new DateTime(); + + $date_formats = [ + 'd-m-Y H:i' => 'd-m-Y H:i (e.g. ' . $now->format('d-m-Y H:i') . ')', + 'Y-m-d H:i' => 'Y-m-d H:i (e.g. ' . $now->format('Y-m-d H:i') . ')', + 'm/d/Y h:i a' => 'm/d/Y h:i a (e.g. ' . $now->format('m/d/Y h:i a') . ')', + 'H:i d-m-Y' => 'H:i d-m-Y (e.g. ' . $now->format('H:i d-m-Y') . ')', + 'h:i a m/d/Y' => 'h:i a m/d/Y (e.g. ' . $now->format('h:i a m/d/Y') . ')', + ]; + $default_format = Grav::instance()['config']->get('system.pages.dateformat.default'); + if ($default_format) { + $date_formats = array_merge([$default_format => $default_format . ' (e.g. ' . $now->format($default_format) . ')'], $date_formats); + } + + return $date_formats; + } + + /** + * Get current date/time + * + * @param string|null $default_format + * @return string + * @throws Exception + */ + public static function dateNow($default_format = null) + { + $now = new DateTime(); + + if (null === $default_format) { + $default_format = Grav::instance()['config']->get('system.pages.dateformat.default'); + } + + return $now->format($default_format); + } + + /** + * Truncate text by number of characters but can cut off words. + * + * @param string $string + * @param int $limit Max number of characters. + * @param bool $up_to_break truncate up to breakpoint after char count + * @param string $break Break point. + * @param string $pad Appended padding to the end of the string. + * @return string + */ + public static function truncate($string, $limit = 150, $up_to_break = false, $break = ' ', $pad = '…') + { + // return with no change if string is shorter than $limit + if (mb_strlen($string) <= $limit) { + return $string; + } + + // is $break present between $limit and the end of the string? + if ($up_to_break && false !== ($breakpoint = mb_strpos($string, $break, $limit))) { + if ($breakpoint < mb_strlen($string) - 1) { + $string = mb_substr($string, 0, $breakpoint) . $pad; + } + } else { + $string = mb_substr($string, 0, $limit) . $pad; + } + + return $string; + } + + /** + * Truncate text by number of characters in a "word-safe" manor. + * + * @param string $string + * @param int $limit + * @return string + */ + public static function safeTruncate($string, $limit = 150) + { + return static::truncate($string, $limit, true); + } + + + /** + * Truncate HTML by number of characters. not "word-safe"! + * + * @param string $text + * @param int $length in characters + * @param string $ellipsis + * @return string + */ + public static function truncateHtml($text, $length = 100, $ellipsis = '...') + { + return Truncator::truncateLetters($text, $length, $ellipsis); + } + + /** + * Truncate HTML by number of characters in a "word-safe" manor. + * + * @param string $text + * @param int $length in words + * @param string $ellipsis + * @return string + */ + public static function safeTruncateHtml($text, $length = 25, $ellipsis = '...') + { + return Truncator::truncateWords($text, $length, $ellipsis); + } + + /** + * Generate a random string of a given length + * + * @param int $length + * @return string + */ + public static function generateRandomString($length = 5) + { + return substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, $length); + } + + /** + * Generates a random string with configurable length, prefix and suffix. + * Unlike the built-in `uniqid()`, this string is non-conflicting and safe + * + * @param int $length + * @param array $options + * @return string + * @throws Exception + */ + public static function uniqueId(int $length = 13, array $options = []): string + { + $options = array_merge(['prefix' => '', 'suffix' => ''], $options); + $bytes = random_bytes(ceil($length / 2)); + + return $options['prefix'] . substr(bin2hex($bytes), 0, $length) . $options['suffix']; + } + + /** + * Provides the ability to download a file to the browser + * + * @param string $file the full path to the file to be downloaded + * @param bool $force_download as opposed to letting browser choose if to download or render + * @param int $sec Throttling, try 0.1 for some speed throttling of downloads + * @param int $bytes Size of chunks to send in bytes. Default is 1024 + * @param array $options Extra options: [mime, download_name, expires] + * @throws Exception + */ + public static function download($file, $force_download = true, $sec = 0, $bytes = 1024, array $options = []) + { + $grav = Grav::instance(); + + if (file_exists($file)) { + // fire download event + $grav->fireEvent('onBeforeDownload', new Event(['file' => $file, 'options' => &$options])); + + $file_parts = static::pathinfo($file); + $mimetype = $options['mime'] ?? static::getMimeByExtension($file_parts['extension']); + $size = filesize($file); // File size + + $grav->cleanOutputBuffers(); + + // required for IE, otherwise Content-Disposition may be ignored + if (ini_get('zlib.output_compression')) { + ini_set('zlib.output_compression', 'Off'); + } + + header('Content-Type: ' . $mimetype); + header('Accept-Ranges: bytes'); + + if ($force_download) { + // output the regular HTTP headers + header('Content-Disposition: attachment; filename="' . ($options['download_name'] ?? $file_parts['basename']) . '"'); + } + + // multipart-download and download resuming support + if (isset($_SERVER['HTTP_RANGE'])) { + [$a, $range] = explode('=', $_SERVER['HTTP_RANGE'], 2); + [$range] = explode(',', $range, 2); + [$range, $range_end] = explode('-', $range); + $range = (int)$range; + if (!$range_end) { + $range_end = $size - 1; + } else { + $range_end = (int)$range_end; + } + $new_length = $range_end - $range + 1; + header('HTTP/1.1 206 Partial Content'); + header("Content-Length: {$new_length}"); + header("Content-Range: bytes {$range}-{$range_end}/{$size}"); + } else { + $range = 0; + $new_length = $size; + header('Content-Length: ' . $size); + + if ($grav['config']->get('system.cache.enabled')) { + $expires = $options['expires'] ?? $grav['config']->get('system.pages.expires'); + if ($expires > 0) { + $expires_date = gmdate('D, d M Y H:i:s T', time() + $expires); + header('Cache-Control: max-age=' . $expires); + header('Expires: ' . $expires_date); + header('Pragma: cache'); + } + header('Last-Modified: ' . gmdate('D, d M Y H:i:s T', filemtime($file))); + + // Return 304 Not Modified if the file is already cached in the browser + if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && + strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= filemtime($file)) { + header('HTTP/1.1 304 Not Modified'); + exit(); + } + } + } + + /* output the file itself */ + $chunksize = $bytes * 8; //you may want to change this + $bytes_send = 0; + + $fp = @fopen($file, 'rb'); + if ($fp) { + if ($range) { + fseek($fp, $range); + } + while (!feof($fp) && (!connection_aborted()) && ($bytes_send < $new_length)) { + $buffer = fread($fp, $chunksize); + echo($buffer); //echo($buffer); // is also possible + flush(); + usleep($sec * 1000000); + $bytes_send += strlen($buffer); + } + fclose($fp); + } else { + throw new RuntimeException('Error - can not open file.'); + } + + exit; + } + } + + /** + * Returns the output render format, usually the extension provided in the URL. (e.g. `html`, `json`, `xml`, etc). + * + * @return string + */ + public static function getPageFormat(): string + { + /** @var Uri $uri */ + $uri = Grav::instance()['uri']; + + // Set from uri extension + $uri_extension = $uri->extension(); + if (is_string($uri_extension) && $uri->isValidExtension($uri_extension)) { + return ($uri_extension); + } + + // Use content negotiation via the `accept:` header + $http_accept = $_SERVER['HTTP_ACCEPT'] ?? null; + if (is_string($http_accept)) { + $negotiator = new Negotiator(); + + $supported_types = static::getSupportPageTypes(['html', 'json']); + $priorities = static::getMimeTypes($supported_types); + + $media_type = $negotiator->getBest($http_accept, $priorities); + $mimetype = $media_type instanceof Accept ? $media_type->getValue() : ''; + + return static::getExtensionByMime($mimetype); + } + + return 'html'; + } + + /** + * Return the mimetype based on filename extension + * + * @param string $extension Extension of file (eg "txt") + * @param string $default + * @return string + */ + public static function getMimeByExtension($extension, $default = 'application/octet-stream') + { + $extension = strtolower($extension); + + // look for some standard types + switch ($extension) { + case null: + return $default; + case 'json': + return 'application/json'; + case 'html': + return 'text/html'; + case 'atom': + return 'application/atom+xml'; + case 'rss': + return 'application/rss+xml'; + case 'xml': + return 'application/xml'; + } + + $media_types = Grav::instance()['config']->get('media.types'); + + return $media_types[$extension]['mime'] ?? $default; + } + + /** + * Get all the mimetypes for an array of extensions + * + * @param array $extensions + * @return array + */ + public static function getMimeTypes(array $extensions) + { + $mimetypes = []; + foreach ($extensions as $extension) { + $mimetype = static::getMimeByExtension($extension, false); + if ($mimetype && !in_array($mimetype, $mimetypes)) { + $mimetypes[] = $mimetype; + } + } + return $mimetypes; + } + + /** + * Return all extensions for given mimetype. The first extension is the default one. + * + * @param string $mime Mime type (eg 'image/jpeg') + * @return string[] List of extensions eg. ['jpg', 'jpe', 'jpeg'] + */ + public static function getExtensionsByMime($mime) + { + $mime = strtolower($mime); + + $media_types = (array)Grav::instance()['config']->get('media.types'); + + $list = []; + foreach ($media_types as $extension => $type) { + if ($extension === '' || $extension === 'defaults') { + continue; + } + + if (isset($type['mime']) && $type['mime'] === $mime) { + $list[] = $extension; + } + } + + return $list; + } + + /** + * Return the mimetype based on filename extension + * + * @param string $mime mime type (eg "text/html") + * @param string $default default value + * @return string + */ + public static function getExtensionByMime($mime, $default = 'html') + { + $mime = strtolower($mime); + + // look for some standard mime types + switch ($mime) { + case '*/*': + case 'text/*': + case 'text/html': + return 'html'; + case 'application/json': + return 'json'; + case 'application/atom+xml': + return 'atom'; + case 'application/rss+xml': + return 'rss'; + case 'application/xml': + return 'xml'; + } + + $media_types = (array)Grav::instance()['config']->get('media.types'); + + foreach ($media_types as $extension => $type) { + if ($extension === 'defaults') { + continue; + } + if (isset($type['mime']) && $type['mime'] === $mime) { + return $extension; + } + } + + return $default; + } + + /** + * Get all the extensions for an array of mimetypes + * + * @param array $mimetypes + * @return array + */ + public static function getExtensions(array $mimetypes) + { + $extensions = []; + foreach ($mimetypes as $mimetype) { + $extension = static::getExtensionByMime($mimetype, false); + if ($extension && !in_array($extension, $extensions, true)) { + $extensions[] = $extension; + } + } + + return $extensions; + } + + /** + * Return the mimetype based on filename + * + * @param string $filename Filename or path to file + * @param string $default default value + * @return string + */ + public static function getMimeByFilename($filename, $default = 'application/octet-stream') + { + return static::getMimeByExtension(static::pathinfo($filename, PATHINFO_EXTENSION), $default); + } + + /** + * Return the mimetype based on existing local file + * + * @param string $filename Path to the file + * @param string $default + * @return string|bool + */ + public static function getMimeByLocalFile($filename, $default = 'application/octet-stream') + { + $type = false; + + // For local files we can detect type by the file content. + if (!stream_is_local($filename) || !file_exists($filename)) { + return false; + } + + // Prefer using finfo if it exists. + if (extension_loaded('fileinfo')) { + $finfo = finfo_open(FILEINFO_SYMLINK | FILEINFO_MIME_TYPE); + $type = finfo_file($finfo, $filename); + finfo_close($finfo); + } else { + // Fall back to use getimagesize() if it is available (not recommended, but better than nothing) + $info = @getimagesize($filename); + if ($info) { + $type = $info['mime']; + } + } + + return $type ?: static::getMimeByFilename($filename, $default); + } + + + /** + * Returns true if filename is considered safe. + * + * @param string $filename + * @return bool + */ + public static function checkFilename($filename): bool + { + $dangerous_extensions = Grav::instance()['config']->get('security.uploads_dangerous_extensions', []); + $extension = mb_strtolower(static::pathinfo($filename, PATHINFO_EXTENSION)); + + return !( + // Empty filenames are not allowed. + !$filename + // Filename should not contain horizontal/vertical tabs, newlines, nils or back/forward slashes. + || strtr($filename, "\t\v\n\r\0\\/", '_______') !== $filename + // Filename should not start or end with dot or space. + || trim($filename, '. ') !== $filename + // Filename should not contain path traversal + || str_replace('..', '', $filename) !== $filename + // File extension should not be part of configured dangerous extensions + || in_array($extension, $dangerous_extensions) + ); + } + + /** + * Unicode-safe version of PHP’s pathinfo() function. + * + * @link https://www.php.net/manual/en/function.pathinfo.php + * + * @param string $path + * @param int|null $flags + * @return array|string + */ + public static function pathinfo($path, int $flags = null) + { + $path = str_replace(['%2F', '%5C'], ['/', '\\'], rawurlencode($path)); + + if (null === $flags) { + $info = pathinfo($path); + } else { + $info = pathinfo($path, $flags); + } + + if (is_array($info)) { + return array_map('rawurldecode', $info); + } + + return rawurldecode($info); + } + + /** + * Unicode-safe version of the PHP basename() function. + * + * @link https://www.php.net/manual/en/function.basename.php + * + * @param string $path + * @param string $suffix + * @return string + */ + public static function basename($path, string $suffix = ''): string + { + return rawurldecode(basename(str_replace(['%2F', '%5C'], '/', rawurlencode($path)), $suffix)); + } + + /** + * Normalize path by processing relative `.` and `..` syntax and merging path + * + * @param string $path + * @return string + */ + public static function normalizePath($path) + { + // Resolve any streams + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + if ($locator->isStream($path)) { + $path = $locator->findResource($path); + } + + // Set root properly for any URLs + $root = ''; + preg_match(self::ROOTURL_REGEX, $path, $matches); + if ($matches) { + $root = $matches[1]; + $path = $matches[2]; + } + + // Strip off leading / to ensure explode is accurate + if (static::startsWith($path, '/')) { + $root .= '/'; + $path = ltrim($path, '/'); + } + + // If there are any relative paths (..) handle those + if (static::contains($path, '..')) { + $segments = explode('/', trim($path, '/')); + $ret = []; + foreach ($segments as $segment) { + if (($segment === '.') || $segment === '') { + continue; + } + if ($segment === '..') { + array_pop($ret); + } else { + $ret[] = $segment; + } + } + $path = implode('/', $ret); + } + + // Stick everything back together + $normalized = $root . $path; + + return $normalized; + } + + /** + * Check whether a function exists. + * + * Disabled functions count as non-existing functions, just like in PHP 8+. + * + * @param string $function the name of the function to check + * @return bool + */ + public static function functionExists($function): bool + { + if (!function_exists($function)) { + return false; + } + + // In PHP 7 we need to also exclude disabled methods. + return !static::isFunctionDisabled($function); + } + + /** + * Check whether a function is disabled in the PHP settings + * + * @param string $function the name of the function to check + * @return bool + */ + public static function isFunctionDisabled($function): bool + { + static $list; + + if (null === $list) { + $str = trim(ini_get('disable_functions') . ',' . ini_get('suhosin.executor.func.blacklist'), ','); + $list = $str ? array_flip(preg_split('/\s*,\s*/', $str)) : []; + } + + return array_key_exists($function, $list); + } + + /** + * Get the formatted timezones list + * + * @return array + */ + public static function timezones() + { + $timezones = DateTimeZone::listIdentifiers(DateTimeZone::ALL); + $offsets = []; + $testDate = new DateTime(); + + foreach ($timezones as $zone) { + $tz = new DateTimeZone($zone); + $offsets[$zone] = $tz->getOffset($testDate); + } + + asort($offsets); + + $timezone_list = []; + foreach ($offsets as $timezone => $offset) { + $offset_prefix = $offset < 0 ? '-' : '+'; + $offset_formatted = gmdate('H:i', abs($offset)); + + $pretty_offset = "UTC{$offset_prefix}{$offset_formatted}"; + + $timezone_list[$timezone] = "({$pretty_offset}) " . str_replace('_', ' ', $timezone); + } + + return $timezone_list; + } + + /** + * Recursively filter an array, filtering values by processing them through the $fn function argument + * + * @param array $source the Array to filter + * @param callable $fn the function to pass through each array item + * @return array + */ + public static function arrayFilterRecursive(array $source, $fn) + { + $result = []; + foreach ($source as $key => $value) { + if (is_array($value)) { + $result[$key] = static::arrayFilterRecursive($value, $fn); + continue; + } + if ($fn($key, $value)) { + $result[$key] = $value; // KEEP + continue; + } + } + + return $result; + } + + /** + * Flatten a multi-dimensional associative array into query params. + * + * @param array $array + * @param string $prepend + * @return array + */ + public static function arrayToQueryParams($array, $prepend = '') + { + $results = []; + foreach ($array as $key => $value) { + $name = $prepend ? $prepend . '[' . $key . ']' : $key; + + if (is_array($value)) { + $results = array_merge($results, static::arrayToQueryParams($value, $name)); + } else { + $results[$name] = $value; + } + } + + return $results; + } + + /** + * Flatten an array + * + * @param array $array + * @return array + */ + public static function arrayFlatten($array) + { + $flatten = []; + foreach ($array as $key => $inner) { + if (is_array($inner)) { + foreach ($inner as $inner_key => $value) { + $flatten[$inner_key] = $value; + } + } else { + $flatten[$key] = $inner; + } + } + + return $flatten; + } + + /** + * Flatten a multi-dimensional associative array into dot notation + * + * @param array $array + * @param string $prepend + * @return array + */ + public static function arrayFlattenDotNotation($array, $prepend = '') + { + $results = array(); + foreach ($array as $key => $value) { + if (is_array($value)) { + $results = array_merge($results, static::arrayFlattenDotNotation($value, $prepend . $key . '.')); + } else { + $results[$prepend . $key] = $value; + } + } + + return $results; + } + + /** + * Opposite of flatten, convert flat dot notation array to multi dimensional array. + * + * If any of the parent has a scalar value, all children get ignored: + * + * admin.pages=true + * admin.pages.read=true + * + * becomes + * + * admin: + * pages: true + * + * @param array $array + * @param string $separator + * @return array + */ + public static function arrayUnflattenDotNotation($array, $separator = '.') + { + $newArray = []; + foreach ($array as $key => $value) { + $dots = explode($separator, $key); + if (count($dots) > 1) { + $last = &$newArray[$dots[0]]; + foreach ($dots as $k => $dot) { + if ($k === 0) { + continue; + } + + // Cannot use a scalar value as an array + if (null !== $last && !is_array($last)) { + continue 2; + } + + $last = &$last[$dot]; + } + + // Cannot use a scalar value as an array + if (null !== $last && !is_array($last)) { + continue; + } + + $last = $value; + } else { + $newArray[$key] = $value; + } + } + + return $newArray; + } + + /** + * Checks if the passed path contains the language code prefix + * + * @param string $string The path + * + * @return bool|string Either false or the language + * + */ + public static function pathPrefixedByLangCode($string) + { + $languages_enabled = Grav::instance()['config']->get('system.languages.supported', []); + $parts = explode('/', trim($string, '/')); + + if (count($parts) > 0 && in_array($parts[0], $languages_enabled)) { + return $parts[0]; + } + return false; + } + + /** + * Get the timestamp of a date + * + * @param string $date a String expressed in the system.pages.dateformat.default format, with fallback to a + * strtotime argument + * @param string|null $format a date format to use if possible + * @return int the timestamp + */ + public static function date2timestamp($date, $format = null) + { + $config = Grav::instance()['config']; + $dateformat = $format ?: $config->get('system.pages.dateformat.default'); + + // try to use DateTime and default format + if ($dateformat) { + $datetime = DateTime::createFromFormat($dateformat, $date); + } else { + try { + $datetime = new DateTime($date); + } catch (Exception $e) { + $datetime = false; + } + } + + // fallback to strtotime() if DateTime approach failed + if ($datetime !== false) { + return $datetime->getTimestamp(); + } + + return strtotime($date); + } + + /** + * @param array $array + * @param string $path + * @param null $default + * @return mixed + * + * @deprecated 1.5 Use ->getDotNotation() method instead. + */ + public static function resolve(array $array, $path, $default = null) + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.5, use ->getDotNotation() method instead', E_USER_DEPRECATED); + + return static::getDotNotation($array, $path, $default); + } + + /** + * Checks if a value is positive (true) + * + * @param string $value + * @return bool + */ + public static function isPositive($value) + { + return in_array($value, [true, 1, '1', 'yes', 'on', 'true'], true); + } + + /** + * Checks if a value is negative (false) + * + * @param string $value + * @return bool + */ + public static function isNegative($value) + { + return in_array($value, [false, 0, '0', 'no', 'off', 'false'], true); + } + + /** + * Generates a nonce string to be hashed. Called by self::getNonce() + * We removed the IP portion in this version because it causes too many inconsistencies + * with reverse proxy setups. + * + * @param string $action + * @param bool $previousTick if true, generates the token for the previous tick (the previous 12 hours) + * @return string the nonce string + */ + private static function generateNonceString($action, $previousTick = false) + { + $grav = Grav::instance(); + + $username = isset($grav['user']) ? $grav['user']->username : ''; + $token = session_id(); + $i = self::nonceTick(); + + if ($previousTick) { + $i--; + } + + return ($i . '|' . $action . '|' . $username . '|' . $token . '|' . $grav['config']->get('security.salt')); + } + + /** + * Get the time-dependent variable for nonce creation. + * + * Now a tick lasts a day. Once the day is passed, the nonce is not valid any more. Find a better way + * to ensure nonces issued near the end of the day do not expire in that small amount of time + * + * @return int the time part of the nonce. Changes once every 24 hours + */ + private static function nonceTick() + { + $secondsInHalfADay = 60 * 60 * 12; + + return (int)ceil(time() / $secondsInHalfADay); + } + + /** + * Creates a hashed nonce tied to the passed action. Tied to the current user and time. The nonce for a given + * action is the same for 12 hours. + * + * @param string $action the action the nonce is tied to (e.g. save-user-admin or move-page-homepage) + * @param bool $previousTick if true, generates the token for the previous tick (the previous 12 hours) + * @return string the nonce + */ + public static function getNonce($action, $previousTick = false) + { + // Don't regenerate this again if not needed + if (isset(static::$nonces[$action][$previousTick])) { + return static::$nonces[$action][$previousTick]; + } + $nonce = md5(self::generateNonceString($action, $previousTick)); + static::$nonces[$action][$previousTick] = $nonce; + + return static::$nonces[$action][$previousTick]; + } + + /** + * Verify the passed nonce for the give action + * + * @param string|string[] $nonce the nonce to verify + * @param string $action the action to verify the nonce to + * @return boolean verified or not + */ + public static function verifyNonce($nonce, $action) + { + //Safety check for multiple nonces + if (is_array($nonce)) { + $nonce = array_shift($nonce); + } + + //Nonce generated 0-12 hours ago + if ($nonce === self::getNonce($action)) { + return true; + } + + //Nonce generated 12-24 hours ago + return $nonce === self::getNonce($action, true); + } + + /** + * Simple helper method to get whether or not the admin plugin is active + * + * @return bool + */ + public static function isAdminPlugin() + { + return isset(Grav::instance()['admin']); + } + + /** + * Get a portion of an array (passed by reference) with dot-notation key + * + * @param array $array + * @param string|int|null $key + * @param null $default + * @return mixed + */ + public static function getDotNotation($array, $key, $default = null) + { + if (null === $key) { + return $array; + } + + if (isset($array[$key])) { + return $array[$key]; + } + + foreach (explode('.', $key) as $segment) { + if (!is_array($array) || !array_key_exists($segment, $array)) { + return $default; + } + + $array = $array[$segment]; + } + + return $array; + } + + /** + * Set portion of array (passed by reference) for a dot-notation key + * and set the value + * + * @param array $array + * @param string|int|null $key + * @param mixed $value + * @param bool $merge + * + * @return mixed + */ + public static function setDotNotation(&$array, $key, $value, $merge = false) + { + if (null === $key) { + return $array = $value; + } + + $keys = explode('.', $key); + + while (count($keys) > 1) { + $key = array_shift($keys); + + if (!isset($array[$key]) || !is_array($array[$key])) { + $array[$key] = array(); + } + + $array =& $array[$key]; + } + + $key = array_shift($keys); + + if (!$merge || !isset($array[$key])) { + $array[$key] = $value; + } else { + $array[$key] = array_merge($array[$key], $value); + } + + return $array; + } + + /** + * Utility method to determine if the current OS is Windows + * + * @return bool + */ + public static function isWindows() + { + return strncasecmp(PHP_OS, 'WIN', 3) === 0; + } + + /** + * Utility to determine if the server running PHP is Apache + * + * @return bool + */ + public static function isApache() + { + return isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false; + } + + /** + * Sort a multidimensional array by another array of ordered keys + * + * @param array $array + * @param array $orderArray + * @return array + */ + public static function sortArrayByArray(array $array, array $orderArray) + { + $ordered = []; + foreach ($orderArray as $key) { + if (array_key_exists($key, $array)) { + $ordered[$key] = $array[$key]; + unset($array[$key]); + } + } + return $ordered + $array; + } + + /** + * Sort an array by a key value in the array + * + * @param mixed $array + * @param string|int $array_key + * @param int $direction + * @param int $sort_flags + * @return array + */ + public static function sortArrayByKey($array, $array_key, $direction = SORT_DESC, $sort_flags = SORT_REGULAR) + { + $output = []; + + if (!is_array($array) || !$array) { + return $output; + } + + foreach ($array as $key => $row) { + $output[$key] = $row[$array_key]; + } + + array_multisort($output, $direction, $sort_flags, $array); + + return $array; + } + + /** + * Get relative page path based on a token. + * + * @param string $path + * @param PageInterface|null $page + * @return string + * @throws RuntimeException + */ + public static function getPagePathFromToken($path, PageInterface $page = null) + { + return static::getPathFromToken($path, $page); + } + + /** + * Get relative path based on a token. + * + * Path supports following syntaxes: + * + * 'self@', 'self@/path' + * 'page@:/route', 'page@:/route/filename.ext' + * 'theme@:', 'theme@:/path' + * + * @param string $path + * @param FlexObjectInterface|PageInterface|null $object + * @return string + * @throws RuntimeException + */ + public static function getPathFromToken($path, $object = null) + { + $matches = static::resolveTokenPath($path); + if (null === $matches) { + return $path; + } + + $grav = Grav::instance(); + + switch ($matches[0]) { + case 'self': + if (!$object instanceof MediaInterface) { + throw new RuntimeException(sprintf('Page not available for self@ reference: %s', $path)); + } + + if ($matches[2] === '') { + if ($object->exists()) { + $route = '/' . $matches[1]; + + if ($object instanceof PageInterface) { + return trim($object->relativePagePath() . $route, '/'); + } + + $folder = $object->getMediaFolder(); + if ($folder) { + return trim($folder . $route, '/'); + } + } else { + return ''; + } + } + + break; + case 'page': + if ($matches[1] === '') { + $route = '/' . $matches[2]; + + // Exclude filename from the page lookup. + if (static::pathinfo($route, PATHINFO_EXTENSION)) { + $basename = '/' . static::basename($route); + $route = \dirname($route); + } else { + $basename = ''; + } + + $key = trim($route === '/' ? $grav['config']->get('system.home.alias') : $route, '/'); + if ($object instanceof PageObject) { + $object = $object->getFlexDirectory()->getObject($key); + } elseif (static::isAdminPlugin()) { + /** @var Flex|null $flex */ + $flex = $grav['flex'] ?? null; + $object = $flex ? $flex->getObject($key, 'pages') : null; + } else { + /** @var Pages $pages */ + $pages = $grav['pages']; + $object = $pages->find($route); + } + + if ($object instanceof PageInterface) { + return trim($object->relativePagePath() . $basename, '/'); + } + } + + break; + case 'theme': + if ($matches[1] === '') { + $route = '/' . $matches[2]; + $theme = $grav['locator']->findResource('theme://', false); + if (false !== $theme) { + return trim($theme . $route, '/'); + } + } + + break; + } + + throw new RuntimeException(sprintf('Token path not found: %s', $path)); + } + + /** + * Returns [token, route, path] from '@token/route:/path'. Route and path are optional. If pattern does not match, return null. + * + * @param string $path + * @return string[]|null + */ + protected static function resolveTokenPath(string $path): ?array + { + if (strpos($path, '@') !== false) { + $regex = '/^(@\w+|\w+@|@\w+@)([^:]*)(.*)$/u'; + if (preg_match($regex, $path, $matches)) { + return [ + trim($matches[1], '@'), + trim($matches[2], '/'), + trim($matches[3], ':/') + ]; + } + } + + return null; + } + + /** + * @return int + */ + public static function getUploadLimit() + { + static $max_size = -1; + + if ($max_size < 0) { + $post_max_size = static::parseSize(ini_get('post_max_size')); + if ($post_max_size > 0) { + $max_size = $post_max_size; + } else { + $max_size = 0; + } + + $upload_max = static::parseSize(ini_get('upload_max_filesize')); + if ($upload_max > 0 && $upload_max < $max_size) { + $max_size = $upload_max; + } + } + + return $max_size; + } + + /** + * Convert bytes to the unit specified by the $to parameter. + * + * @param int $bytes The filesize in Bytes. + * @param string $to The unit type to convert to. Accepts K, M, or G for Kilobytes, Megabytes, or Gigabytes, respectively. + * @param int $decimal_places The number of decimal places to return. + * @return int Returns only the number of units, not the type letter. Returns 0 if the $to unit type is out of scope. + * + */ + public static function convertSize($bytes, $to, $decimal_places = 1) + { + $formulas = array( + 'K' => number_format($bytes / 1024, $decimal_places), + 'M' => number_format($bytes / 1048576, $decimal_places), + 'G' => number_format($bytes / 1073741824, $decimal_places) + ); + return $formulas[$to] ?? 0; + } + + /** + * Return a pretty size based on bytes + * + * @param int $bytes + * @param int $precision + * @return string + */ + public static function prettySize($bytes, $precision = 2) + { + $units = array('B', 'KB', 'MB', 'GB', 'TB'); + + $bytes = max($bytes, 0); + $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); + $pow = min($pow, count($units) - 1); + + // Uncomment one of the following alternatives + $bytes /= 1024 ** $pow; + // $bytes /= (1 << (10 * $pow)); + + return round($bytes, $precision) . ' ' . $units[$pow]; + } + + /** + * Parse a readable file size and return a value in bytes + * + * @param string|int|float $size + * @return int + */ + public static function parseSize($size) + { + $unit = preg_replace('/[^bkmgtpezy]/i', '', $size); + $size = (float)preg_replace('/[^0-9\.]/', '', $size); + + if ($unit) { + $size *= 1024 ** stripos('bkmgtpezy', $unit[0]); + } + + return (int)abs(round($size)); + } + + /** + * Multibyte-safe Parse URL function + * + * @param string $url + * @return array + * @throws InvalidArgumentException + */ + public static function multibyteParseUrl($url) + { + $enc_url = preg_replace_callback( + '%[^:/@?&=#]+%usD', + static function ($matches) { + return urlencode($matches[0]); + }, + $url + ); + + $parts = parse_url($enc_url); + + if ($parts === false) { + $parts = []; + } + + foreach ($parts as $name => $value) { + $parts[$name] = urldecode($value); + } + + return $parts; + } + + /** + * Process a string as markdown + * + * @param string $string + * @param bool $block Block or Line processing + * @param PageInterface|null $page + * @return string + * @throws Exception + */ + public static function processMarkdown($string, $block = true, $page = null) + { + $grav = Grav::instance(); + $page = $page ?? $grav['page'] ?? null; + $defaults = [ + 'markdown' => $grav['config']->get('system.pages.markdown', []), + 'images' => $grav['config']->get('system.images', []) + ]; + $extra = $defaults['markdown']['extra'] ?? false; + + $excerpts = new Excerpts($page, $defaults); + + // Initialize the preferred variant of Parsedown + if ($extra) { + $parsedown = new ParsedownExtra($excerpts); + } else { + $parsedown = new Parsedown($excerpts); + } + + if ($block) { + $string = $parsedown->text((string) $string); + } else { + $string = $parsedown->line((string) $string); + } + + return $string; + } + + public static function toAscii(String $string): String + { + return strtr(utf8_decode($string), + utf8_decode( + 'ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ'), + 'SOZsozYYuAAAAAAACEEEEIIIIDNOOOOOOUUUUYsaaaaaaaceeeeiiiionoooooouuuuyy'); + } + + /** + * Find the subnet of an ip with CIDR prefix size + * + * @param string $ip + * @param int $prefix + * @return string + */ + public static function getSubnet($ip, $prefix = 64) + { + if (!filter_var($ip, FILTER_VALIDATE_IP)) { + return $ip; + } + + // Packed representation of IP + $ip = (string)inet_pton($ip); + + // Maximum netmask length = same as packed address + $len = 8 * strlen($ip); + if ($prefix > $len) { + $prefix = $len; + } + + $mask = str_repeat('f', $prefix >> 2); + + switch ($prefix & 3) { + case 3: + $mask .= 'e'; + break; + case 2: + $mask .= 'c'; + break; + case 1: + $mask .= '8'; + break; + } + $mask = str_pad($mask, $len >> 2, '0'); + + // Packed representation of netmask + $mask = pack('H*', $mask); + // Bitwise - Take all bits that are both 1 to generate subnet + $subnet = inet_ntop($ip & $mask); + + return $subnet; + } + + /** + * Wrapper to ensure html, htm in the front of the supported page types + * + * @param array|null $defaults + * @return array + */ + public static function getSupportPageTypes(array $defaults = null) + { + $types = Grav::instance()['config']->get('system.pages.types', $defaults); + if (!is_array($types)) { + return []; + } + + // remove html/htm + $types = static::arrayRemoveValue($types, ['html', 'htm']); + + // put them back at the front + $types = array_merge(['html', 'htm'], $types); + + return $types; + } + + /** + * @param string|array|Closure $name + * @return bool + */ + public static function isDangerousFunction($name): bool + { + static $commandExecutionFunctions = [ + 'exec', + 'passthru', + 'system', + 'shell_exec', + 'popen', + 'proc_open', + 'pcntl_exec', + ]; + + static $codeExecutionFunctions = [ + 'assert', + 'preg_replace', + 'create_function', + 'include', + 'include_once', + 'require', + 'require_once' + ]; + + static $callbackFunctions = [ + 'ob_start' => 0, + 'array_diff_uassoc' => -1, + 'array_diff_ukey' => -1, + 'array_filter' => 1, + 'array_intersect_uassoc' => -1, + 'array_intersect_ukey' => -1, + 'array_map' => 0, + 'array_reduce' => 1, + 'array_udiff_assoc' => -1, + 'array_udiff_uassoc' => [-1, -2], + 'array_udiff' => -1, + 'array_uintersect_assoc' => -1, + 'array_uintersect_uassoc' => [-1, -2], + 'array_uintersect' => -1, + 'array_walk_recursive' => 1, + 'array_walk' => 1, + 'assert_options' => 1, + 'uasort' => 1, + 'uksort' => 1, + 'usort' => 1, + 'preg_replace_callback' => 1, + 'spl_autoload_register' => 0, + 'iterator_apply' => 1, + 'call_user_func' => 0, + 'call_user_func_array' => 0, + 'register_shutdown_function' => 0, + 'register_tick_function' => 0, + 'set_error_handler' => 0, + 'set_exception_handler' => 0, + 'session_set_save_handler' => [0, 1, 2, 3, 4, 5], + 'sqlite_create_aggregate' => [2, 3], + 'sqlite_create_function' => 2, + ]; + + static $informationDiscosureFunctions = [ + 'phpinfo', + 'posix_mkfifo', + 'posix_getlogin', + 'posix_ttyname', + 'getenv', + 'get_current_user', + 'proc_get_status', + 'get_cfg_var', + 'disk_free_space', + 'disk_total_space', + 'diskfreespace', + 'getcwd', + 'getlastmo', + 'getmygid', + 'getmyinode', + 'getmypid', + 'getmyuid' + ]; + + static $otherFunctions = [ + 'extract', + 'parse_str', + 'putenv', + 'ini_set', + 'mail', + 'header', + 'proc_nice', + 'proc_terminate', + 'proc_close', + 'pfsockopen', + 'fsockopen', + 'apache_child_terminate', + 'posix_kill', + 'posix_mkfifo', + 'posix_setpgid', + 'posix_setsid', + 'posix_setuid', + 'unserialize', + 'ini_alter', + 'simplexml_load_file', + 'simplexml_load_string', + 'forward_static_call', + 'forward_static_call_array', + ]; + + if (is_string($name)) { + $name = strtolower($name); + } + + if ($name instanceof \Closure) { + return false; + } + + if (is_array($name) || strpos($name, ":") !== false) { + return true; + } + + if (strpos($name, "\\") !== false) { + return true; + } + + if (in_array($name, $commandExecutionFunctions)) { + return true; + } + + if (in_array($name, $codeExecutionFunctions)) { + return true; + } + + if (isset($callbackFunctions[$name])) { + return true; + } + + if (in_array($name, $informationDiscosureFunctions)) { + return true; + } + + if (in_array($name, $otherFunctions)) { + return true; + } + + return static::isFilesystemFunction($name); + } + + /** + * @param string $name + * @return bool + */ + public static function isFilesystemFunction(string $name): bool + { + static $fileWriteFunctions = [ + 'fopen', + 'tmpfile', + 'bzopen', + 'gzopen', + // write to filesystem (partially in combination with reading) + 'chgrp', + 'chmod', + 'chown', + 'copy', + 'file_put_contents', + 'lchgrp', + 'lchown', + 'link', + 'mkdir', + 'move_uploaded_file', + 'rename', + 'rmdir', + 'symlink', + 'tempnam', + 'touch', + 'unlink', + 'imagepng', + 'imagewbmp', + 'image2wbmp', + 'imagejpeg', + 'imagexbm', + 'imagegif', + 'imagegd', + 'imagegd2', + 'iptcembed', + 'ftp_get', + 'ftp_nb_get', + ]; + + static $fileContentFunctions = [ + 'file_get_contents', + 'file', + 'filegroup', + 'fileinode', + 'fileowner', + 'fileperms', + 'glob', + 'is_executable', + 'is_uploaded_file', + 'parse_ini_file', + 'readfile', + 'readlink', + 'realpath', + 'gzfile', + 'readgzfile', + 'stat', + 'imagecreatefromgif', + 'imagecreatefromjpeg', + 'imagecreatefrompng', + 'imagecreatefromwbmp', + 'imagecreatefromxbm', + 'imagecreatefromxpm', + 'ftp_put', + 'ftp_nb_put', + 'hash_update_file', + 'highlight_file', + 'show_source', + 'php_strip_whitespace', + ]; + + static $filesystemFunctions = [ + // read from filesystem + 'file_exists', + 'fileatime', + 'filectime', + 'filemtime', + 'filesize', + 'filetype', + 'is_dir', + 'is_file', + 'is_link', + 'is_readable', + 'is_writable', + 'is_writeable', + 'linkinfo', + 'lstat', + //'pathinfo', + 'getimagesize', + 'exif_read_data', + 'read_exif_data', + 'exif_thumbnail', + 'exif_imagetype', + 'hash_file', + 'hash_hmac_file', + 'md5_file', + 'sha1_file', + 'get_meta_tags', + ]; + + if (in_array($name, $fileWriteFunctions)) { + return true; + } + + if (in_array($name, $fileContentFunctions)) { + return true; + } + + if (in_array($name, $filesystemFunctions)) { + return true; + } + + return false; + } +} diff --git a/system/src/Grav/Common/Yaml.php b/system/src/Grav/Common/Yaml.php new file mode 100644 index 0000000..a4b3d73 --- /dev/null +++ b/system/src/Grav/Common/Yaml.php @@ -0,0 +1,65 @@ +decode($data); + } + + /** + * @param array $data + * @param int|null $inline + * @param int|null $indent + * @return string + */ + public static function dump($data, $inline = null, $indent = null) + { + if (null === static::$yaml) { + static::init(); + } + + return static::$yaml->encode($data, $inline, $indent); + } + + /** + * @return void + */ + protected static function init() + { + $config = [ + 'inline' => 5, + 'indent' => 2, + 'native' => true, + 'compat' => true + ]; + + static::$yaml = new YamlFormatter($config); + } +} diff --git a/system/src/Grav/Console/Application/Application.php b/system/src/Grav/Console/Application/Application.php new file mode 100644 index 0000000..d2fa0cd --- /dev/null +++ b/system/src/Grav/Console/Application/Application.php @@ -0,0 +1,138 @@ +addListener(ConsoleEvents::COMMAND, [$this, 'prepareEnvironment']); + + $this->setDispatcher($dispatcher); + } + + /** + * @param InputInterface $input + * @return string|null + */ + public function getCommandName(InputInterface $input): ?string + { + if ($input->hasParameterOption('--env', true)) { + $this->environment = $input->getParameterOption('--env'); + } + if ($input->hasParameterOption('--lang', true)) { + $this->language = $input->getParameterOption('--lang'); + } + + $this->init(); + + return parent::getCommandName($input); + } + + /** + * @param ConsoleCommandEvent $event + * @return void + */ + public function prepareEnvironment(ConsoleCommandEvent $event): void + { + } + + /** + * @return void + */ + protected function init(): void + { + if ($this->initialized) { + return; + } + + $this->initialized = true; + + $grav = Grav::instance(); + $grav->setup($this->environment); + } + + /** + * Add global --env and --lang options. + * + * @return InputDefinition + */ + protected function getDefaultInputDefinition(): InputDefinition + { + $inputDefinition = parent::getDefaultInputDefinition(); + $inputDefinition->addOption( + new InputOption( + '--env', + '', + InputOption::VALUE_OPTIONAL, + 'Use environment configuration (defaults to localhost)' + ) + ); + $inputDefinition->addOption( + new InputOption( + '--lang', + '', + InputOption::VALUE_OPTIONAL, + 'Language to be used (defaults to en)' + ) + ); + + return $inputDefinition; + } + + /** + * @param InputInterface $input + * @param OutputInterface $output + * @return void + */ + protected function configureIO(InputInterface $input, OutputInterface $output) + { + $formatter = $output->getFormatter(); + $formatter->setStyle('normal', new OutputFormatterStyle('white')); + $formatter->setStyle('yellow', new OutputFormatterStyle('yellow', null, ['bold'])); + $formatter->setStyle('red', new OutputFormatterStyle('red', null, ['bold'])); + $formatter->setStyle('cyan', new OutputFormatterStyle('cyan', null, ['bold'])); + $formatter->setStyle('green', new OutputFormatterStyle('green', null, ['bold'])); + $formatter->setStyle('magenta', new OutputFormatterStyle('magenta', null, ['bold'])); + $formatter->setStyle('white', new OutputFormatterStyle('white', null, ['bold'])); + + parent::configureIO($input, $output); + } +} diff --git a/system/src/Grav/Console/Application/CommandLoader/PluginCommandLoader.php b/system/src/Grav/Console/Application/CommandLoader/PluginCommandLoader.php new file mode 100644 index 0000000..210250c --- /dev/null +++ b/system/src/Grav/Console/Application/CommandLoader/PluginCommandLoader.php @@ -0,0 +1,103 @@ +commands = []; + + try { + $path = "plugins://{$name}/cli"; + $pattern = '([A-Z]\w+Command\.php)'; + + $commands = is_dir($path) ? Folder::all($path, ['compare' => 'Filename', 'pattern' => '/' . $pattern . '$/usm', 'levels' => 1]) : []; + } catch (RuntimeException $e) { + throw new RuntimeException("Failed to load console commands for plugin {$name}"); + } + + $grav = Grav::instance(); + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + foreach ($commands as $command_path) { + $full_path = $locator->findResource("plugins://{$name}/cli/{$command_path}"); + require_once $full_path; + + $command_class = 'Grav\Plugin\Console\\' . preg_replace('/.php$/', '', $command_path); + if (class_exists($command_class)) { + $command = new $command_class(); + if ($command instanceof Command) { + $this->commands[$command->getName()] = $command; + + // If the command has an alias, add that as a possible command name. + $aliases = $this->commands[$command->getName()]->getAliases(); + if (isset($aliases)) { + foreach ($aliases as $alias) { + $this->commands[$alias] = $command; + } + } + } + } + } + } + + /** + * @param string $name + * @return Command + */ + public function get($name): Command + { + $command = $this->commands[$name] ?? null; + if (null === $command) { + throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $name)); + } + + return $command; + } + + /** + * @param string $name + * @return bool + */ + public function has($name): bool + { + return isset($this->commands[$name]); + } + + /** + * @return string[] + */ + public function getNames(): array + { + return array_keys($this->commands); + } +} diff --git a/system/src/Grav/Console/Application/GpmApplication.php b/system/src/Grav/Console/Application/GpmApplication.php new file mode 100644 index 0000000..cddf473 --- /dev/null +++ b/system/src/Grav/Console/Application/GpmApplication.php @@ -0,0 +1,42 @@ +addCommands([ + new IndexCommand(), + new VersionCommand(), + new InfoCommand(), + new InstallCommand(), + new UninstallCommand(), + new UpdateCommand(), + new SelfupgradeCommand(), + new DirectInstallCommand(), + ]); + } +} diff --git a/system/src/Grav/Console/Application/GravApplication.php b/system/src/Grav/Console/Application/GravApplication.php new file mode 100644 index 0000000..7b43b2b --- /dev/null +++ b/system/src/Grav/Console/Application/GravApplication.php @@ -0,0 +1,52 @@ +addCommands([ + new InstallCommand(), + new ComposerCommand(), + new SandboxCommand(), + new CleanCommand(), + new ClearCacheCommand(), + new BackupCommand(), + new NewProjectCommand(), + new SchedulerCommand(), + new SecurityCommand(), + new LogViewerCommand(), + new YamlLinterCommand(), + new ServerCommand(), + new PageSystemValidatorCommand(), + ]); + } +} diff --git a/system/src/Grav/Console/Application/PluginApplication.php b/system/src/Grav/Console/Application/PluginApplication.php new file mode 100644 index 0000000..e748018 --- /dev/null +++ b/system/src/Grav/Console/Application/PluginApplication.php @@ -0,0 +1,116 @@ +addCommands([ + new PluginListCommand(), + ]); + } + + /** + * @param string $pluginName + * @return void + */ + public function setPluginName(string $pluginName): void + { + $this->pluginName = $pluginName; + } + + /** + * @return string + */ + public function getPluginName(): string + { + return $this->pluginName; + } + + /** + * @param InputInterface|null $input + * @param OutputInterface|null $output + * @return int + * @throws Throwable + */ + public function run(InputInterface $input = null, OutputInterface $output = null): int + { + if (null === $input) { + $argv = $_SERVER['argv'] ?? []; + + $bin = array_shift($argv); + $this->pluginName = array_shift($argv); + $argv = array_merge([$bin], $argv); + + $input = new ArgvInput($argv); + } + + return parent::run($input, $output); + } + + /** + * @return void + */ + protected function init(): void + { + if ($this->initialized) { + return; + } + + parent::init(); + + if (null === $this->pluginName) { + $this->setDefaultCommand('plugins:list'); + + return; + } + + $grav = Grav::instance(); + $grav->initializeCli(); + + /** @var Plugins $plugins */ + $plugins = $grav['plugins']; + + $plugin = $this->pluginName ? $plugins::get($this->pluginName) : null; + if (null === $plugin) { + throw new NamespaceNotFoundException("Plugin \"{$this->pluginName}\" is not installed."); + } + if (!$plugin->enabled) { + throw new NamespaceNotFoundException("Plugin \"{$this->pluginName}\" is not enabled."); + } + + $this->setCommandLoader(new PluginCommandLoader($this->pluginName)); + } +} diff --git a/system/src/Grav/Console/Cli/BackupCommand.php b/system/src/Grav/Console/Cli/BackupCommand.php new file mode 100644 index 0000000..d95e7cf --- /dev/null +++ b/system/src/Grav/Console/Cli/BackupCommand.php @@ -0,0 +1,138 @@ +setName('backup') + ->addArgument( + 'id', + InputArgument::OPTIONAL, + 'The ID of the backup profile to perform without prompting' + ) + ->setDescription('Creates a backup of the Grav instance') + ->setHelp('The backup creates a zipped backup.'); + + $this->source = getcwd(); + } + + /** + * @return int + */ + protected function serve(): int + { + $this->initializeGrav(); + + $input = $this->getInput(); + $io = $this->getIO(); + + $io->title('Grav Backup'); + + if (!class_exists(ZipArchive::class)) { + $io->error('php-zip extension needs to be enabled!'); + return 1; + } + + ProgressBar::setFormatDefinition('zip', 'Archiving %current% files [%bar%] %percent:3s%% %elapsed:6s% %message%'); + + $this->progress = new ProgressBar($this->output, 100); + $this->progress->setFormat('zip'); + + + /** @var Backups $backups */ + $backups = Grav::instance()['backups']; + $backups_list = $backups::getBackupProfiles(); + $backups_names = $backups->getBackupNames(); + + $id = null; + + $inline_id = $input->getArgument('id'); + if (null !== $inline_id && is_numeric($inline_id)) { + $id = $inline_id; + } + + if (null === $id) { + if (count($backups_list) > 1) { + $question = new ChoiceQuestion( + 'Choose a backup?', + $backups_names, + 0 + ); + $question->setErrorMessage('Option %s is invalid.'); + $backup_name = $io->askQuestion($question); + $id = array_search($backup_name, $backups_names, true); + + $io->newLine(); + $io->note('Selected backup: ' . $backup_name); + } else { + $id = 0; + } + } + + $backup = $backups::backup($id, function($args) { $this->outputProgress($args); }); + + $io->newline(2); + $io->success('Backup Successfully Created: ' . $backup); + + return 0; + } + + /** + * @param array $args + * @return void + */ + public function outputProgress(array $args): void + { + switch ($args['type']) { + case 'count': + $steps = $args['steps']; + $freq = (int)($steps > 100 ? round($steps / 100) : $steps); + $this->progress->setMaxSteps($steps); + $this->progress->setRedrawFrequency($freq); + $this->progress->setMessage('Adding files...'); + break; + case 'message': + $this->progress->setMessage($args['message']); + $this->progress->display(); + break; + case 'progress': + if (isset($args['complete']) && $args['complete']) { + $this->progress->finish(); + } else { + $this->progress->advance(); + } + break; + } + } +} diff --git a/system/src/Grav/Console/Cli/CleanCommand.php b/system/src/Grav/Console/Cli/CleanCommand.php new file mode 100644 index 0000000..34fc522 --- /dev/null +++ b/system/src/Grav/Console/Cli/CleanCommand.php @@ -0,0 +1,411 @@ +setName('clean') + ->setDescription('Handles cleaning chores for Grav distribution') + ->setHelp('The clean clean extraneous folders and data'); + } + + /** + * @param InputInterface $input + * @param OutputInterface $output + * @return int + */ + protected function execute(InputInterface $input, OutputInterface $output): int + { + $this->setupConsole($input, $output); + + return $this->cleanPaths() ? 0 : 1; + } + + /** + * @return bool + */ + private function cleanPaths(): bool + { + $success = true; + + $this->io->writeln(''); + $this->io->writeln('DELETING'); + $anything = false; + foreach ($this->paths_to_remove as $path) { + $path = GRAV_ROOT . DS . $path; + try { + if (is_dir($path) && Folder::delete($path)) { + $anything = true; + $this->io->writeln('dir: ' . $path); + } elseif (is_file($path) && @unlink($path)) { + $anything = true; + $this->io->writeln('file: ' . $path); + } + } catch (\Exception $e) { + $success = false; + $this->io->error(sprintf('Failed to delete %s: %s', $path, $e->getMessage())); + } + } + if (!$anything) { + $this->io->writeln(''); + $this->io->writeln('Nothing to clean...'); + } + + return $success; + } + + /** + * Set colors style definition for the formatter. + * + * @param InputInterface $input + * @param OutputInterface $output + * @return void + */ + public function setupConsole(InputInterface $input, OutputInterface $output): void + { + $this->input = $input; + $this->io = new SymfonyStyle($input, $output); + + $this->io->getFormatter()->setStyle('normal', new OutputFormatterStyle('white')); + $this->io->getFormatter()->setStyle('yellow', new OutputFormatterStyle('yellow', null, ['bold'])); + $this->io->getFormatter()->setStyle('red', new OutputFormatterStyle('red', null, ['bold'])); + $this->io->getFormatter()->setStyle('cyan', new OutputFormatterStyle('cyan', null, ['bold'])); + $this->io->getFormatter()->setStyle('green', new OutputFormatterStyle('green', null, ['bold'])); + $this->io->getFormatter()->setStyle('magenta', new OutputFormatterStyle('magenta', null, ['bold'])); + $this->io->getFormatter()->setStyle('white', new OutputFormatterStyle('white', null, ['bold'])); + } +} diff --git a/system/src/Grav/Console/Cli/ClearCacheCommand.php b/system/src/Grav/Console/Cli/ClearCacheCommand.php new file mode 100644 index 0000000..14795ef --- /dev/null +++ b/system/src/Grav/Console/Cli/ClearCacheCommand.php @@ -0,0 +1,104 @@ +setName('cache') + ->setAliases(['clearcache', 'cache-clear']) + ->setDescription('Clears Grav cache') + ->addOption('invalidate', null, InputOption::VALUE_NONE, 'Invalidate cache, but do not remove any files') + ->addOption('purge', null, InputOption::VALUE_NONE, 'If set purge old caches') + ->addOption('all', null, InputOption::VALUE_NONE, 'If set will remove all including compiled, twig, doctrine caches') + ->addOption('assets-only', null, InputOption::VALUE_NONE, 'If set will remove only assets/*') + ->addOption('images-only', null, InputOption::VALUE_NONE, 'If set will remove only images/*') + ->addOption('cache-only', null, InputOption::VALUE_NONE, 'If set will remove only cache/*') + ->addOption('tmp-only', null, InputOption::VALUE_NONE, 'If set will remove only tmp/*') + + ->setHelp('The cache command allows you to interact with Grav cache'); + } + + /** + * @return int + */ + protected function serve(): int + { + // Old versions of Grav called this command after grav upgrade. + // We need make this command to work with older GravCommand instance: + if (!method_exists($this, 'initializePlugins')) { + Cache::clearCache('all'); + + return 0; + } + + $this->initializePlugins(); + $this->cleanPaths(); + + return 0; + } + + /** + * loops over the array of paths and deletes the files/folders + * + * @return void + */ + private function cleanPaths(): void + { + $input = $this->getInput(); + $io = $this->getIO(); + + $io->newLine(); + + if ($input->getOption('purge')) { + $io->writeln('Purging old cache'); + $io->newLine(); + + $msg = Cache::purgeJob(); + $io->writeln($msg); + } else { + $io->writeln('Clearing cache'); + $io->newLine(); + + if ($input->getOption('all')) { + $remove = 'all'; + } elseif ($input->getOption('assets-only')) { + $remove = 'assets-only'; + } elseif ($input->getOption('images-only')) { + $remove = 'images-only'; + } elseif ($input->getOption('cache-only')) { + $remove = 'cache-only'; + } elseif ($input->getOption('tmp-only')) { + $remove = 'tmp-only'; + } elseif ($input->getOption('invalidate')) { + $remove = 'invalidate'; + } else { + $remove = 'standard'; + } + + foreach (Cache::clearCache($remove) as $result) { + $io->writeln($result); + } + } + } +} diff --git a/system/src/Grav/Console/Cli/ComposerCommand.php b/system/src/Grav/Console/Cli/ComposerCommand.php new file mode 100644 index 0000000..05c784a --- /dev/null +++ b/system/src/Grav/Console/Cli/ComposerCommand.php @@ -0,0 +1,64 @@ +setName('composer') + ->addOption( + 'install', + 'i', + InputOption::VALUE_NONE, + 'install the dependencies' + ) + ->addOption( + 'update', + 'u', + InputOption::VALUE_NONE, + 'update the dependencies' + ) + ->setDescription('Updates the composer vendor dependencies needed by Grav.') + ->setHelp('The composer command updates the composer vendor dependencies needed by Grav'); + } + + /** + * @return int + */ + protected function serve(): int + { + $input = $this->getInput(); + $io = $this->getIO(); + + $action = $input->getOption('install') ? 'install' : ($input->getOption('update') ? 'update' : 'install'); + + if ($input->getOption('install')) { + $action = 'install'; + } + + // Updates composer first + $io->writeln("\nInstalling vendor dependencies"); + $io->writeln($this->composerUpdate(GRAV_ROOT, $action)); + + return 0; + } +} diff --git a/system/src/Grav/Console/Cli/InstallCommand.php b/system/src/Grav/Console/Cli/InstallCommand.php new file mode 100644 index 0000000..51fd16c --- /dev/null +++ b/system/src/Grav/Console/Cli/InstallCommand.php @@ -0,0 +1,302 @@ +setName('install') + ->addOption( + 'symlink', + 's', + InputOption::VALUE_NONE, + 'Symlink the required bits' + ) + ->addOption( + 'plugin', + 'p', + InputOption::VALUE_REQUIRED, + 'Install plugin (symlink)' + ) + ->addOption( + 'theme', + 't', + InputOption::VALUE_REQUIRED, + 'Install theme (symlink)' + ) + ->addArgument( + 'destination', + InputArgument::OPTIONAL, + 'Where to install the required bits (default to current project)' + ) + ->setDescription('Installs the dependencies needed by Grav. Optionally can create symbolic links') + ->setHelp('The install command installs the dependencies needed by Grav. Optionally can create symbolic links'); + } + + /** + * @return int + */ + protected function serve(): int + { + $input = $this->getInput(); + $io = $this->getIO(); + + $dependencies_file = '.dependencies'; + $this->destination = $input->getArgument('destination') ?: GRAV_WEBROOT; + + // fix trailing slash + $this->destination = rtrim($this->destination, DS) . DS; + $this->user_path = $this->destination . GRAV_USER_PATH . DS; + if ($local_config_file = $this->loadLocalConfig()) { + $io->writeln('Read local config from ' . $local_config_file . ''); + } + + // Look for dependencies file in ROOT and USER dir + if (file_exists($this->user_path . $dependencies_file)) { + $file = YamlFile::instance($this->user_path . $dependencies_file); + } elseif (file_exists($this->destination . $dependencies_file)) { + $file = YamlFile::instance($this->destination . $dependencies_file); + } else { + $io->writeln('ERROR Missing .dependencies file in user/ folder'); + if ($input->getArgument('destination')) { + $io->writeln('HINT Are you trying to install a plugin or a theme? Make sure you use bin/gpm install , not bin/grav install. This command is only used to install Grav skeletons.'); + } else { + $io->writeln('HINT Are you trying to install Grav? Grav is already installed. You need to run this command only if you download a skeleton from GitHub directly.'); + } + + return 1; + } + + $this->config = $file->content(); + $file->free(); + + // If no config, fail. + if (!$this->config) { + $io->writeln('ERROR invalid YAML in ' . $dependencies_file); + + return 1; + } + + $plugin = $input->getOption('plugin'); + $theme = $input->getOption('theme'); + $name = $plugin ?? $theme; + $symlink = $name || $input->getOption('symlink'); + + if (!$symlink) { + // Updates composer first + $io->writeln("\nInstalling vendor dependencies"); + $io->writeln($this->composerUpdate(GRAV_ROOT, 'install')); + + $error = $this->gitclone(); + } else { + $type = $name ? ($plugin ? 'plugin' : 'theme') : null; + + $error = $this->symlink($name, $type); + } + + return $error; + } + + /** + * Clones from Git + * + * @return int + */ + private function gitclone(): int + { + $io = $this->getIO(); + + $io->newLine(); + $io->writeln('Cloning Bits'); + $io->writeln('============'); + $io->newLine(); + + $error = 0; + $this->destination = rtrim($this->destination, DS); + foreach ($this->config['git'] as $repo => $data) { + $path = $this->destination . DS . $data['path']; + if (!file_exists($path)) { + exec('cd ' . escapeshellarg($this->destination) . ' && git clone -b ' . $data['branch'] . ' --depth 1 ' . $data['url'] . ' ' . $data['path'], $output, $return); + + if (!$return) { + $io->writeln('SUCCESS cloned ' . $data['url'] . ' -> ' . $path . ''); + } else { + $io->writeln('ERROR cloning ' . $data['url']); + $error = 1; + } + + $io->newLine(); + } else { + $io->writeln('' . $path . ' already exists, skipping...'); + $io->newLine(); + } + } + + return $error; + } + + /** + * Symlinks + * + * @param string|null $name + * @param string|null $type + * @return int + */ + private function symlink(string $name = null, string $type = null): int + { + $io = $this->getIO(); + + $io->newLine(); + $io->writeln('Symlinking Bits'); + $io->writeln('==============='); + $io->newLine(); + + if (!$this->local_config) { + $io->writeln('No local configuration available, aborting...'); + $io->newLine(); + + return 1; + } + + $error = 0; + $this->destination = rtrim($this->destination, DS); + + if ($name) { + $src = "grav-{$type}-{$name}"; + $links = [ + $name => [ + 'scm' => 'github', // TODO: make configurable + 'src' => $src, + 'path' => "user/{$type}s/{$name}" + ] + ]; + } else { + $links = $this->config['links']; + } + + foreach ($links as $name => $data) { + $scm = $data['scm'] ?? null; + $src = $data['src'] ?? null; + $path = $data['path'] ?? null; + if (!isset($scm, $src, $path)) { + $io->writeln("Dependency '$name' has broken configuration, skipping..."); + $io->newLine(); + $error = 1; + + continue; + } + + $locations = (array) $this->local_config["{$scm}_repos"]; + $to = $this->destination . DS . $path; + + $from = null; + foreach ($locations as $location) { + $test = rtrim($location, '\\/') . DS . $src; + if (file_exists($test)) { + $from = $test; + continue; + } + } + + if (is_link($to) && !realpath($to)) { + $io->writeln('Removed broken symlink '. $path .''); + unlink($to); + } + if (null === $from) { + $io->writeln('source for ' . $src . ' does not exists, skipping...'); + $io->newLine(); + $error = 1; + } elseif (!file_exists($to)) { + $error = $this->addSymlinks($from, $to, ['name' => $name, 'src' => $src, 'path' => $path]); + $io->newLine(); + } else { + $io->writeln('destination: ' . $path . ' already exists, skipping...'); + $io->newLine(); + } + } + + return $error; + } + + private function addSymlinks(string $from, string $to, array $options): int + { + $io = $this->getIO(); + + $hebe = $this->readHebe($from); + if (null === $hebe) { + symlink($from, $to); + + $io->writeln('SUCCESS symlinked ' . $options['src'] . ' -> ' . $options['path'] . ''); + } else { + $to = GRAV_ROOT; + $name = $options['name']; + $io->writeln("Processing {$name}"); + foreach ($hebe as $section => $symlinks) { + foreach ($symlinks as $symlink) { + $src = trim($symlink['source'], '/'); + $dst = trim($symlink['destination'], '/'); + $s = "{$from}/{$src}"; + $d = "{$to}/{$dst}"; + + if (is_link($d) && !realpath($d)) { + unlink($d); + $io->writeln(' Removed broken symlink '. $dst .''); + } + if (!file_exists($d)) { + symlink($s, $d); + $io->writeln(' symlinked ' . $src . ' -> ' . $dst . ''); + } + } + } + $io->writeln('SUCCESS'); + } + + return 0; + } + + private function readHebe(string $folder): ?array + { + $filename = "{$folder}/hebe.json"; + if (!is_file($filename)) { + return null; + } + + $formatter = new JsonFormatter(); + $file = new JsonFile($filename, $formatter); + $hebe = $file->load(); + $paths = $hebe['platforms']['grav']['nodes'] ?? null; + + return is_array($paths) ? $paths : null; + } +} diff --git a/system/src/Grav/Console/Cli/LogViewerCommand.php b/system/src/Grav/Console/Cli/LogViewerCommand.php new file mode 100644 index 0000000..fe19a40 --- /dev/null +++ b/system/src/Grav/Console/Cli/LogViewerCommand.php @@ -0,0 +1,96 @@ +setName('logviewer') + ->addOption( + 'file', + 'f', + InputOption::VALUE_OPTIONAL, + 'custom log file location (default = grav.log)' + ) + ->addOption( + 'lines', + 'l', + InputOption::VALUE_OPTIONAL, + 'number of lines (default = 10)' + ) + ->setDescription('Display the last few entries of Grav log') + ->setHelp('Display the last few entries of Grav log'); + } + + /** + * @return int + */ + protected function serve(): int + { + $input = $this->getInput(); + $io = $this->getIO(); + + $file = $input->getOption('file') ?? 'grav.log'; + $lines = $input->getOption('lines') ?? 20; + $verbose = $input->getOption('verbose') ?? false; + + $io->title('Log Viewer'); + + $io->writeln(sprintf('viewing last %s entries in %s', $lines, $file)); + $io->newLine(); + + $viewer = new LogViewer(); + + $grav = Grav::instance(); + + $logfile = $grav['locator']->findResource('log://' . $file); + if (!$logfile) { + $io->error('cannot find the log file: logs/' . $file); + + return 1; + } + + $rows = $viewer->objectTail($logfile, $lines, true); + foreach ($rows as $log) { + $date = $log['date']; + $level_color = LogViewer::levelColor($log['level']); + + if ($date instanceof DateTime) { + $output = "{$log['date']->format('Y-m-d h:i:s')} [<{$level_color}>{$log['level']}]"; + if ($log['trace'] && $verbose) { + $output .= " {$log['message']}\n"; + foreach ((array) $log['trace'] as $index => $tracerow) { + $output .= "{$index}{$tracerow}\n"; + } + } else { + $output .= " {$log['message']}"; + } + $io->writeln($output); + } + } + + return 0; + } +} diff --git a/system/src/Grav/Console/Cli/NewProjectCommand.php b/system/src/Grav/Console/Cli/NewProjectCommand.php new file mode 100644 index 0000000..9450139 --- /dev/null +++ b/system/src/Grav/Console/Cli/NewProjectCommand.php @@ -0,0 +1,75 @@ +setName('new-project') + ->setAliases(['newproject']) + ->addArgument( + 'destination', + InputArgument::REQUIRED, + 'The destination directory of your new Grav project' + ) + ->addOption( + 'symlink', + 's', + InputOption::VALUE_NONE, + 'Symlink the required bits' + ) + ->setDescription('Creates a new Grav project with all the dependencies installed') + ->setHelp("The new-project command is a combination of the `setup` and `install` commands.\nCreates a new Grav instance and performs the installation of all the required dependencies."); + } + + /** + * @return int + */ + protected function serve(): int + { + $io = $this->getIO(); + + $sandboxCommand = $this->getApplication()->find('sandbox'); + $installCommand = $this->getApplication()->find('install'); + + $sandboxArguments = new ArrayInput([ + 'command' => 'sandbox', + 'destination' => $this->input->getArgument('destination'), + '-s' => $this->input->getOption('symlink') + ]); + + $installArguments = new ArrayInput([ + 'command' => 'install', + 'destination' => $this->input->getArgument('destination'), + '-s' => $this->input->getOption('symlink') + ]); + + $error = $sandboxCommand->run($sandboxArguments, $io); + if ($error === 0) { + $error = $installCommand->run($installArguments, $io); + } + + return $error; + } +} diff --git a/system/src/Grav/Console/Cli/PageSystemValidatorCommand.php b/system/src/Grav/Console/Cli/PageSystemValidatorCommand.php new file mode 100644 index 0000000..1e8302d --- /dev/null +++ b/system/src/Grav/Console/Cli/PageSystemValidatorCommand.php @@ -0,0 +1,299 @@ + [[]], + 'summary' => [[], [200], [200, true]], + 'content' => [[]], + 'getRawContent' => [[]], + 'rawMarkdown' => [[]], + 'value' => [['content'], ['route'], ['order'], ['ordering'], ['folder'], ['slug'], ['name'], /*['frontmatter'],*/ ['header.menu'], ['header.slug']], + 'title' => [[]], + 'menu' => [[]], + 'visible' => [[]], + 'published' => [[]], + 'publishDate' => [[]], + 'unpublishDate' => [[]], + 'process' => [[]], + 'slug' => [[]], + 'order' => [[]], + //'id' => [[]], + 'modified' => [[]], + 'lastModified' => [[]], + 'folder' => [[]], + 'date' => [[]], + 'dateformat' => [[]], + 'taxonomy' => [[]], + 'shouldProcess' => [['twig'], ['markdown']], + 'isPage' => [[]], + 'isDir' => [[]], + 'exists' => [[]], + + // Forms + 'forms' => [[]], + + // Routing + 'urlExtension' => [[]], + 'routable' => [[]], + 'link' => [[], [false], [true]], + 'permalink' => [[]], + 'canonical' => [[], [false], [true]], + 'url' => [[], [true], [true, true], [true, true, false], [false, false, true, false]], + 'route' => [[]], + 'rawRoute' => [[]], + 'routeAliases' => [[]], + 'routeCanonical' => [[]], + 'redirect' => [[]], + 'relativePagePath' => [[]], + 'path' => [[]], + //'folder' => [[]], + 'parent' => [[]], + 'topParent' => [[]], + 'currentPosition' => [[]], + 'active' => [[]], + 'activeChild' => [[]], + 'home' => [[]], + 'root' => [[]], + + // Translations + 'translatedLanguages' => [[], [false], [true]], + 'untranslatedLanguages' => [[], [false], [true]], + 'language' => [[]], + + // Legacy + 'raw' => [[]], + 'frontmatter' => [[]], + 'httpResponseCode' => [[]], + 'httpHeaders' => [[]], + 'blueprintName' => [[]], + 'name' => [[]], + 'childType' => [[]], + 'template' => [[]], + 'templateFormat' => [[]], + 'extension' => [[]], + 'expires' => [[]], + 'cacheControl' => [[]], + 'ssl' => [[]], + 'metadata' => [[]], + 'eTag' => [[]], + 'filePath' => [[]], + 'filePathClean' => [[]], + 'orderDir' => [[]], + 'orderBy' => [[]], + 'orderManual' => [[]], + 'maxCount' => [[]], + 'modular' => [[]], + 'modularTwig' => [[]], + //'children' => [[]], + 'isFirst' => [[]], + 'isLast' => [[]], + 'prevSibling' => [[]], + 'nextSibling' => [[]], + 'adjacentSibling' => [[]], + 'ancestor' => [[]], + //'inherited' => [[]], + //'inheritedField' => [[]], + 'find' => [['/']], + //'collection' => [[]], + //'evaluate' => [[]], + 'folderExists' => [[]], + //'getOriginal' => [[]], + //'getAction' => [[]], + ]; + + /** @var Grav */ + protected $grav; + + /** + * @return void + */ + protected function configure(): void + { + $this + ->setName('page-system-validator') + ->setDescription('Page validator can be used to compare site before/after update and when migrating to Flex Pages.') + ->addOption('record', 'r', InputOption::VALUE_NONE, 'Record results') + ->addOption('check', 'c', InputOption::VALUE_NONE, 'Compare site against previously recorded results') + ->setHelp('The page-system-validator command can be used to test the pages before and after upgrade'); + } + + /** + * @return int + */ + protected function serve(): int + { + $input = $this->getInput(); + $io = $this->getIO(); + + $this->setLanguage('en'); + $this->initializePages(); + + $io->newLine(); + + $this->grav = $grav = Grav::instance(); + + $grav->fireEvent('onPageInitialized', new Event(['page' => $grav['page']])); + + /** @var Config $config */ + $config = $grav['config']; + + if ($input->getOption('record')) { + $io->writeln('Pages: ' . $config->get('system.pages.type', 'page')); + + $io->writeln('Record tests'); + $io->newLine(); + + $results = $this->record(); + $file = $this->getFile('pages-old'); + $file->save($results); + + $io->writeln('Recorded tests to ' . $file->filename()); + } elseif ($input->getOption('check')) { + $io->writeln('Pages: ' . $config->get('system.pages.type', 'page')); + + $io->writeln('Run tests'); + $io->newLine(); + + $new = $this->record(); + $file = $this->getFile('pages-new'); + $file->save($new); + $io->writeln('Recorded tests to ' . $file->filename()); + + $file = $this->getFile('pages-old'); + $old = $file->content(); + + $results = $this->check($old, $new); + $file = $this->getFile('diff'); + $file->save($results); + $io->writeln('Recorded results to ' . $file->filename()); + } else { + $io->writeln('page-system-validator [-r|--record] [-c|--check]'); + } + $io->newLine(); + + return 0; + } + + /** + * @return array + */ + private function record(): array + { + $io = $this->getIO(); + + /** @var Pages $pages */ + $pages = $this->grav['pages']; + $all = $pages->all(); + + $results = []; + $results[''] = $this->recordRow($pages->root()); + foreach ($all as $path => $page) { + if (null === $page) { + $io->writeln('Error on page ' . $path . ''); + continue; + } + + $results[$page->rawRoute()] = $this->recordRow($page); + } + + return json_decode(json_encode($results), true); + } + + /** + * @param PageInterface $page + * @return array + */ + private function recordRow(PageInterface $page): array + { + $results = []; + + foreach ($this->tests as $method => $params) { + $params = $params ?: [[]]; + foreach ($params as $p) { + $result = $page->$method(...$p); + if (in_array($method, ['summary', 'content', 'getRawContent'], true)) { + $result = preg_replace('/name="(form-nonce|__unique_form_id__)" value="[^"]+"/', + 'name="\\1" value="DYNAMIC"', $result); + $result = preg_replace('`src=("|\'|")/images/./././././[^"]+\\1`', + 'src="\\1images/GENERATED\\1', $result); + $result = preg_replace('/\?\d{10}/', '?1234567890', $result); + } elseif ($method === 'httpHeaders' && isset($result['Expires'])) { + $result['Expires'] = 'Thu, 19 Sep 2019 13:10:24 GMT (REPLACED AS DYNAMIC)'; + } elseif ($result instanceof PageInterface) { + $result = $result->rawRoute(); + } elseif (is_object($result)) { + $result = json_decode(json_encode($result), true); + } + + $ps = []; + foreach ($p as $val) { + $ps[] = (string)var_export($val, true); + } + $pstr = implode(', ', $ps); + $call = "->{$method}({$pstr})"; + $results[$call] = $result; + } + } + + return $results; + } + + /** + * @param array $old + * @param array $new + * @return array + */ + private function check(array $old, array $new): array + { + $errors = []; + foreach ($old as $path => $page) { + if (!isset($new[$path])) { + $errors[$path] = 'PAGE REMOVED'; + continue; + } + foreach ($page as $method => $test) { + if (($new[$path][$method] ?? null) !== $test) { + $errors[$path][$method] = ['old' => $test, 'new' => $new[$path][$method]]; + } + } + } + + return $errors; + } + + /** + * @param string $name + * @return CompiledYamlFile + */ + private function getFile(string $name): CompiledYamlFile + { + return CompiledYamlFile::instance('cache://tests/' . $name . '.yaml'); + } +} diff --git a/system/src/Grav/Console/Cli/SandboxCommand.php b/system/src/Grav/Console/Cli/SandboxCommand.php new file mode 100644 index 0000000..4e2cadd --- /dev/null +++ b/system/src/Grav/Console/Cli/SandboxCommand.php @@ -0,0 +1,347 @@ + '/.gitignore', + '/.editorconfig' => '/.editorconfig', + '/CHANGELOG.md' => '/CHANGELOG.md', + '/LICENSE.txt' => '/LICENSE.txt', + '/README.md' => '/README.md', + '/CONTRIBUTING.md' => '/CONTRIBUTING.md', + '/index.php' => '/index.php', + '/composer.json' => '/composer.json', + '/bin' => '/bin', + '/system' => '/system', + '/vendor' => '/vendor', + '/webserver-configs' => '/webserver-configs', + ]; + + /** @var string */ + protected $source; + /** @var string */ + protected $destination; + + /** + * @return void + */ + protected function configure(): void + { + $this + ->setName('sandbox') + ->setDescription('Setup of a base Grav system in your webroot, good for development, playing around or starting fresh') + ->addArgument( + 'destination', + InputArgument::REQUIRED, + 'The destination directory to symlink into' + ) + ->addOption( + 'symlink', + 's', + InputOption::VALUE_NONE, + 'Symlink the base grav system' + ) + ->setHelp("The sandbox command help create a development environment that can optionally use symbolic links to link the core of grav to the git cloned repository.\nGood for development, playing around or starting fresh"); + + $source = getcwd(); + if ($source === false) { + throw new RuntimeException('Internal Error'); + } + $this->source = $source; + } + + /** + * @return int + */ + protected function serve(): int + { + $input = $this->getInput(); + + $this->destination = $input->getArgument('destination'); + + // Create Some core stuff if it doesn't exist + $error = $this->createDirectories(); + if ($error) { + return $error; + } + + // Copy files or create symlinks + $error = $input->getOption('symlink') ? $this->symlink() : $this->copy(); + if ($error) { + return $error; + } + + $error = $this->pages(); + if ($error) { + return $error; + } + + $error = $this->initFiles(); + if ($error) { + return $error; + } + + $error = $this->perms(); + if ($error) { + return $error; + } + + return 0; + } + + /** + * @return int + */ + private function createDirectories(): int + { + $io = $this->getIO(); + + $io->newLine(); + $io->writeln('Creating Directories'); + $dirs_created = false; + + if (!file_exists($this->destination)) { + Folder::create($this->destination); + } + + foreach ($this->directories as $dir) { + if (!file_exists($this->destination . $dir)) { + $dirs_created = true; + $io->writeln(' ' . $dir . ''); + Folder::create($this->destination . $dir); + } + } + + if (!$dirs_created) { + $io->writeln(' Directories already exist'); + } + + return 0; + } + + /** + * @return int + */ + private function copy(): int + { + $io = $this->getIO(); + + $io->newLine(); + $io->writeln('Copying Files'); + + + foreach ($this->mappings as $source => $target) { + if ((string)(int)$source === (string)$source) { + $source = $target; + } + + $from = $this->source . $source; + $to = $this->destination . $target; + + $io->writeln(' ' . $source . ' -> ' . $to); + @Folder::rcopy($from, $to); + } + + return 0; + } + + /** + * @return int + */ + private function symlink(): int + { + $io = $this->getIO(); + + $io->newLine(); + $io->writeln('Resetting Symbolic Links'); + + // Symlink also tests if using git. + if (is_dir($this->source . '/tests')) { + $this->mappings['/tests'] = '/tests'; + } + + foreach ($this->mappings as $source => $target) { + if ((string)(int)$source === (string)$source) { + $source = $target; + } + + $from = $this->source . $source; + $to = $this->destination . $target; + + $io->writeln(' ' . $source . ' -> ' . $to); + + if (is_dir($to)) { + @Folder::delete($to); + } else { + @unlink($to); + } + symlink($from, $to); + } + + return 0; + } + + /** + * @return int + */ + private function pages(): int + { + $io = $this->getIO(); + + $io->newLine(); + $io->writeln('Pages Initializing'); + + // get pages files and initialize if no pages exist + $pages_dir = $this->destination . '/user/pages'; + $pages_files = array_diff(scandir($pages_dir), ['..', '.']); + + if (count($pages_files) === 0) { + $destination = $this->source . '/user/pages'; + Folder::rcopy($destination, $pages_dir); + $io->writeln(' ' . $destination . ' -> Created'); + } + + return 0; + } + + /** + * @return int + */ + private function initFiles(): int + { + if (!$this->check()) { + return 1; + } + + $io = $this->getIO(); + $io->newLine(); + $io->writeln('File Initializing'); + $files_init = false; + + // Copy files if they do not exist + foreach ($this->files as $source => $target) { + if ((string)(int)$source === (string)$source) { + $source = $target; + } + + $from = $this->source . $source; + $to = $this->destination . $target; + + if (!file_exists($to)) { + $files_init = true; + copy($from, $to); + $io->writeln(' ' . $target . ' -> Created'); + } + } + + if (!$files_init) { + $io->writeln(' Files already exist'); + } + + return 0; + } + + /** + * @return int + */ + private function perms(): int + { + $io = $this->getIO(); + $io->newLine(); + $io->writeln('Permissions Initializing'); + + $dir_perms = 0755; + + $binaries = glob($this->destination . DS . 'bin' . DS . '*'); + + foreach ($binaries as $bin) { + chmod($bin, $dir_perms); + $io->writeln(' bin/' . Utils::basename($bin) . ' permissions reset to ' . decoct($dir_perms)); + } + + $io->newLine(); + + return 0; + } + + /** + * @return bool + */ + private function check(): bool + { + $success = true; + $io = $this->getIO(); + + if (!file_exists($this->destination)) { + $io->writeln(' file: ' . $this->destination . ' does not exist!'); + $success = false; + } + + foreach ($this->directories as $dir) { + if (!file_exists($this->destination . $dir)) { + $io->writeln(' directory: ' . $dir . ' does not exist!'); + $success = false; + } + } + + foreach ($this->mappings as $target => $link) { + if (!file_exists($this->destination . $target)) { + $io->writeln(' mappings: ' . $target . ' does not exist!'); + $success = false; + } + } + + if (!$success) { + $io->newLine(); + $io->writeln('install should be run with --symlink|--s to symlink first'); + } + + return $success; + } +} diff --git a/system/src/Grav/Console/Cli/SchedulerCommand.php b/system/src/Grav/Console/Cli/SchedulerCommand.php new file mode 100644 index 0000000..fb30244 --- /dev/null +++ b/system/src/Grav/Console/Cli/SchedulerCommand.php @@ -0,0 +1,223 @@ +setName('scheduler') + ->addOption( + 'install', + 'i', + InputOption::VALUE_NONE, + 'Show Install Command' + ) + ->addOption( + 'jobs', + 'j', + InputOption::VALUE_NONE, + 'Show Jobs Summary' + ) + ->addOption( + 'details', + 'd', + InputOption::VALUE_NONE, + 'Show Job Details' + ) + ->addOption( + 'run', + 'r', + InputOption::VALUE_OPTIONAL, + 'Force run all jobs or a specific job if you specify a specific Job ID', + false + ) + ->setDescription('Run the Grav Scheduler. Best when integrated with system cron') + ->setHelp("Running without any options will force the Scheduler to run through it's jobs and process them"); + } + + /** + * @return int + */ + protected function serve(): int + { + $this->initializePlugins(); + + $grav = Grav::instance(); + $grav['backups']->init(); + $this->initializePages(); + $this->initializeThemes(); + + /** @var Scheduler $scheduler */ + $scheduler = $grav['scheduler']; + $grav->fireEvent('onSchedulerInitialized', new Event(['scheduler' => $scheduler])); + + $input = $this->getInput(); + $io = $this->getIO(); + $error = 0; + + $run = $input->getOption('run'); + + if ($input->getOption('jobs')) { + // Show jobs list + + $jobs = $scheduler->getAllJobs(); + $job_states = (array)$scheduler->getJobStates()->content(); + $rows = []; + + $table = new Table($io); + $table->setStyle('box'); + $headers = ['Job ID', 'Command', 'Run At', 'Status', 'Last Run', 'State']; + + $io->title('Scheduler Jobs Listing'); + + foreach ($jobs as $job) { + $job_status = ucfirst($job_states[$job->getId()]['state'] ?? 'ready'); + $last_run = $job_states[$job->getId()]['last-run'] ?? 0; + $status = $job_status === 'Failure' ? "{$job_status}" : "{$job_status}"; + $state = $job->getEnabled() ? 'Enabled' : 'Disabled'; + $row = [ + $job->getId(), + "{$job->getCommand()}", + "{$job->getAt()}", + $status, + '' . ($last_run === 0 ? 'Never' : date('Y-m-d H:i', $last_run)) . '', + $state, + + ]; + $rows[] = $row; + } + + if (!empty($rows)) { + $table->setHeaders($headers); + $table->setRows($rows); + $table->render(); + } else { + $io->text('no jobs found...'); + } + + $io->newLine(); + $io->note('For error details run "bin/grav scheduler -d"'); + $io->newLine(); + } elseif ($input->getOption('details')) { + $jobs = $scheduler->getAllJobs(); + $job_states = (array)$scheduler->getJobStates()->content(); + + $io->title('Job Details'); + + $table = new Table($io); + $table->setStyle('box'); + $table->setHeaders(['Job ID', 'Last Run', 'Next Run', 'Errors']); + $rows = []; + + foreach ($jobs as $job) { + $job_state = $job_states[$job->getId()]; + $error = isset($job_state['error']) ? trim($job_state['error']) : false; + + /** @var CronExpression $expression */ + $expression = $job->getCronExpression(); + $next_run = $expression->getNextRunDate(); + + $row = []; + $row[] = $job->getId(); + if (!is_null($job_state['last-run'])) { + $row[] = '' . date('Y-m-d H:i', $job_state['last-run']) . ''; + } else { + $row[] = 'Never'; + } + $row[] = '' . $next_run->format('Y-m-d H:i') . ''; + + if ($error) { + $row[] = "{$error}"; + } else { + $row[] = 'None'; + } + $rows[] = $row; + } + + $table->setRows($rows); + $table->render(); + } elseif ($run !== false && $run !== null) { + $io->title('Force Run Job: ' . $run); + + $job = $scheduler->getJob($run); + + if ($job) { + $job->inForeground()->run(); + + if ($job->isSuccessful()) { + $io->success('Job ran successfully...'); + } else { + $error = 1; + $io->error('Job failed to run successfully...'); + } + + $output = $job->getOutput(); + + if ($output) { + $io->write($output); + } + } else { + $error = 1; + $io->error('Could not find a job with id: ' . $run); + } + } elseif ($input->getOption('install')) { + $io->title('Install Scheduler'); + + $verb = 'install'; + + if ($scheduler->isCrontabSetup()) { + $io->success('All Ready! You have already set up Grav\'s Scheduler in your crontab. You can validate this by running "crontab -l" to list your current crontab entries.'); + $verb = 'reinstall'; + } else { + $user = $scheduler->whoami(); + $error = 1; + $io->error('Can\'t find a crontab for ' . $user . '. You need to set up Grav\'s Scheduler in your crontab'); + } + if (!Utils::isWindows()) { + $io->note("To $verb, run the following command from your terminal:"); + $io->newLine(); + $io->text(trim($scheduler->getCronCommand())); + } else { + $io->note("To $verb, create a scheduled task in Windows."); + $io->text('Learn more at https://learn.getgrav.org/advanced/scheduler'); + } + } else { + // Run scheduler + $force = $run === null; + $scheduler->run(null, $force); + + if ($input->getOption('verbose')) { + $io->title('Running Scheduled Jobs'); + $io->text($scheduler->getVerboseOutput()); + } + } + + return $error; + } +} diff --git a/system/src/Grav/Console/Cli/SecurityCommand.php b/system/src/Grav/Console/Cli/SecurityCommand.php new file mode 100644 index 0000000..d75a4a6 --- /dev/null +++ b/system/src/Grav/Console/Cli/SecurityCommand.php @@ -0,0 +1,102 @@ +setName('security') + ->setDescription('Capable of running various Security checks') + ->setHelp('The security runs various security checks on your Grav site'); + } + + /** + * @return int + */ + protected function serve(): int + { + $this->initializePages(); + + $io = $this->getIO(); + + /** @var Grav $grav */ + $grav = Grav::instance(); + $this->progress = new ProgressBar($this->output, count($grav['pages']->routes()) - 1); + $this->progress->setFormat('Scanning %current% pages [%bar%] %percent:3s%% %elapsed:6s%'); + $this->progress->setBarWidth(100); + + $io->title('Grav Security Check'); + $io->newline(2); + + $output = Security::detectXssFromPages($grav['pages'], false, [$this, 'outputProgress']); + + $error = 0; + if (!empty($output)) { + $counter = 1; + foreach ($output as $route => $results) { + $results_parts = array_map(static function ($value, $key) { + return $key.': \''.$value . '\''; + }, array_values($results), array_keys($results)); + + $io->writeln($counter++ .' - ' . $route . '' . implode(', ', $results_parts) . ''); + } + + $error = 1; + $io->error('Security Scan complete: ' . count($output) . ' potential XSS issues found...'); + } else { + $io->success('Security Scan complete: No issues found...'); + } + + $io->newline(1); + + return $error; + } + + /** + * @param array $args + * @return void + */ + public function outputProgress(array $args): void + { + switch ($args['type']) { + case 'count': + $steps = $args['steps']; + $freq = (int)($steps > 100 ? round($steps / 100) : $steps); + $this->progress->setMaxSteps($steps); + $this->progress->setRedrawFrequency($freq); + break; + case 'progress': + if (isset($args['complete']) && $args['complete']) { + $this->progress->finish(); + } else { + $this->progress->advance(); + } + break; + } + } +} diff --git a/system/src/Grav/Console/Cli/ServerCommand.php b/system/src/Grav/Console/Cli/ServerCommand.php new file mode 100644 index 0000000..7b50082 --- /dev/null +++ b/system/src/Grav/Console/Cli/ServerCommand.php @@ -0,0 +1,154 @@ +setName('server') + ->addOption('port', 'p', InputOption::VALUE_OPTIONAL, 'Preferred HTTP port rather than auto-find (default is 8000-9000') + ->addOption('symfony', null, InputOption::VALUE_NONE, 'Force using Symfony server') + ->addOption('php', null, InputOption::VALUE_NONE, 'Force using built-in PHP server') + ->setDescription("Runs built-in web-server, Symfony first, then tries PHP's") + ->setHelp("Runs built-in web-server, Symfony first, then tries PHP's"); + } + + /** + * @return int + */ + protected function serve(): int + { + $input = $this->getInput(); + $io = $this->getIO(); + + $io->title('Grav Web Server'); + + // Ensure CLI colors are on + ini_set('cli_server.color', 'on'); + + // Options + $force_symfony = $input->getOption('symfony'); + $force_php = $input->getOption('php'); + + // Find PHP + $executableFinder = new PhpExecutableFinder(); + $php = $executableFinder->find(false); + + $this->ip = '127.0.0.1'; + $this->port = (int)($input->getOption('port') ?? 8000); + + // Get an open port + while (!$this->portAvailable($this->ip, $this->port)) { + $this->port++; + } + + // Setup the commands + $symfony_cmd = ['symfony', 'server:start', '--ansi', '--port=' . $this->port]; + $php_cmd = [$php, '-S', $this->ip.':'.$this->port, 'system/router.php']; + + $commands = [ + self::SYMFONY_SERVER => $symfony_cmd, + self::PHP_SERVER => $php_cmd + ]; + + if ($force_symfony) { + unset($commands[self::PHP_SERVER]); + } elseif ($force_php) { + unset($commands[self::SYMFONY_SERVER]); + } + + $error = 0; + foreach ($commands as $name => $command) { + $process = $this->runProcess($name, $command); + if (!$process) { + $io->note('Starting ' . $name . '...'); + } + + // Should only get here if there's an error running + if (!$process->isRunning() && (($name === self::SYMFONY_SERVER && $force_symfony) || ($name === self::PHP_SERVER))) { + $error = 1; + $io->error('Could not start ' . $name); + } + } + + return $error; + } + + /** + * @param string $name + * @param array $cmd + * @return Process + */ + protected function runProcess(string $name, array $cmd): Process + { + $io = $this->getIO(); + + $process = new Process($cmd); + $process->setTimeout(0); + $process->start(); + + if ($name === self::SYMFONY_SERVER && Utils::contains($process->getErrorOutput(), 'symfony: not found')) { + $io->error('The symfony binary could not be found, please install the CLI tools: https://symfony.com/download'); + $io->warning('Falling back to PHP web server...'); + } + + if ($name === self::PHP_SERVER) { + $io->success('Built-in PHP web server listening on http://' . $this->ip . ':' . $this->port . ' (PHP v' . PHP_VERSION . ')'); + } + + $process->wait(function ($type, $buffer) { + $this->getIO()->write($buffer); + }); + + return $process; + } + + /** + * Simple function test the port + * + * @param string $ip + * @param int $port + * @return bool + */ + protected function portAvailable(string $ip, int $port): bool + { + $fp = @fsockopen($ip, $port, $errno, $errstr, 0.1); + if (!$fp) { + return true; + } + + fclose($fp); + + return false; + } +} diff --git a/system/src/Grav/Console/Cli/YamlLinterCommand.php b/system/src/Grav/Console/Cli/YamlLinterCommand.php new file mode 100644 index 0000000..76a5a75 --- /dev/null +++ b/system/src/Grav/Console/Cli/YamlLinterCommand.php @@ -0,0 +1,124 @@ +setName('yamllinter') + ->addOption( + 'all', + 'a', + InputOption::VALUE_NONE, + 'Go through the whole Grav installation' + ) + ->addOption( + 'folder', + 'f', + InputOption::VALUE_OPTIONAL, + 'Go through specific folder' + ) + ->setDescription('Checks various files for YAML errors') + ->setHelp('Checks various files for YAML errors'); + } + + /** + * @return int + */ + protected function serve(): int + { + $input = $this->getInput(); + $io = $this->getIO(); + + $io->title('Yaml Linter'); + + $error = 0; + if ($input->getOption('all')) { + $io->section('All'); + $errors = YamlLinter::lint(''); + + if (empty($errors)) { + $io->success('No YAML Linting issues found'); + } else { + $error = 1; + $this->displayErrors($errors, $io); + } + } elseif ($folder = $input->getOption('folder')) { + $io->section($folder); + $errors = YamlLinter::lint($folder); + + if (empty($errors)) { + $io->success('No YAML Linting issues found'); + } else { + $error = 1; + $this->displayErrors($errors, $io); + } + } else { + $io->section('User Configuration'); + $errors = YamlLinter::lintConfig(); + + if (empty($errors)) { + $io->success('No YAML Linting issues with configuration'); + } else { + $error = 1; + $this->displayErrors($errors, $io); + } + + $io->section('Pages Frontmatter'); + $errors = YamlLinter::lintPages(); + + if (empty($errors)) { + $io->success('No YAML Linting issues with pages'); + } else { + $error = 1; + $this->displayErrors($errors, $io); + } + + $io->section('Page Blueprints'); + $errors = YamlLinter::lintBlueprints(); + + if (empty($errors)) { + $io->success('No YAML Linting issues with blueprints'); + } else { + $error = 1; + $this->displayErrors($errors, $io); + } + } + + return $error; + } + + /** + * @param array $errors + * @param SymfonyStyle $io + * @return void + */ + protected function displayErrors(array $errors, SymfonyStyle $io): void + { + $io->error('YAML Linting issues found...'); + foreach ($errors as $path => $error) { + $io->writeln("{$path} - {$error}"); + } + } +} diff --git a/system/src/Grav/Console/ConsoleCommand.php b/system/src/Grav/Console/ConsoleCommand.php new file mode 100644 index 0000000..d7cff9f --- /dev/null +++ b/system/src/Grav/Console/ConsoleCommand.php @@ -0,0 +1,46 @@ +setupConsole($input, $output); + + return $this->serve(); + } + + /** + * Override with your implementation. + * + * @return int + */ + protected function serve() + { + // Return error. + return 1; + } +} diff --git a/system/src/Grav/Console/ConsoleTrait.php b/system/src/Grav/Console/ConsoleTrait.php new file mode 100644 index 0000000..2f8848f --- /dev/null +++ b/system/src/Grav/Console/ConsoleTrait.php @@ -0,0 +1,338 @@ +argv = $_SERVER['argv'][0]; + $this->input = $input; + $this->output = new SymfonyStyle($input, $output); + + $this->setupGrav(); + } + + public function getInput(): InputInterface + { + return $this->input; + } + + /** + * @return SymfonyStyle + */ + public function getIO(): SymfonyStyle + { + return $this->output; + } + + /** + * Adds an option. + * + * @param string $name The option name + * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts + * @param int|null $mode The option mode: One of the InputOption::VALUE_* constants + * @param string $description A description text + * @param string|string[]|int|bool|null $default The default value (must be null for InputOption::VALUE_NONE) + * @return $this + * @throws InvalidArgumentException If option mode is invalid or incompatible + */ + public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null) + { + if ($name !== 'env' && $name !== 'lang') { + parent::addOption($name, $shortcut, $mode, $description, $default); + } + + return $this; + } + + /** + * @return void + */ + final protected function setupGrav(): void + { + try { + $language = $this->input->getOption('lang'); + if ($language) { + // Set used language. + $this->setLanguage($language); + } + } catch (InvalidArgumentException $e) {} + + // Initialize cache with CLI compatibility + $grav = Grav::instance(); + $grav['config']->set('system.cache.cli_compatibility', true); + } + + /** + * Initialize Grav. + * + * - Load configuration + * - Initialize logger + * - Disable debugger + * - Set timezone, locale + * - Load plugins (call PluginsLoadedEvent) + * - Set Pages and Users type to be used in the site + * + * Safe to be called multiple times. + * + * @return $this + */ + final protected function initializeGrav() + { + InitializeProcessor::initializeCli(Grav::instance()); + + return $this; + } + + /** + * Set language to be used in CLI. + * + * @param string|null $code + * @return $this + */ + final protected function setLanguage(string $code = null) + { + $this->initializeGrav(); + + $grav = Grav::instance(); + /** @var Language $language */ + $language = $grav['language']; + if ($language->enabled()) { + if ($code && $language->validate($code)) { + $language->setActive($code); + } else { + $language->setActive($language->getDefault()); + } + } + + return $this; + } + + /** + * Properly initialize plugins. + * + * - call $this->initializeGrav() + * - call onPluginsInitialized event + * + * Safe to be called multiple times. + * + * @return $this + */ + final protected function initializePlugins() + { + if (!$this->plugins_initialized) { + $this->plugins_initialized = true; + + $this->initializeGrav(); + + // Initialize plugins. + $grav = Grav::instance(); + $grav['plugins']->init(); + $grav->fireEvent('onPluginsInitialized'); + } + + return $this; + } + + /** + * Properly initialize themes. + * + * - call $this->initializePlugins() + * - initialize theme (call onThemeInitialized event) + * + * Safe to be called multiple times. + * + * @return $this + */ + final protected function initializeThemes() + { + if (!$this->themes_initialized) { + $this->themes_initialized = true; + + $this->initializePlugins(); + + // Initialize themes. + $grav = Grav::instance(); + $grav['themes']->init(); + } + + return $this; + } + + /** + * Properly initialize pages. + * + * - call $this->initializeThemes() + * - initialize assets (call onAssetsInitialized event) + * - initialize twig (calls the twig events) + * - initialize pages (calls onPagesInitialized event) + * + * Safe to be called multiple times. + * + * @return $this + */ + final protected function initializePages() + { + if (!$this->pages_initialized) { + $this->pages_initialized = true; + + $this->initializeThemes(); + + $grav = Grav::instance(); + + // Initialize assets. + $grav['assets']->init(); + $grav->fireEvent('onAssetsInitialized'); + + // Initialize twig. + $grav['twig']->init(); + + // Initialize pages. + $pages = $grav['pages']; + $pages->init(); + $grav->fireEvent('onPagesInitialized', new Event(['pages' => $pages])); + } + + return $this; + } + + /** + * @param string $path + * @return void + */ + public function isGravInstance($path) + { + $io = $this->getIO(); + + if (!file_exists($path)) { + $io->writeln(''); + $io->writeln("ERROR: Destination doesn't exist:"); + $io->writeln(" $path"); + $io->writeln(''); + exit; + } + + if (!is_dir($path)) { + $io->writeln(''); + $io->writeln("ERROR: Destination chosen to install is not a directory:"); + $io->writeln(" $path"); + $io->writeln(''); + exit; + } + + if (!file_exists($path . DS . 'index.php') || !file_exists($path . DS . '.dependencies') || !file_exists($path . DS . 'system' . DS . 'config' . DS . 'system.yaml')) { + $io->writeln(''); + $io->writeln('ERROR: Destination chosen to install does not appear to be a Grav instance:'); + $io->writeln(" $path"); + $io->writeln(''); + exit; + } + } + + /** + * @param string $path + * @param string $action + * @return string|false + */ + public function composerUpdate($path, $action = 'install') + { + $composer = Composer::getComposerExecutor(); + + return system($composer . ' --working-dir=' . escapeshellarg($path) . ' --no-interaction --no-dev --prefer-dist -o '. $action); + } + + /** + * @param array $all + * @return int + * @throws Exception + */ + public function clearCache($all = []) + { + if ($all) { + $all = ['--all' => true]; + } + + $command = new ClearCacheCommand(); + $input = new ArrayInput($all); + return $command->run($input, $this->output); + } + + /** + * @return void + */ + public function invalidateCache() + { + Cache::invalidateCache(); + } + + /** + * Load the local config file + * + * @return string|false The local config file name. false if local config does not exist + */ + public function loadLocalConfig() + { + $home_folder = getenv('HOME') ?: getenv('HOMEDRIVE') . getenv('HOMEPATH'); + $local_config_file = $home_folder . '/.grav/config'; + + if (file_exists($local_config_file)) { + $file = YamlFile::instance($local_config_file); + $this->local_config = $file->content(); + $file->free(); + + return $local_config_file; + } + + return false; + } +} diff --git a/system/src/Grav/Console/Gpm/DirectInstallCommand.php b/system/src/Grav/Console/Gpm/DirectInstallCommand.php new file mode 100644 index 0000000..272b5f5 --- /dev/null +++ b/system/src/Grav/Console/Gpm/DirectInstallCommand.php @@ -0,0 +1,321 @@ +setName('direct-install') + ->setAliases(['directinstall']) + ->addArgument( + 'package-file', + InputArgument::REQUIRED, + 'Installable package local or remote . Can install specific version' + ) + ->addOption( + 'all-yes', + 'y', + InputOption::VALUE_NONE, + 'Assumes yes (or best approach) instead of prompting' + ) + ->addOption( + 'destination', + 'd', + InputOption::VALUE_OPTIONAL, + 'The destination where the package should be installed at. By default this would be where the grav instance has been launched from', + GRAV_ROOT + ) + ->setDescription('Installs Grav, plugin, or theme directly from a file or a URL') + ->setHelp('The direct-install command installs Grav, plugin, or theme directly from a file or a URL'); + } + + /** + * @return int + */ + protected function serve(): int + { + $input = $this->getInput(); + $io = $this->getIO(); + + if (!class_exists(ZipArchive::class)) { + $io->title('Direct Install'); + $io->error('php-zip extension needs to be enabled!'); + + return 1; + } + + // Making sure the destination is usable + $this->destination = realpath($input->getOption('destination')); + + if (!Installer::isGravInstance($this->destination) || + !Installer::isValidDestination($this->destination, [Installer::EXISTS, Installer::IS_LINK]) + ) { + $io->writeln('ERROR: ' . Installer::lastErrorMsg()); + + return 1; + } + + $this->all_yes = $input->getOption('all-yes'); + + $package_file = $input->getArgument('package-file'); + + $question = new ConfirmationQuestion("Are you sure you want to direct-install {$package_file} [y|N] ", false); + + $answer = $this->all_yes ? true : $io->askQuestion($question); + + if (!$answer) { + $io->writeln('exiting...'); + $io->newLine(); + + return 1; + } + + $tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true); + $tmp_zip = $tmp_dir . uniqid('/Grav-', false); + + $io->newLine(); + $io->writeln("Preparing to install {$package_file}"); + + $zip = null; + if (Response::isRemote($package_file)) { + $io->write(' |- Downloading package... 0%'); + try { + $zip = GPM::downloadPackage($package_file, $tmp_zip); + } catch (RuntimeException $e) { + $io->newLine(); + $io->writeln(" `- ERROR: {$e->getMessage()}"); + $io->newLine(); + + return 1; + } + + if ($zip) { + $io->write("\x0D"); + $io->write(' |- Downloading package... 100%'); + $io->newLine(); + } + } elseif (is_file($package_file)) { + $io->write(' |- Copying package... 0%'); + $zip = GPM::copyPackage($package_file, $tmp_zip); + if ($zip) { + $io->write("\x0D"); + $io->write(' |- Copying package... 100%'); + $io->newLine(); + } + } + + if ($zip && file_exists($zip)) { + $tmp_source = $tmp_dir . uniqid('/Grav-', false); + + $io->write(' |- Extracting package... '); + $extracted = Installer::unZip($zip, $tmp_source); + + if (!$extracted) { + $io->write("\x0D"); + $io->writeln(' |- Extracting package... failed'); + Folder::delete($tmp_source); + Folder::delete($tmp_zip); + + return 1; + } + + $io->write("\x0D"); + $io->writeln(' |- Extracting package... ok'); + + + $type = GPM::getPackageType($extracted); + + if (!$type) { + $io->writeln(" '- ERROR: Not a valid Grav package"); + $io->newLine(); + Folder::delete($tmp_source); + Folder::delete($tmp_zip); + + return 1; + } + + $blueprint = GPM::getBlueprints($extracted); + if ($blueprint) { + if (isset($blueprint['dependencies'])) { + $dependencies = []; + foreach ($blueprint['dependencies'] as $dependency) { + if (is_array($dependency)) { + if (isset($dependency['name'])) { + $dependencies[] = $dependency['name']; + } + if (isset($dependency['github'])) { + $dependencies[] = $dependency['github']; + } + } else { + $dependencies[] = $dependency; + } + } + $io->writeln(' |- Dependencies found... [' . implode(',', $dependencies) . ']'); + + $question = new ConfirmationQuestion(" | '- Dependencies will not be satisfied. Continue ? [y|N] ", false); + $answer = $this->all_yes ? true : $io->askQuestion($question); + + if (!$answer) { + $io->writeln('exiting...'); + $io->newLine(); + Folder::delete($tmp_source); + Folder::delete($tmp_zip); + + return 1; + } + } + } + + if ($type === 'grav') { + $io->write(' |- Checking destination... '); + Installer::isValidDestination(GRAV_ROOT . '/system'); + if (Installer::IS_LINK === Installer::lastErrorCode()) { + $io->write("\x0D"); + $io->writeln(' |- Checking destination... symbolic link'); + $io->writeln(" '- ERROR: symlinks found... " . GRAV_ROOT . ''); + $io->newLine(); + Folder::delete($tmp_source); + Folder::delete($tmp_zip); + + return 1; + } + + $io->write("\x0D"); + $io->writeln(' |- Checking destination... ok'); + + $io->write(' |- Installing package... '); + + $this->upgradeGrav($zip, $extracted); + } else { + $name = GPM::getPackageName($extracted); + + if (!$name) { + $io->writeln('ERROR: Name could not be determined. Please specify with --name|-n'); + $io->newLine(); + Folder::delete($tmp_source); + Folder::delete($tmp_zip); + + return 1; + } + + $install_path = GPM::getInstallPath($type, $name); + $is_update = file_exists($install_path); + + $io->write(' |- Checking destination... '); + + Installer::isValidDestination(GRAV_ROOT . DS . $install_path); + if (Installer::lastErrorCode() === Installer::IS_LINK) { + $io->write("\x0D"); + $io->writeln(' |- Checking destination... symbolic link'); + $io->writeln(" '- ERROR: symlink found... " . GRAV_ROOT . DS . $install_path . ''); + $io->newLine(); + Folder::delete($tmp_source); + Folder::delete($tmp_zip); + + return 1; + } + + $io->write("\x0D"); + $io->writeln(' |- Checking destination... ok'); + + $io->write(' |- Installing package... '); + + Installer::install( + $zip, + $this->destination, + $options = [ + 'install_path' => $install_path, + 'theme' => (($type === 'theme')), + 'is_update' => $is_update + ], + $extracted + ); + + // clear cache after successful upgrade + $this->clearCache(); + } + + Folder::delete($tmp_source); + + $io->write("\x0D"); + + if (Installer::lastErrorCode()) { + $io->writeln(" '- " . Installer::lastErrorMsg() . ''); + $io->newLine(); + } else { + $io->writeln(' |- Installing package... ok'); + $io->writeln(" '- Success! "); + $io->newLine(); + } + } else { + $io->writeln(" '- ERROR: ZIP package could not be found"); + Folder::delete($tmp_zip); + + return 1; + } + + Folder::delete($tmp_zip); + + return 0; + } + + /** + * @param string $zip + * @param string $folder + * @return void + */ + private function upgradeGrav(string $zip, string $folder): void + { + if (!is_dir($folder)) { + Installer::setError('Invalid source folder'); + } + + try { + $script = $folder . '/system/install.php'; + /** Install $installer */ + if ((file_exists($script) && $install = include $script) && is_callable($install)) { + $install($zip); + } else { + throw new RuntimeException('Uploaded archive file is not a valid Grav update package'); + } + } catch (Exception $e) { + Installer::setError($e->getMessage()); + } + } +} diff --git a/system/src/Grav/Console/Gpm/IndexCommand.php b/system/src/Grav/Console/Gpm/IndexCommand.php new file mode 100644 index 0000000..d9b5448 --- /dev/null +++ b/system/src/Grav/Console/Gpm/IndexCommand.php @@ -0,0 +1,335 @@ +setName('index') + ->addOption( + 'force', + 'f', + InputOption::VALUE_NONE, + 'Force re-fetching the data from remote' + ) + ->addOption( + 'filter', + 'F', + InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, + 'Allows to limit the results based on one or multiple filters input. This can be either portion of a name/slug or a regex' + ) + ->addOption( + 'themes-only', + 'T', + InputOption::VALUE_NONE, + 'Filters the results to only Themes' + ) + ->addOption( + 'plugins-only', + 'P', + InputOption::VALUE_NONE, + 'Filters the results to only Plugins' + ) + ->addOption( + 'updates-only', + 'U', + InputOption::VALUE_NONE, + 'Filters the results to Updatable Themes and Plugins only' + ) + ->addOption( + 'installed-only', + 'I', + InputOption::VALUE_NONE, + 'Filters the results to only the Themes and Plugins you have installed' + ) + ->addOption( + 'sort', + 's', + InputOption::VALUE_REQUIRED, + 'Allows to sort (ASC) the results. SORT can be either "name", "slug", "author", "date"', + 'date' + ) + ->addOption( + 'desc', + 'D', + InputOption::VALUE_NONE, + 'Reverses the order of the output.' + ) + ->addOption( + 'enabled', + 'e', + InputOption::VALUE_NONE, + 'Filters the results to only enabled Themes and Plugins.' + ) + ->addOption( + 'disabled', + 'd', + InputOption::VALUE_NONE, + 'Filters the results to only disabled Themes and Plugins.' + ) + ->setDescription('Lists the plugins and themes available for installation') + ->setHelp('The index command lists the plugins and themes available for installation') + ; + } + + /** + * @return int + */ + protected function serve(): int + { + $input = $this->getInput(); + $this->options = $input->getOptions(); + $this->gpm = new GPM($this->options['force']); + $this->displayGPMRelease(); + $this->data = $this->gpm->getRepository(); + + $data = $this->filter($this->data); + + $io = $this->getIO(); + + if (count($data) === 0) { + $io->writeln('No data was found in the GPM repository stored locally.'); + $io->writeln('Please try clearing cache and running the bin/gpm index -f command again'); + $io->writeln('If this doesn\'t work try tweaking your GPM system settings.'); + $io->newLine(); + $io->writeln('For more help go to:'); + $io->writeln(' -> https://learn.getgrav.org/troubleshooting/common-problems#cannot-connect-to-the-gpm'); + + return 1; + } + + foreach ($data as $type => $packages) { + $io->writeln('' . strtoupper($type) . ' [ ' . count($packages) . ' ]'); + + $packages = $this->sort($packages); + + if (!empty($packages)) { + $io->section('Packages table'); + $table = new Table($io); + $table->setHeaders(['Count', 'Name', 'Slug', 'Version', 'Installed', 'Enabled']); + + $index = 0; + foreach ($packages as $slug => $package) { + $row = [ + 'Count' => $index++ + 1, + 'Name' => '' . Utils::truncate($package->name, 20, false, ' ', '...') . ' ', + 'Slug' => $slug, + 'Version'=> $this->version($package), + 'Installed' => $this->installed($package), + 'Enabled' => $this->enabled($package), + ]; + + $table->addRow($row); + } + + $table->render(); + } + + $io->newLine(); + } + + $io->writeln('You can either get more informations about a package by typing:'); + $io->writeln(" {$this->argv} info "); + $io->newLine(); + $io->writeln('Or you can install a package by typing:'); + $io->writeln(" {$this->argv} install "); + $io->newLine(); + + return 0; + } + + /** + * @param Package $package + * @return string + */ + private function version(Package $package): string + { + $list = $this->gpm->{'getUpdatable' . ucfirst($package->package_type)}(); + $package = $list[$package->slug] ?? $package; + $type = ucfirst(preg_replace('/s$/', '', $package->package_type)); + $updatable = $this->gpm->{'is' . $type . 'Updatable'}($package->slug); + $installed = $this->gpm->{'is' . $type . 'Installed'}($package->slug); + $local = $this->gpm->{'getInstalled' . $type}($package->slug); + + if (!$installed || !$updatable) { + $version = $installed ? $local->version : $package->version; + return "v{$version}"; + } + + return "v{$package->version} -> v{$package->available}"; + } + + /** + * @param Package $package + * @return string + */ + private function installed(Package $package): string + { + $type = ucfirst(preg_replace('/s$/', '', $package->package_type)); + $method = 'is' . $type . 'Installed'; + $installed = $this->gpm->{$method}($package->slug); + + return !$installed ? 'not installed' : 'installed'; + } + + /** + * @param Package $package + * @return string + */ + private function enabled(Package $package): string + { + $type = ucfirst(preg_replace('/s$/', '', $package->package_type)); + $method = 'is' . $type . 'Installed'; + $installed = $this->gpm->{$method}($package->slug); + + $result = ''; + if ($installed) { + $method = 'is' . $type . 'Enabled'; + $enabled = $this->gpm->{$method}($package->slug); + if ($enabled === true) { + $result = 'enabled'; + } elseif ($enabled === false) { + $result = 'disabled'; + } + } + + return $result; + } + + /** + * @param Packages $data + * @return Packages + */ + public function filter(Packages $data): Packages + { + // filtering and sorting + if ($this->options['plugins-only']) { + unset($data['themes']); + } + if ($this->options['themes-only']) { + unset($data['plugins']); + } + + $filter = [ + $this->options['desc'], + $this->options['disabled'], + $this->options['enabled'], + $this->options['filter'], + $this->options['installed-only'], + $this->options['updates-only'], + ]; + + if (count(array_filter($filter))) { + foreach ($data as $type => $packages) { + foreach ($packages as $slug => $package) { + $filter = true; + + // Filtering by string + if ($this->options['filter']) { + $filter = preg_grep('/(' . implode('|', $this->options['filter']) . ')/i', [$slug, $package->name]); + } + + // Filtering updatables only + if ($filter && ($this->options['installed-only'] || $this->options['enabled'] || $this->options['disabled'])) { + $method = ucfirst(preg_replace('/s$/', '', $package->package_type)); + $function = 'is' . $method . 'Installed'; + $filter = $this->gpm->{$function}($package->slug); + } + + // Filtering updatables only + if ($filter && $this->options['updates-only']) { + $method = ucfirst(preg_replace('/s$/', '', $package->package_type)); + $function = 'is' . $method . 'Updatable'; + $filter = $this->gpm->{$function}($package->slug); + } + + // Filtering enabled only + if ($filter && $this->options['enabled']) { + $method = ucfirst(preg_replace('/s$/', '', $package->package_type)); + + // Check if packaged is enabled. + $function = 'is' . $method . 'Enabled'; + $filter = $this->gpm->{$function}($package->slug); + } + + // Filtering disabled only + if ($filter && $this->options['disabled']) { + $method = ucfirst(preg_replace('/s$/', '', $package->package_type)); + + // Check if package is disabled. + $function = 'is' . $method . 'Enabled'; + $enabled_filter = $this->gpm->{$function}($package->slug); + + // Apply filtering results. + if (!( $enabled_filter === false)) { + $filter = false; + } + } + + if (!$filter) { + unset($data[$type][$slug]); + } + } + } + } + + return $data; + } + + /** + * @param AbstractPackageCollection|Plugins|Themes $packages + * @return array + */ + public function sort(AbstractPackageCollection $packages): array + { + $key = $this->options['sort']; + + // Sorting only works once. + return $packages->sort( + function ($a, $b) use ($key) { + switch ($key) { + case 'author': + return strcmp($a->{$key}['name'], $b->{$key}['name']); + default: + return strcmp($a->$key, $b->$key); + } + }, + $this->options['desc'] ? true : false + ); + } +} diff --git a/system/src/Grav/Console/Gpm/InfoCommand.php b/system/src/Grav/Console/Gpm/InfoCommand.php new file mode 100644 index 0000000..d343cfd --- /dev/null +++ b/system/src/Grav/Console/Gpm/InfoCommand.php @@ -0,0 +1,191 @@ +setName('info') + ->addOption( + 'force', + 'f', + InputOption::VALUE_NONE, + 'Force fetching the new data remotely' + ) + ->addOption( + 'all-yes', + 'y', + InputOption::VALUE_NONE, + 'Assumes yes (or best approach) instead of prompting' + ) + ->addArgument( + 'package', + InputArgument::REQUIRED, + 'The package of which more informations are desired. Use the "index" command for a list of packages' + ) + ->setDescription('Shows more informations about a package') + ->setHelp('The info shows more information about a package'); + } + + /** + * @return int + */ + protected function serve(): int + { + $input = $this->getInput(); + $io = $this->getIO(); + + $this->gpm = new GPM($input->getOption('force')); + + $this->all_yes = $input->getOption('all-yes'); + + $this->displayGPMRelease(); + + $foundPackage = $this->gpm->findPackage($input->getArgument('package')); + + if (!$foundPackage) { + $io->writeln("The package '{$input->getArgument('package')}' was not found in the Grav repository."); + $io->newLine(); + $io->writeln('You can list all the available packages by typing:'); + $io->writeln(" {$this->argv} index"); + $io->newLine(); + + return 1; + } + + $io->writeln("Found package '{$input->getArgument('package')}' under the '" . ucfirst($foundPackage->package_type) . "' section"); + $io->newLine(); + $io->writeln("{$foundPackage->name} [{$foundPackage->slug}]"); + $io->writeln(str_repeat('-', strlen($foundPackage->name) + strlen($foundPackage->slug) + 3)); + $io->writeln('' . strip_tags($foundPackage->description_plain) . ''); + $io->newLine(); + + $packageURL = ''; + if (isset($foundPackage->author['url'])) { + $packageURL = '<' . $foundPackage->author['url'] . '>'; + } + + $io->writeln('' . str_pad( + 'Author', + 12 + ) . ': ' . $foundPackage->author['name'] . ' <' . $foundPackage->author['email'] . '> ' . $packageURL); + + foreach ([ + 'version', + 'keywords', + 'date', + 'homepage', + 'demo', + 'docs', + 'guide', + 'repository', + 'bugs', + 'zipball_url', + 'license' + ] as $info) { + if (isset($foundPackage->{$info})) { + $name = ucfirst($info); + $data = $foundPackage->{$info}; + + if ($info === 'zipball_url') { + $name = 'Download'; + } + + if ($info === 'date') { + $name = 'Last Update'; + $data = date('D, j M Y, H:i:s, P ', strtotime($data)); + } + + $name = str_pad($name, 12); + $io->writeln("{$name}: {$data}"); + } + } + + $type = rtrim($foundPackage->package_type, 's'); + $updatable = $this->gpm->{'is' . $type . 'Updatable'}($foundPackage->slug); + $installed = $this->gpm->{'is' . $type . 'Installed'}($foundPackage->slug); + + // display current version if installed and different + if ($installed && $updatable) { + $local = $this->gpm->{'getInstalled'. $type}($foundPackage->slug); + $io->newLine(); + $io->writeln("Currently installed version: {$local->version}"); + $io->newLine(); + } + + // display changelog information + $question = new ConfirmationQuestion( + 'Would you like to read the changelog? [y|N] ', + false + ); + $answer = $this->all_yes ? true : $io->askQuestion($question); + + if ($answer) { + $changelog = $foundPackage->changelog; + + $io->newLine(); + foreach ($changelog as $version => $log) { + $title = $version . ' [' . $log['date'] . ']'; + $content = preg_replace_callback('/\d\.\s\[\]\(#(.*)\)/', static function ($match) { + return "\n" . ucfirst($match[1]) . ':'; + }, $log['content']); + + $io->writeln("{$title}"); + $io->writeln(str_repeat('-', strlen($title))); + $io->writeln($content); + $io->newLine(); + + $question = new ConfirmationQuestion('Press [ENTER] to continue or [q] to quit ', true); + $answer = $this->all_yes ? false : $io->askQuestion($question); + if (!$answer) { + break; + } + $io->newLine(); + } + } + + $io->newLine(); + + if ($installed && $updatable) { + $io->writeln('You can update this package by typing:'); + $io->writeln(" {$this->argv} update {$foundPackage->slug}"); + } else { + $io->writeln('You can install this package by typing:'); + $io->writeln(" {$this->argv} install {$foundPackage->slug}"); + } + + $io->newLine(); + + return 0; + } +} diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php new file mode 100644 index 0000000..e3bb901 --- /dev/null +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -0,0 +1,726 @@ +setName('install') + ->addOption( + 'force', + 'f', + InputOption::VALUE_NONE, + 'Force re-fetching the data from remote' + ) + ->addOption( + 'all-yes', + 'y', + InputOption::VALUE_NONE, + 'Assumes yes (or best approach) instead of prompting' + ) + ->addOption( + 'destination', + 'd', + InputOption::VALUE_OPTIONAL, + 'The destination where the package should be installed at. By default this would be where the grav instance has been launched from', + GRAV_ROOT + ) + ->addArgument( + 'package', + InputArgument::IS_ARRAY | InputArgument::REQUIRED, + 'Package(s) to install. Use "bin/gpm index" to list packages. Use "bin/gpm direct-install" to install a specific version' + ) + ->setDescription('Performs the installation of plugins and themes') + ->setHelp('The install command allows to install plugins and themes'); + } + + /** + * Allows to set the GPM object, used for testing the class + * + * @param GPM $gpm + */ + public function setGpm(GPM $gpm): void + { + $this->gpm = $gpm; + } + + /** + * @return int + */ + protected function serve(): int + { + $input = $this->getInput(); + $io = $this->getIO(); + + if (!class_exists(ZipArchive::class)) { + $io->title('GPM Install'); + $io->error('php-zip extension needs to be enabled!'); + + return 1; + } + + $this->gpm = new GPM($input->getOption('force')); + + $this->all_yes = $input->getOption('all-yes'); + + $this->displayGPMRelease(); + + $this->destination = realpath($input->getOption('destination')); + + $packages = array_map('strtolower', $input->getArgument('package')); + $this->data = $this->gpm->findPackages($packages); + $this->loadLocalConfig(); + + if (!Installer::isGravInstance($this->destination) || + !Installer::isValidDestination($this->destination, [Installer::EXISTS, Installer::IS_LINK]) + ) { + $io->writeln('ERROR: ' . Installer::lastErrorMsg()); + + return 1; + } + + $io->newLine(); + + if (!$this->data['total']) { + $io->writeln('Nothing to install.'); + $io->newLine(); + + return 0; + } + + if (count($this->data['not_found'])) { + $io->writeln('These packages were not found on Grav: ' . implode( + ', ', + array_keys($this->data['not_found']) + ) . ''); + } + + unset($this->data['not_found'], $this->data['total']); + + if (null !== $this->local_config) { + // Symlinks available, ask if Grav should use them + $this->use_symlinks = false; + $question = new ConfirmationQuestion('Should Grav use the symlinks if available? [y|N] ', false); + + $answer = $this->all_yes ? false : $io->askQuestion($question); + + if ($answer) { + $this->use_symlinks = true; + } + } + + $io->newLine(); + + try { + $dependencies = $this->gpm->getDependencies($packages); + } catch (Exception $e) { + //Error out if there are incompatible packages requirements and tell which ones, and what to do + //Error out if there is any error in parsing the dependencies and their versions, and tell which one is broken + $io->writeln("{$e->getMessage()}"); + + return 1; + } + + if ($dependencies) { + try { + $this->installDependencies($dependencies, 'install', 'The following dependencies need to be installed...'); + $this->installDependencies($dependencies, 'update', 'The following dependencies need to be updated...'); + $this->installDependencies($dependencies, 'ignore', "The following dependencies can be updated as there is a newer version, but it's not mandatory...", false); + } catch (Exception $e) { + $io->writeln('Installation aborted'); + + return 1; + } + + $io->writeln('Dependencies are OK'); + $io->newLine(); + } + + + //We're done installing dependencies. Install the actual packages + foreach ($this->data as $data) { + foreach ($data as $package_name => $package) { + if (array_key_exists($package_name, $dependencies)) { + $io->writeln("Package {$package_name} already installed as dependency"); + } else { + $is_valid_destination = Installer::isValidDestination($this->destination . DS . $package->install_path); + if ($is_valid_destination || Installer::lastErrorCode() == Installer::NOT_FOUND) { + $this->processPackage($package, false); + } else { + if (Installer::lastErrorCode() == Installer::EXISTS) { + try { + $this->askConfirmationIfMajorVersionUpdated($package); + $this->gpm->checkNoOtherPackageNeedsThisDependencyInALowerVersion($package->slug, $package->available, array_keys($data)); + } catch (Exception $e) { + $io->writeln("{$e->getMessage()}"); + + return 1; + } + + $question = new ConfirmationQuestion("The package {$package_name} is already installed, overwrite? [y|N] ", false); + $answer = $this->all_yes ? true : $io->askQuestion($question); + + if ($answer) { + $is_update = true; + $this->processPackage($package, $is_update); + } else { + $io->writeln("Package {$package_name} not overwritten"); + } + } else { + if (Installer::lastErrorCode() == Installer::IS_LINK) { + $io->writeln("Cannot overwrite existing symlink for {$package_name}"); + $io->newLine(); + } + } + } + } + } + } + + if (count($this->demo_processing) > 0) { + foreach ($this->demo_processing as $package) { + $this->installDemoContent($package); + } + } + + // clear cache after successful upgrade + $this->clearCache(); + + return 0; + } + + /** + * If the package is updated from an older major release, show warning and ask confirmation + * + * @param Package $package + * @return void + */ + public function askConfirmationIfMajorVersionUpdated(Package $package): void + { + $io = $this->getIO(); + $package_name = $package->name; + $new_version = $package->available ?: $this->gpm->getLatestVersionOfPackage($package->slug); + $old_version = $package->version; + + $major_version_changed = explode('.', $new_version)[0] !== explode('.', $old_version)[0]; + + if ($major_version_changed) { + if ($this->all_yes) { + $io->writeln("The package {$package_name} will be updated to a new major version {$new_version}, from {$old_version}"); + return; + } + + $question = new ConfirmationQuestion("The package {$package_name} will be updated to a new major version {$new_version}, from {$old_version}. Be sure to read what changed with the new major release. Continue? [y|N] ", false); + + if (!$io->askQuestion($question)) { + $io->writeln("Package {$package_name} not updated"); + exit; + } + } + } + + /** + * Given a $dependencies list, filters their type according to $type and + * shows $message prior to listing them to the user. Then asks the user a confirmation prior + * to installing them. + * + * @param array $dependencies The dependencies array + * @param string $type The type of dependency to show: install, update, ignore + * @param string $message A message to be shown prior to listing the dependencies + * @param bool $required A flag that determines if the installation is required or optional + * @return void + * @throws Exception + */ + public function installDependencies(array $dependencies, string $type, string $message, bool $required = true): void + { + $io = $this->getIO(); + $packages = array_filter($dependencies, static function ($action) use ($type) { + return $action === $type; + }); + if (count($packages) > 0) { + $io->writeln($message); + + foreach ($packages as $dependencyName => $dependencyVersion) { + $io->writeln(" |- Package {$dependencyName}"); + } + + $io->newLine(); + + if ($type === 'install') { + $questionAction = 'Install'; + } else { + $questionAction = 'Update'; + } + + if (count($packages) === 1) { + $questionArticle = 'this'; + } else { + $questionArticle = 'these'; + } + + if (count($packages) === 1) { + $questionNoun = 'package'; + } else { + $questionNoun = 'packages'; + } + + $question = new ConfirmationQuestion("{$questionAction} {$questionArticle} {$questionNoun}? [Y|n] ", true); + $answer = $this->all_yes ? true : $io->askQuestion($question); + + if ($answer) { + foreach ($packages as $dependencyName => $dependencyVersion) { + $package = $this->gpm->findPackage($dependencyName); + $this->processPackage($package, $type === 'update'); + } + $io->newLine(); + } elseif ($required) { + throw new Exception(); + } + } + } + + /** + * @param Package|null $package + * @param bool $is_update True if the package is an update + * @return void + */ + private function processPackage(?Package $package, bool $is_update = false): void + { + $io = $this->getIO(); + + if (!$package) { + $io->writeln('Package not found on the GPM!'); + $io->newLine(); + return; + } + + $symlink = false; + if ($this->use_symlinks) { + if (!isset($package->version) || $this->getSymlinkSource($package)) { + $symlink = true; + } + } + + $symlink ? $this->processSymlink($package) : $this->processGpm($package, $is_update); + + $this->processDemo($package); + } + + /** + * Add package to the queue to process the demo content, if demo content exists + * + * @param Package $package + * @return void + */ + private function processDemo(Package $package): void + { + $demo_dir = $this->destination . DS . $package->install_path . DS . '_demo'; + if (file_exists($demo_dir)) { + $this->demo_processing[] = $package; + } + } + + /** + * Prompt to install the demo content of a package + * + * @param Package $package + * @return void + */ + private function installDemoContent(Package $package): void + { + $io = $this->getIO(); + $demo_dir = $this->destination . DS . $package->install_path . DS . '_demo'; + + if (file_exists($demo_dir)) { + $dest_dir = $this->destination . DS . 'user'; + $pages_dir = $dest_dir . DS . 'pages'; + + // Demo content exists, prompt to install it. + $io->writeln("Attention: {$package->name} contains demo content"); + + $question = new ConfirmationQuestion('Do you wish to install this demo content? [y|N] ', false); + + $answer = $io->askQuestion($question); + + if (!$answer) { + $io->writeln(" '- Skipped! "); + $io->newLine(); + + return; + } + + // if pages folder exists in demo + if (file_exists($demo_dir . DS . 'pages')) { + $pages_backup = 'pages.' . date('m-d-Y-H-i-s'); + $question = new ConfirmationQuestion('This will backup your current `user/pages` folder to `user/' . $pages_backup . '`, continue? [y|N]', false); + $answer = $this->all_yes ? true : $io->askQuestion($question); + + if (!$answer) { + $io->writeln(" '- Skipped! "); + $io->newLine(); + + return; + } + + // backup current pages folder + if (file_exists($dest_dir)) { + if (rename($pages_dir, $dest_dir . DS . $pages_backup)) { + $io->writeln(' |- Backing up pages... ok'); + } else { + $io->writeln(' |- Backing up pages... failed'); + } + } + } + + // Confirmation received, copy over the data + $io->writeln(' |- Installing demo content... ok '); + Folder::rcopy($demo_dir, $dest_dir); + $io->writeln(" '- Success! "); + $io->newLine(); + } + } + + /** + * @param Package $package + * @return array|false + */ + private function getGitRegexMatches(Package $package) + { + if (isset($package->repository)) { + $repository = $package->repository; + } else { + return false; + } + + preg_match(GIT_REGEX, $repository, $matches); + + return $matches; + } + + /** + * @param Package $package + * @return string|false + */ + private function getSymlinkSource(Package $package) + { + $matches = $this->getGitRegexMatches($package); + + foreach ($this->local_config as $paths) { + if (Utils::endsWith($matches[2], '.git')) { + $repo_dir = preg_replace('/\.git$/', '', $matches[2]); + } else { + $repo_dir = $matches[2]; + } + + $paths = (array) $paths; + foreach ($paths as $repo) { + $path = rtrim($repo, '/') . '/' . $repo_dir; + if (file_exists($path)) { + return $path; + } + } + } + + return false; + } + + /** + * @param Package $package + * @return void + */ + private function processSymlink(Package $package): void + { + $io = $this->getIO(); + + exec('cd ' . escapeshellarg($this->destination)); + + $to = $this->destination . DS . $package->install_path; + $from = $this->getSymlinkSource($package); + + $io->writeln("Preparing to Symlink {$package->name}"); + $io->write(' |- Checking source... '); + + if (file_exists($from)) { + $io->writeln('ok'); + + $io->write(' |- Checking destination... '); + $checks = $this->checkDestination($package); + + if (!$checks) { + $io->writeln(" '- Installation failed or aborted."); + $io->newLine(); + } elseif (file_exists($to)) { + $io->writeln(" '- Symlink cannot overwrite an existing package, please remove first"); + $io->newLine(); + } else { + symlink($from, $to); + + // extra white spaces to clear out the buffer properly + $io->writeln(' |- Symlinking package... ok '); + $io->writeln(" '- Success! "); + $io->newLine(); + } + + return; + } + + $io->writeln('not found!'); + $io->writeln(" '- Installation failed or aborted."); + } + + /** + * @param Package $package + * @param bool $is_update + * @return bool + */ + private function processGpm(Package $package, bool $is_update = false) + { + $io = $this->getIO(); + + $version = $package->available ?? $package->version; + $license = Licenses::get($package->slug); + + $io->writeln("Preparing to install {$package->name} [v{$version}]"); + + $io->write(' |- Downloading package... 0%'); + $this->file = $this->downloadPackage($package, $license); + + if (!$this->file) { + $io->writeln(" '- Installation failed or aborted."); + $io->newLine(); + + return false; + } + + $io->write(' |- Checking destination... '); + $checks = $this->checkDestination($package); + + if (!$checks) { + $io->writeln(" '- Installation failed or aborted."); + $io->newLine(); + } else { + $io->write(' |- Installing package... '); + $installation = $this->installPackage($package, $is_update); + if (!$installation) { + $io->writeln(" '- Installation failed or aborted."); + $io->newLine(); + } else { + $io->writeln(" '- Success! "); + $io->newLine(); + + return true; + } + } + + return false; + } + + /** + * @param Package $package + * @param string|null $license + * @return string|null + */ + private function downloadPackage(Package $package, string $license = null) + { + $io = $this->getIO(); + + $tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true); + $this->tmp = $tmp_dir . '/Grav-' . uniqid(); + $filename = $package->slug . Utils::basename($package->zipball_url); + $filename = preg_replace('/[\\\\\/:"*?&<>|]+/m', '-', $filename); + $query = ''; + + if (!empty($package->premium)) { + $query = json_encode(array_merge( + $package->premium, + [ + 'slug' => $package->slug, + 'filename' => $package->premium['filename'], + 'license_key' => $license, + 'sid' => md5(GRAV_ROOT) + ] + )); + + $query = '?d=' . base64_encode($query); + } + + try { + $output = Response::get($package->zipball_url . $query, [], [$this, 'progress']); + } catch (Exception $e) { + if (!empty($package->premium) && $e->getCode() === 401) { + $message = 'Unauthorized Premium License Key'; + } else { + $message = $e->getMessage(); + } + + $error = str_replace("\n", "\n | '- ", $message); + $io->write("\x0D"); + // extra white spaces to clear out the buffer properly + $io->writeln(' |- Downloading package... error '); + $io->writeln(" | '- " . $error); + + return null; + } + + Folder::create($this->tmp); + + $io->write("\x0D"); + $io->write(' |- Downloading package... 100%'); + $io->newLine(); + + file_put_contents($this->tmp . DS . $filename, $output); + + return $this->tmp . DS . $filename; + } + + /** + * @param Package $package + * @return bool + */ + private function checkDestination(Package $package): bool + { + $io = $this->getIO(); + + Installer::isValidDestination($this->destination . DS . $package->install_path); + + if (Installer::lastErrorCode() === Installer::IS_LINK) { + $io->write("\x0D"); + $io->writeln(' |- Checking destination... symbolic link'); + + if ($this->all_yes) { + $io->writeln(" | '- Skipped automatically."); + + return false; + } + + $question = new ConfirmationQuestion( + " | '- Destination has been detected as symlink, delete symbolic link first? [y|N] ", + false + ); + $answer = $io->askQuestion($question); + + if (!$answer) { + $io->writeln(" | '- You decided to not delete the symlink automatically."); + + return false; + } + + unlink($this->destination . DS . $package->install_path); + } + + $io->write("\x0D"); + $io->writeln(' |- Checking destination... ok'); + + return true; + } + + /** + * Install a package + * + * @param Package $package + * @param bool $is_update True if it's an update. False if it's an install + * @return bool + */ + private function installPackage(Package $package, bool $is_update = false): bool + { + $io = $this->getIO(); + + $type = $package->package_type; + + Installer::install($this->file, $this->destination, ['install_path' => $package->install_path, 'theme' => $type === 'themes', 'is_update' => $is_update]); + $error_code = Installer::lastErrorCode(); + Folder::delete($this->tmp); + + if ($error_code) { + $io->write("\x0D"); + // extra white spaces to clear out the buffer properly + $io->writeln(' |- Installing package... error '); + $io->writeln(" | '- " . Installer::lastErrorMsg()); + + return false; + } + + $message = Installer::getMessage(); + if ($message) { + $io->write("\x0D"); + // extra white spaces to clear out the buffer properly + $io->writeln(" |- {$message}"); + } + + $io->write("\x0D"); + // extra white spaces to clear out the buffer properly + $io->writeln(' |- Installing package... ok '); + + return true; + } + + /** + * @param array $progress + * @return void + */ + public function progress(array $progress): void + { + $io = $this->getIO(); + + $io->write("\x0D"); + $io->write(' |- Downloading package... ' . str_pad( + $progress['percent'], + 5, + ' ', + STR_PAD_LEFT + ) . '%'); + } +} diff --git a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php new file mode 100644 index 0000000..2b164d0 --- /dev/null +++ b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php @@ -0,0 +1,344 @@ +setName('self-upgrade') + ->setAliases(['selfupgrade', 'selfupdate']) + ->addOption( + 'force', + 'f', + InputOption::VALUE_NONE, + 'Force re-fetching the data from remote' + ) + ->addOption( + 'all-yes', + 'y', + InputOption::VALUE_NONE, + 'Assumes yes (or best approach) instead of prompting' + ) + ->addOption( + 'overwrite', + 'o', + InputOption::VALUE_NONE, + 'Option to overwrite packages if they already exist' + ) + ->addOption( + 'timeout', + 't', + InputOption::VALUE_OPTIONAL, + 'Option to set the timeout in seconds when downloading the update (0 for no timeout)', + 30 + ) + ->setDescription('Detects and performs an update of Grav itself when available') + ->setHelp('The update command updates Grav itself when a new version is available'); + } + + /** + * @return int + */ + protected function serve(): int + { + $input = $this->getInput(); + $io = $this->getIO(); + + if (!class_exists(ZipArchive::class)) { + $io->title('GPM Self Upgrade'); + $io->error('php-zip extension needs to be enabled!'); + + return 1; + } + + $this->upgrader = new Upgrader($input->getOption('force')); + $this->all_yes = $input->getOption('all-yes'); + $this->overwrite = $input->getOption('overwrite'); + $this->timeout = (int) $input->getOption('timeout'); + + $this->displayGPMRelease(); + + $update = $this->upgrader->getAssets()['grav-update']; + + $local = $this->upgrader->getLocalVersion(); + $remote = $this->upgrader->getRemoteVersion(); + $release = strftime('%c', strtotime($this->upgrader->getReleaseDate())); + + if (!$this->upgrader->meetsRequirements()) { + $io->writeln('ATTENTION:'); + $io->writeln(' Grav has increased the minimum PHP requirement.'); + $io->writeln(' You are currently running PHP ' . phpversion() . ', but PHP ' . $this->upgrader->minPHPVersion() . ' is required.'); + $io->writeln(' Additional information: http://getgrav.org/blog/changing-php-requirements'); + $io->newLine(); + $io->writeln('Selfupgrade aborted.'); + $io->newLine(); + + return 1; + } + + if (!$this->overwrite && !$this->upgrader->isUpgradable()) { + $io->writeln("You are already running the latest version of Grav v{$local}"); + $io->writeln("which was released on {$release}"); + + $config = Grav::instance()['config']; + $schema = $config->get('versions.core.grav.schema'); + if ($schema !== GRAV_SCHEMA && version_compare($schema, GRAV_SCHEMA, '<')) { + $io->newLine(); + $io->writeln('However post-install scripts have not been run.'); + if (!$this->all_yes) { + $question = new ConfirmationQuestion( + 'Would you like to run the scripts? [Y|n] ', + true + ); + $answer = $io->askQuestion($question); + } else { + $answer = true; + } + + if ($answer) { + // Finalize installation. + Install::instance()->finalize(); + + $io->write(' |- Running post-install scripts... '); + $io->writeln(" '- Success! "); + $io->newLine(); + } + } + + return 0; + } + + Installer::isValidDestination(GRAV_ROOT . '/system'); + if (Installer::IS_LINK === Installer::lastErrorCode()) { + $io->writeln('ATTENTION: Grav is symlinked, cannot upgrade, aborting...'); + $io->newLine(); + $io->writeln("You are currently running a symbolically linked Grav v{$local}. Latest available is v{$remote}."); + + return 1; + } + + // not used but preloaded just in case! + new ArrayInput([]); + + $io->writeln("Grav v{$remote} is now available [release date: {$release}]."); + $io->writeln('You are currently using v' . GRAV_VERSION . '.'); + + if (!$this->all_yes) { + $question = new ConfirmationQuestion( + 'Would you like to read the changelog before proceeding? [y|N] ', + false + ); + $answer = $io->askQuestion($question); + + if ($answer) { + $changelog = $this->upgrader->getChangelog(GRAV_VERSION); + + $io->newLine(); + foreach ($changelog as $version => $log) { + $title = $version . ' [' . $log['date'] . ']'; + $content = preg_replace_callback('/\d\.\s\[\]\(#(.*)\)/', static function ($match) { + return "\n" . ucfirst($match[1]) . ':'; + }, $log['content']); + + $io->writeln($title); + $io->writeln(str_repeat('-', strlen($title))); + $io->writeln($content); + $io->newLine(); + } + + $question = new ConfirmationQuestion('Press [ENTER] to continue.', true); + $io->askQuestion($question); + } + + $question = new ConfirmationQuestion('Would you like to upgrade now? [y|N] ', false); + $answer = $io->askQuestion($question); + + if (!$answer) { + $io->writeln('Aborting...'); + + return 1; + } + } + + $io->newLine(); + $io->writeln("Preparing to upgrade to v{$remote}.."); + + $io->write(" |- Downloading upgrade [{$this->formatBytes($update['size'])}]... 0%"); + $this->file = $this->download($update); + + $io->write(' |- Installing upgrade... '); + $installation = $this->upgrade(); + + $error = 0; + if (!$installation) { + $io->writeln(" '- Installation failed or aborted."); + $io->newLine(); + $error = 1; + } else { + $io->writeln(" '- Success! "); + $io->newLine(); + } + + if ($this->tmp && is_dir($this->tmp)) { + Folder::delete($this->tmp); + } + + return $error; + } + + /** + * @param array $package + * @return string + */ + private function download(array $package): string + { + $io = $this->getIO(); + + $tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true); + $this->tmp = $tmp_dir . '/grav-update-' . uniqid('', false); + $options = [ + 'timeout' => $this->timeout, + ]; + + $output = Response::get($package['download'], $options, [$this, 'progress']); + + Folder::create($this->tmp); + + $io->write("\x0D"); + $io->write(" |- Downloading upgrade [{$this->formatBytes($package['size'])}]... 100%"); + $io->newLine(); + + file_put_contents($this->tmp . DS . $package['name'], $output); + + return $this->tmp . DS . $package['name']; + } + + /** + * @return bool + */ + private function upgrade(): bool + { + $io = $this->getIO(); + + $this->upgradeGrav($this->file); + + $errorCode = Installer::lastErrorCode(); + if ($errorCode) { + $io->write("\x0D"); + // extra white spaces to clear out the buffer properly + $io->writeln(' |- Installing upgrade... error '); + $io->writeln(" | '- " . Installer::lastErrorMsg()); + + return false; + } + + $io->write("\x0D"); + // extra white spaces to clear out the buffer properly + $io->writeln(' |- Installing upgrade... ok '); + + return true; + } + + /** + * @param array $progress + * @return void + */ + public function progress(array $progress): void + { + $io = $this->getIO(); + + $io->write("\x0D"); + $io->write(" |- Downloading upgrade [{$this->formatBytes($progress['filesize']) }]... " . str_pad( + $progress['percent'], + 5, + ' ', + STR_PAD_LEFT + ) . '%'); + } + + /** + * @param int|float $size + * @param int $precision + * @return string + */ + public function formatBytes($size, int $precision = 2): string + { + $base = log($size) / log(1024); + $suffixes = array('', 'k', 'M', 'G', 'T'); + + return round(1024 ** ($base - floor($base)), $precision) . $suffixes[(int)floor($base)]; + } + + /** + * @param string $zip + * @return void + */ + private function upgradeGrav(string $zip): void + { + try { + $folder = Installer::unZip($zip, $this->tmp . '/zip'); + if ($folder === false) { + throw new RuntimeException(Installer::lastErrorMsg()); + } + + $script = $folder . '/system/install.php'; + if ((file_exists($script) && $install = include $script) && is_callable($install)) { + $install($zip); + } else { + throw new RuntimeException('Uploaded archive file is not a valid Grav update package'); + } + } catch (Exception $e) { + Installer::setError($e->getMessage()); + } + } +} diff --git a/system/src/Grav/Console/Gpm/UninstallCommand.php b/system/src/Grav/Console/Gpm/UninstallCommand.php new file mode 100644 index 0000000..60d85aa --- /dev/null +++ b/system/src/Grav/Console/Gpm/UninstallCommand.php @@ -0,0 +1,312 @@ +setName('uninstall') + ->addOption( + 'all-yes', + 'y', + InputOption::VALUE_NONE, + 'Assumes yes (or best approach) instead of prompting' + ) + ->addArgument( + 'package', + InputArgument::IS_ARRAY | InputArgument::REQUIRED, + 'The package(s) that are desired to be removed. Use the "index" command for a list of packages' + ) + ->setDescription('Performs the uninstallation of plugins and themes') + ->setHelp('The uninstall command allows to uninstall plugins and themes'); + } + + /** + * @return int + */ + protected function serve(): int + { + $input = $this->getInput(); + $io = $this->getIO(); + + $this->gpm = new GPM(); + + $this->all_yes = $input->getOption('all-yes'); + + $packages = array_map('strtolower', $input->getArgument('package')); + $this->data = ['total' => 0, 'not_found' => []]; + + $total = 0; + foreach ($packages as $package) { + $plugin = $this->gpm->getInstalledPlugin($package); + $theme = $this->gpm->getInstalledTheme($package); + if ($plugin || $theme) { + $this->data[strtolower($package)] = $plugin ?: $theme; + $total++; + } else { + $this->data['not_found'][] = $package; + } + } + $this->data['total'] = $total; + + $io->newLine(); + + if (!$this->data['total']) { + $io->writeln('Nothing to uninstall.'); + $io->newLine(); + + return 0; + } + + if (count($this->data['not_found'])) { + $io->writeln('These packages were not found installed: ' . implode( + ', ', + $this->data['not_found'] + ) . ''); + } + + unset($this->data['not_found'], $this->data['total']); + + // Plugins need to be initialized in order to make clearcache to work. + try { + $this->initializePlugins(); + } catch (Throwable $e) { + $io->writeln("Some plugins failed to initialize: {$e->getMessage()}"); + } + + $error = 0; + foreach ($this->data as $slug => $package) { + $io->writeln("Preparing to uninstall {$package->name} [v{$package->version}]"); + + $io->write(' |- Checking destination... '); + $checks = $this->checkDestination($slug, $package); + + if (!$checks) { + $io->writeln(" '- Installation failed or aborted."); + $io->newLine(); + $error = 1; + } else { + $uninstall = $this->uninstallPackage($slug, $package); + + if (!$uninstall) { + $io->writeln(" '- Uninstallation failed or aborted."); + $error = 1; + } else { + $io->writeln(" '- Success! "); + } + } + } + + // clear cache after successful upgrade + $this->clearCache(); + + return $error; + } + + /** + * @param string $slug + * @param Local\Package|Remote\Package $package + * @param bool $is_dependency + * @return bool + */ + private function uninstallPackage($slug, $package, $is_dependency = false): bool + { + $io = $this->getIO(); + + if (!$slug) { + return false; + } + + //check if there are packages that have this as a dependency. Abort and show list + $dependent_packages = $this->gpm->getPackagesThatDependOnPackage($slug); + if (count($dependent_packages) > ($is_dependency ? 1 : 0)) { + $io->newLine(2); + $io->writeln('Uninstallation failed.'); + $io->newLine(); + if (count($dependent_packages) > ($is_dependency ? 2 : 1)) { + $io->writeln('The installed packages ' . implode(', ', $dependent_packages) . ' depends on this package. Please remove those first.'); + } else { + $io->writeln('The installed package ' . implode(', ', $dependent_packages) . ' depends on this package. Please remove it first.'); + } + + $io->newLine(); + return false; + } + + if (isset($package->dependencies)) { + $dependencies = $package->dependencies; + + if ($is_dependency) { + foreach ($dependencies as $key => $dependency) { + if (in_array($dependency['name'], $this->dependencies, true)) { + unset($dependencies[$key]); + } + } + } elseif (count($dependencies) > 0) { + $io->writeln(' `- Dependencies found...'); + $io->newLine(); + } + + foreach ($dependencies as $dependency) { + $this->dependencies[] = $dependency['name']; + + if (is_array($dependency)) { + $dependency = $dependency['name']; + } + if ($dependency === 'grav' || $dependency === 'php') { + continue; + } + + $dependencyPackage = $this->gpm->findPackage($dependency); + + $dependency_exists = $this->packageExists($dependency, $dependencyPackage); + + if ($dependency_exists == Installer::EXISTS) { + $io->writeln("A dependency on {$dependencyPackage->name} [v{$dependencyPackage->version}] was found"); + + $question = new ConfirmationQuestion(" |- Uninstall {$dependencyPackage->name}? [y|N] ", false); + $answer = $this->all_yes ? true : $io->askQuestion($question); + + if ($answer) { + $uninstall = $this->uninstallPackage($dependency, $dependencyPackage, true); + + if (!$uninstall) { + $io->writeln(" '- Uninstallation failed or aborted."); + } else { + $io->writeln(" '- Success! "); + } + $io->newLine(); + } else { + $io->writeln(" '- You decided not to uninstall {$dependencyPackage->name}."); + $io->newLine(); + } + } + } + } + + + $locator = Grav::instance()['locator']; + $path = $locator->findResource($package->package_type . '://' . $slug); + Installer::uninstall($path); + $errorCode = Installer::lastErrorCode(); + + if ($errorCode && $errorCode !== Installer::IS_LINK && $errorCode !== Installer::EXISTS) { + $io->writeln(" |- Uninstalling {$package->name} package... error "); + $io->writeln(" | '- " . Installer::lastErrorMsg() . ''); + + return false; + } + + $message = Installer::getMessage(); + if ($message) { + $io->writeln(" |- {$message}"); + } + + if (!$is_dependency && $this->dependencies) { + $io->writeln("Finishing up uninstalling {$package->name}"); + } + $io->writeln(" |- Uninstalling {$package->name} package... ok "); + + return true; + } + + /** + * @param string $slug + * @param Local\Package|Remote\Package $package + * @return bool + */ + private function checkDestination(string $slug, $package): bool + { + $io = $this->getIO(); + + $exists = $this->packageExists($slug, $package); + + if ($exists === Installer::IS_LINK) { + $io->write("\x0D"); + $io->writeln(' |- Checking destination... symbolic link'); + + if ($this->all_yes) { + $io->writeln(" | '- Skipped automatically."); + + return false; + } + + $question = new ConfirmationQuestion( + " | '- Destination has been detected as symlink, delete symbolic link first? [y|N] ", + false + ); + + $answer = $io->askQuestion($question); + if (!$answer) { + $io->writeln(" | '- You decided not to delete the symlink automatically."); + + return false; + } + } + + $io->write("\x0D"); + $io->writeln(' |- Checking destination... ok'); + + return true; + } + + /** + * Check if package exists + * + * @param string $slug + * @param Local\Package|Remote\Package $package + * @return int + */ + private function packageExists(string $slug, $package): int + { + $path = Grav::instance()['locator']->findResource($package->package_type . '://' . $slug); + Installer::isValidDestination($path); + + return Installer::lastErrorCode(); + } +} diff --git a/system/src/Grav/Console/Gpm/UpdateCommand.php b/system/src/Grav/Console/Gpm/UpdateCommand.php new file mode 100644 index 0000000..d39b77d --- /dev/null +++ b/system/src/Grav/Console/Gpm/UpdateCommand.php @@ -0,0 +1,289 @@ +setName('update') + ->addOption( + 'force', + 'f', + InputOption::VALUE_NONE, + 'Force re-fetching the data from remote' + ) + ->addOption( + 'destination', + 'd', + InputOption::VALUE_OPTIONAL, + 'The grav instance location where the updates should be applied to. By default this would be where the grav cli has been launched from', + GRAV_ROOT + ) + ->addOption( + 'all-yes', + 'y', + InputOption::VALUE_NONE, + 'Assumes yes (or best approach) instead of prompting' + ) + ->addOption( + 'overwrite', + 'o', + InputOption::VALUE_NONE, + 'Option to overwrite packages if they already exist' + ) + ->addOption( + 'plugins', + 'p', + InputOption::VALUE_NONE, + 'Update only plugins' + ) + ->addOption( + 'themes', + 't', + InputOption::VALUE_NONE, + 'Update only themes' + ) + ->addArgument( + 'package', + InputArgument::IS_ARRAY | InputArgument::OPTIONAL, + 'The package or packages that is desired to update. By default all available updates will be applied.' + ) + ->setDescription('Detects and performs an update of plugins and themes when available') + ->setHelp('The update command updates plugins and themes when a new version is available'); + } + + /** + * @return int + */ + protected function serve(): int + { + $input = $this->getInput(); + $io = $this->getIO(); + + if (!class_exists(ZipArchive::class)) { + $io->title('GPM Update'); + $io->error('php-zip extension needs to be enabled!'); + + return 1; + } + + $this->upgrader = new Upgrader($input->getOption('force')); + $local = $this->upgrader->getLocalVersion(); + $remote = $this->upgrader->getRemoteVersion(); + if ($local !== $remote) { + $io->writeln('WARNING: A new version of Grav is available. You should update Grav before updating plugins and themes. If you continue without updating Grav, some plugins or themes may stop working.'); + $io->newLine(); + $question = new ConfirmationQuestion('Continue with the update process? [Y|n] ', true); + $answer = $io->askQuestion($question); + + if (!$answer) { + $io->writeln('Update aborted. Exiting...'); + + return 1; + } + } + + $this->gpm = new GPM($input->getOption('force')); + + $this->all_yes = $input->getOption('all-yes'); + $this->overwrite = $input->getOption('overwrite'); + + $this->displayGPMRelease(); + + $this->destination = realpath($input->getOption('destination')); + + if (!Installer::isGravInstance($this->destination)) { + $io->writeln('ERROR: ' . Installer::lastErrorMsg()); + exit; + } + if ($input->getOption('plugins') === false && $input->getOption('themes') === false) { + $list_type = ['plugins' => true, 'themes' => true]; + } else { + $list_type['plugins'] = $input->getOption('plugins'); + $list_type['themes'] = $input->getOption('themes'); + } + + if ($this->overwrite) { + $this->data = $this->gpm->getInstallable($list_type); + $description = ' can be overwritten'; + } else { + $this->data = $this->gpm->getUpdatable($list_type); + $description = ' need updating'; + } + + $only_packages = array_map('strtolower', $input->getArgument('package')); + + if (!$this->overwrite && !$this->data['total']) { + $io->writeln('Nothing to update.'); + + return 0; + } + + $io->write("Found {$this->gpm->countInstalled()} packages installed of which {$this->data['total']}{$description}"); + + $limit_to = $this->userInputPackages($only_packages); + + $io->newLine(); + + unset($this->data['total'], $limit_to['total']); + + + // updates review + $slugs = []; + + $index = 1; + foreach ($this->data as $packages) { + foreach ($packages as $slug => $package) { + if (!array_key_exists($slug, $limit_to) && count($only_packages)) { + continue; + } + + if (!$package->available) { + $package->available = $package->version; + } + + $io->writeln( + // index + str_pad((string)$index++, 2, '0', STR_PAD_LEFT) . '. ' . + // name + '' . str_pad($package->name, 15) . ' ' . + // version + "[v{$package->version} -> v{$package->available}]" + ); + $slugs[] = $slug; + } + } + + if (!$this->all_yes) { + // prompt to continue + $io->newLine(); + $question = new ConfirmationQuestion('Continue with the update process? [Y|n] ', true); + $answer = $io->askQuestion($question); + + if (!$answer) { + $io->writeln('Update aborted. Exiting...'); + + return 1; + } + } + + // finally update + $install_command = $this->getApplication()->find('install'); + + $args = new ArrayInput([ + 'command' => 'install', + 'package' => $slugs, + '-f' => $input->getOption('force'), + '-d' => $this->destination, + '-y' => true + ]); + $command_exec = $install_command->run($args, $io); + + if ($command_exec != 0) { + $io->writeln('Error: An error occurred while trying to install the packages'); + + return 1; + } + + return 0; + } + + /** + * @param array $only_packages + * @return array + */ + private function userInputPackages(array $only_packages): array + { + $io = $this->getIO(); + + $found = ['total' => 0]; + $ignore = []; + + if (!count($only_packages)) { + $io->newLine(); + } else { + foreach ($only_packages as $only_package) { + $find = $this->gpm->findPackage($only_package); + + if (!$find || (!$this->overwrite && !$this->gpm->isUpdatable($find->slug))) { + $name = $find->slug ?? $only_package; + $ignore[$name] = $name; + } else { + $found[$find->slug] = $find; + $found['total']++; + } + } + + if ($found['total']) { + $list = $found; + unset($list['total']); + $list = array_keys($list); + + if ($found['total'] !== $this->data['total']) { + $io->write(", only {$found['total']} will be updated"); + } + + $io->newLine(); + $io->writeln('Limiting updates for only ' . implode( + ', ', + $list + ) . ''); + } + + if (count($ignore)) { + $io->newLine(); + $io->writeln('Packages not found or not requiring updates: ' . implode( + ', ', + $ignore + ) . ''); + } + } + + return $found; + } +} diff --git a/system/src/Grav/Console/Gpm/VersionCommand.php b/system/src/Grav/Console/Gpm/VersionCommand.php new file mode 100644 index 0000000..3e16adb --- /dev/null +++ b/system/src/Grav/Console/Gpm/VersionCommand.php @@ -0,0 +1,125 @@ +setName('version') + ->addOption( + 'force', + 'f', + InputOption::VALUE_NONE, + 'Force re-fetching the data from remote' + ) + ->addArgument( + 'package', + InputArgument::IS_ARRAY | InputArgument::OPTIONAL, + 'The package or packages that is desired to know the version of. By default and if not specified this would be grav' + ) + ->setDescription('Shows the version of an installed package. If available also shows pending updates.') + ->setHelp('The version command displays the current version of a package installed and, if available, the available version of pending updates'); + } + + /** + * @return int + */ + protected function serve(): int + { + $input = $this->getInput(); + $io = $this->getIO(); + + $this->gpm = new GPM($input->getOption('force')); + $packages = $input->getArgument('package'); + + $installed = false; + + if (!count($packages)) { + $packages = ['grav']; + } + + foreach ($packages as $package) { + $package = strtolower($package); + $name = null; + $version = null; + $updatable = false; + + if ($package === 'grav') { + $name = 'Grav'; + $version = GRAV_VERSION; + $upgrader = new Upgrader(); + + if ($upgrader->isUpgradable()) { + $updatable = " [upgradable: v{$upgrader->getRemoteVersion()}]"; + } + } else { + // get currently installed version + $locator = Grav::instance()['locator']; + $blueprints_path = $locator->findResource('plugins://' . $package . DS . 'blueprints.yaml'); + if (!file_exists($blueprints_path)) { // theme? + $blueprints_path = $locator->findResource('themes://' . $package . DS . 'blueprints.yaml'); + if (!file_exists($blueprints_path)) { + continue; + } + } + + $file = YamlFile::instance($blueprints_path); + $package_yaml = $file->content(); + $file->free(); + + $version = $package_yaml['version']; + + if (!$version) { + continue; + } + + $installed = $this->gpm->findPackage($package); + if ($installed) { + $name = $installed->name; + + if ($this->gpm->isUpdatable($package)) { + $updatable = " [updatable: v{$installed->available}]"; + } + } + } + + $updatable = $updatable ?: ''; + + if ($installed || $package === 'grav') { + $io->writeln("You are running {$name} v{$version}{$updatable}"); + } else { + $io->writeln("Package {$package} not found"); + } + } + + return 0; + } +} diff --git a/system/src/Grav/Console/GpmCommand.php b/system/src/Grav/Console/GpmCommand.php new file mode 100644 index 0000000..f89d565 --- /dev/null +++ b/system/src/Grav/Console/GpmCommand.php @@ -0,0 +1,68 @@ +setupConsole($input, $output); + + $grav = Grav::instance(); + $grav['config']->init(); + $grav['uri']->init(); + // @phpstan-ignore-next-line + $grav['accounts']; + + return $this->serve(); + } + + /** + * Override with your implementation. + * + * @return int + */ + protected function serve() + { + // Return error. + return 1; + } + + /** + * @return void + */ + protected function displayGPMRelease() + { + /** @var Config $config */ + $config = Grav::instance()['config']; + + $io = $this->getIO(); + $io->newLine(); + $io->writeln('GPM Releases Configuration: ' . ucfirst($config->get('system.gpm.releases')) . ''); + $io->newLine(); + } +} diff --git a/system/src/Grav/Console/GravCommand.php b/system/src/Grav/Console/GravCommand.php new file mode 100644 index 0000000..a62dbc3 --- /dev/null +++ b/system/src/Grav/Console/GravCommand.php @@ -0,0 +1,52 @@ +setupConsole($input, $output); + + // Old versions of Grav called this command after grav upgrade. + // We need make this command to work with older ConsoleTrait: + if (method_exists($this, 'initializeGrav')) { + $this->initializeGrav(); + } + + return $this->serve(); + } + + /** + * Override with your implementation. + * + * @return int + */ + protected function serve() + { + // Return error. + return 1; + } +} diff --git a/system/src/Grav/Console/Plugin/PluginListCommand.php b/system/src/Grav/Console/Plugin/PluginListCommand.php new file mode 100644 index 0000000..24be2f5 --- /dev/null +++ b/system/src/Grav/Console/Plugin/PluginListCommand.php @@ -0,0 +1,69 @@ +setHidden(true); + } + + /** + * @return int + */ + protected function serve(): int + { + $bin = $this->argv; + $pattern = '([A-Z]\w+Command\.php)'; + + $io = $this->getIO(); + $io->newLine(); + $io->writeln('Usage:'); + $io->writeln(" {$bin} [slug] [command] [arguments]"); + $io->newLine(); + $io->writeln('Example:'); + $io->writeln(" {$bin} error log -l 1 --trace"); + $io->newLine(); + $io->writeln('Plugins with CLI available:'); + + $plugins = Plugins::all(); + $index = 0; + foreach ($plugins as $name => $plugin) { + if (!$plugin->enabled) { + continue; + } + + $list = Folder::all("plugins://{$name}", ['compare' => 'Pathname', 'pattern' => '/\/cli\/' . $pattern . '$/usm', 'levels' => 1]); + if (!$list) { + continue; + } + + $index++; + $num = str_pad((string)$index, 2, '0', STR_PAD_LEFT); + $io->writeln(' ' . $num . '. ' . str_pad($name, 15) . " {$bin} {$name} list"); + } + + return 0; + } +} diff --git a/system/src/Grav/Console/TerminalObjects/Table.php b/system/src/Grav/Console/TerminalObjects/Table.php new file mode 100644 index 0000000..754f2dc --- /dev/null +++ b/system/src/Grav/Console/TerminalObjects/Table.php @@ -0,0 +1,38 @@ +column_widths = $this->getColumnWidths(); + $this->table_width = $this->getWidth(); + $this->border = $this->getBorder(); + + $this->buildHeaderRow(); + + foreach ($this->data as $key => $columns) { + $this->rows[] = $this->buildRow($columns); + } + + $this->rows[] = $this->border; + + return $this->rows; + } +} diff --git a/system/src/Grav/Events/BeforeSessionStartEvent.php b/system/src/Grav/Events/BeforeSessionStartEvent.php new file mode 100644 index 0000000..de15051 --- /dev/null +++ b/system/src/Grav/Events/BeforeSessionStartEvent.php @@ -0,0 +1,36 @@ +start() right before session_start() call. + * + * @property SessionInterface $session Session instance. + */ +class BeforeSessionStartEvent extends Event +{ + /** @var SessionInterface */ + public $session; + + public function __construct(SessionInterface $session) + { + $this->session = $session; + } + + public function __debugInfo(): array + { + return (array)$this; + } +} diff --git a/system/src/Grav/Events/FlexRegisterEvent.php b/system/src/Grav/Events/FlexRegisterEvent.php new file mode 100644 index 0000000..40c8529 --- /dev/null +++ b/system/src/Grav/Events/FlexRegisterEvent.php @@ -0,0 +1,45 @@ +flex = $flex; + } + + /** + * @return array + */ + public function __debugInfo(): array + { + return (array)$this; + } +} diff --git a/system/src/Grav/Events/PageEvent.php b/system/src/Grav/Events/PageEvent.php new file mode 100644 index 0000000..a451f9f --- /dev/null +++ b/system/src/Grav/Events/PageEvent.php @@ -0,0 +1,18 @@ +permissions = $permissions; + } + + /** + * @return array + */ + public function __debugInfo(): array + { + return (array)$this; + } +} diff --git a/system/src/Grav/Events/PluginsLoadedEvent.php b/system/src/Grav/Events/PluginsLoadedEvent.php new file mode 100644 index 0000000..24e1ff7 --- /dev/null +++ b/system/src/Grav/Events/PluginsLoadedEvent.php @@ -0,0 +1,53 @@ +grav = $grav; + $this->plugins = $plugins; + } + + /** + * @return array + */ + public function __debugInfo(): array + { + return [ + 'plugins' => $this->plugins + ]; + } +} diff --git a/system/src/Grav/Events/SessionStartEvent.php b/system/src/Grav/Events/SessionStartEvent.php new file mode 100644 index 0000000..283e9a1 --- /dev/null +++ b/system/src/Grav/Events/SessionStartEvent.php @@ -0,0 +1,36 @@ +start() right after successful session_start() call. + * + * @property SessionInterface $session Session instance. + */ +class SessionStartEvent extends Event +{ + /** @var SessionInterface */ + public $session; + + public function __construct(SessionInterface $session) + { + $this->session = $session; + } + + public function __debugInfo(): array + { + return (array)$this; + } +} diff --git a/system/src/Grav/Events/TypesEvent.php b/system/src/Grav/Events/TypesEvent.php new file mode 100644 index 0000000..6a746a8 --- /dev/null +++ b/system/src/Grav/Events/TypesEvent.php @@ -0,0 +1,18 @@ + + */ +class Access implements JsonSerializable, IteratorAggregate, Countable +{ + /** @var string */ + private $name; + /** @var array */ + private $rules; + /** @var array */ + private $ops; + /** @var array */ + private $acl = []; + /** @var array */ + private $inherited = []; + + /** + * Access constructor. + * @param string|array|null $acl + * @param array|null $rules + * @param string $name + */ + public function __construct($acl = null, array $rules = null, string $name = '') + { + $this->name = $name; + $this->rules = $rules ?? []; + $this->ops = ['+' => true, '-' => false]; + if (is_string($acl)) { + $this->acl = $this->resolvePermissions($acl); + } elseif (is_array($acl)) { + $this->acl = $this->normalizeAcl($acl); + } + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @param Access $parent + * @param string|null $name + * @return void + */ + public function inherit(Access $parent, string $name = null) + { + // Remove cached null actions from acl. + $acl = $this->getAllActions(); + // Get only inherited actions. + $inherited = array_diff_key($parent->getAllActions(), $acl); + + $this->inherited += $parent->inherited + array_fill_keys(array_keys($inherited), $name ?? $parent->getName()); + $this->acl = array_replace($acl, $inherited); + } + + /** + * Checks user authorization to the action. + * + * @param string $action + * @param string|null $scope + * @return bool|null + */ + public function authorize(string $action, string $scope = null): ?bool + { + if (null !== $scope) { + $action = $scope !== 'test' ? "{$scope}.{$action}" : $action; + } + + return $this->get($action); + } + + /** + * @return array + */ + public function toArray(): array + { + return Utils::arrayUnflattenDotNotation($this->acl); + } + + /** + * @return array + */ + public function getAllActions(): array + { + return array_filter($this->acl, static function($val) { return $val !== null; }); + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + return $this->toArray(); + } + + /** + * @param string $action + * @return bool|null + */ + public function get(string $action) + { + // Get access value. + if (isset($this->acl[$action])) { + return $this->acl[$action]; + } + + // If no value is defined, check the parent access (all true|false). + $pos = strrpos($action, '.'); + $value = $pos ? $this->get(substr($action, 0, $pos)) : null; + + // Cache result for faster lookup. + $this->acl[$action] = $value; + + return $value; + } + + /** + * @param string $action + * @return bool + */ + public function isInherited(string $action): bool + { + return isset($this->inherited[$action]); + } + + /** + * @param string $action + * @return string|null + */ + public function getInherited(string $action): ?string + { + return $this->inherited[$action] ?? null; + } + + /** + * @return Traversable + */ + public function getIterator(): Traversable + { + return new ArrayIterator($this->acl); + } + + /** + * @return int + */ + public function count(): int + { + return count($this->acl); + } + + /** + * @param array $acl + * @return array + */ + protected function normalizeAcl(array $acl): array + { + if (empty($acl)) { + return []; + } + + // Normalize access control list. + $list = []; + foreach (Utils::arrayFlattenDotNotation($acl) as $key => $value) { + if (is_bool($value)) { + $list[$key] = $value; + } elseif ($value === 0 || $value === 1) { + $list[$key] = (bool)$value; + } elseif($value === null) { + continue; + } elseif ($this->rules && is_string($value)) { + $list[$key] = $this->resolvePermissions($value); + } elseif (Utils::isPositive($value)) { + $list[$key] = true; + } elseif (Utils::isNegative($value)) { + $list[$key] = false; + } + } + + return $list; + } + + /** + * @param string $access + * @return array + */ + protected function resolvePermissions(string $access): array + { + $len = strlen($access); + $op = true; + $list = []; + for($count = 0; $count < $len; $count++) { + $letter = $access[$count]; + if (isset($this->rules[$letter])) { + $list[$this->rules[$letter]] = $op; + $op = true; + } elseif (isset($this->ops[$letter])) { + $op = $this->ops[$letter]; + } + } + + return $list; + } +} diff --git a/system/src/Grav/Framework/Acl/Action.php b/system/src/Grav/Framework/Acl/Action.php new file mode 100644 index 0000000..a5cfa1a --- /dev/null +++ b/system/src/Grav/Framework/Acl/Action.php @@ -0,0 +1,204 @@ + + */ +class Action implements IteratorAggregate, Countable +{ + /** @var string */ + public $name; + /** @var string */ + public $type; + /** @var bool */ + public $visible; + /** @var string|null */ + public $label; + /** @var array */ + public $params; + + /** @var Action|null */ + protected $parent; + /** @var array */ + protected $children = []; + + /** + * @param string $name + * @param array $action + */ + public function __construct(string $name, array $action = []) + { + $label = $action['label'] ?? null; + if (!$label) { + if ($pos = mb_strrpos($name, '.')) { + $label = mb_substr($name, $pos + 1); + } else { + $label = $name; + } + $label = Inflector::humanize($label, 'all'); + } + + $this->name = $name; + $this->type = $action['type'] ?? 'action'; + $this->visible = (bool)($action['visible'] ?? true); + $this->label = $label; + unset($action['type'], $action['label']); + $this->params = $action; + + // Include compact rules. + if (isset($action['letters'])) { + foreach ($action['letters'] as $letter => $data) { + $data['letter'] = $letter; + $childName = $this->name . '.' . $data['action']; + unset($data['action']); + $child = new Action($childName, $data); + $this->addChild($child); + } + } + } + + /** + * @return array + */ + public function getParams(): array + { + return $this->params; + } + + /** + * @param string $name + * @return mixed|null + */ + public function getParam(string $name) + { + return $this->params[$name] ?? null; + } + + /** + * @return Action|null + */ + public function getParent(): ?Action + { + return $this->parent; + } + + /** + * @param Action|null $parent + * @return void + */ + public function setParent(?Action $parent): void + { + $this->parent = $parent; + } + + /** + * @return string + */ + public function getScope(): string + { + $pos = mb_strpos($this->name, '.'); + if ($pos) { + return mb_substr($this->name, 0, $pos); + } + + return $this->name; + } + + /** + * @return int + */ + public function getLevels(): int + { + return mb_substr_count($this->name, '.'); + } + + /** + * @return bool + */ + public function hasChildren(): bool + { + return !empty($this->children); + } + + /** + * @return Action[] + */ + public function getChildren(): array + { + return $this->children; + } + + /** + * @param string $name + * @return Action|null + */ + public function getChild(string $name): ?Action + { + return $this->children[$name] ?? null; + } + + /** + * @param Action $child + * @return void + */ + public function addChild(Action $child): void + { + if (mb_strpos($child->name, "{$this->name}.") !== 0) { + throw new RuntimeException('Bad child'); + } + + $child->setParent($this); + $name = mb_substr($child->name, mb_strlen($this->name) + 1); + + $this->children[$name] = $child; + } + + /** + * @return Traversable + */ + public function getIterator(): Traversable + { + return new ArrayIterator($this->children); + } + + /** + * @return int + */ + public function count(): int + { + return count($this->children); + } + + /** + * @return array + */ + #[\ReturnTypeWillChange] + public function __debugInfo() + { + return [ + 'name' => $this->name, + 'type' => $this->type, + 'label' => $this->label, + 'params' => $this->params, + 'actions' => $this->children + ]; + } +} diff --git a/system/src/Grav/Framework/Acl/Permissions.php b/system/src/Grav/Framework/Acl/Permissions.php new file mode 100644 index 0000000..a07f7eb --- /dev/null +++ b/system/src/Grav/Framework/Acl/Permissions.php @@ -0,0 +1,249 @@ + + * @implements IteratorAggregate + */ +class Permissions implements ArrayAccess, Countable, IteratorAggregate +{ + /** @var array */ + protected $instances = []; + /** @var array */ + protected $actions = []; + /** @var array */ + protected $nested = []; + /** @var array */ + protected $types = []; + + /** + * @return array + */ + public function getInstances(): array + { + $iterator = new RecursiveActionIterator($this->actions); + $recursive = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST); + + return iterator_to_array($recursive); + } + + /** + * @param string $name + * @return bool + */ + public function hasAction(string $name): bool + { + return isset($this->instances[$name]); + } + + /** + * @param string $name + * @return Action|null + */ + public function getAction(string $name): ?Action + { + return $this->instances[$name] ?? null; + } + + /** + * @param Action $action + * @return void + */ + public function addAction(Action $action): void + { + $name = $action->name; + $parent = $this->getParent($name); + if ($parent) { + $parent->addChild($action); + } else { + $this->actions[$name] = $action; + } + + $this->instances[$name] = $action; + + // If Action has children, add those, too. + foreach ($action->getChildren() as $child) { + $this->instances[$child->name] = $child; + } + } + + /** + * @return array + */ + public function getActions(): array + { + return $this->actions; + } + + /** + * @param Action[] $actions + * @return void + */ + public function addActions(array $actions): void + { + foreach ($actions as $action) { + $this->addAction($action); + } + } + + /** + * @param string $name + * @return bool + */ + public function hasType(string $name): bool + { + return isset($this->types[$name]); + } + + /** + * @param string $name + * @return Action|null + */ + public function getType(string $name): ?Action + { + return $this->types[$name] ?? null; + } + + /** + * @param string $name + * @param array $type + * @return void + */ + public function addType(string $name, array $type): void + { + $this->types[$name] = $type; + } + + /** + * @return array + */ + public function getTypes(): array + { + return $this->types; + } + + /** + * @param array $types + * @return void + */ + public function addTypes(array $types): void + { + $types = array_replace($this->types, $types); + + $this->types = $types; + } + + /** + * @param array|null $access + * @return Access + */ + public function getAccess(array $access = null): Access + { + return new Access($access ?? []); + } + + /** + * @param int|string $offset + * @return bool + */ + public function offsetExists($offset): bool + { + return isset($this->nested[$offset]); + } + + /** + * @param int|string $offset + * @return Action|null + */ + public function offsetGet($offset): ?Action + { + return $this->nested[$offset] ?? null; + } + + /** + * @param int|string $offset + * @param mixed $value + * @return void + */ + public function offsetSet($offset, $value): void + { + throw new RuntimeException(__METHOD__ . '(): Not Supported'); + } + + /** + * @param int|string $offset + * @return void + */ + public function offsetUnset($offset): void + { + throw new RuntimeException(__METHOD__ . '(): Not Supported'); + } + + /** + * @return int + */ + public function count(): int + { + return count($this->actions); + } + + /** + * @return ArrayIterator|Traversable + */ + #[\ReturnTypeWillChange] + public function getIterator() + { + return new ArrayIterator($this->actions); + } + + /** + * @return array + */ + #[\ReturnTypeWillChange] + public function __debugInfo() + { + return [ + 'actions' => $this->actions + ]; + } + + /** + * @param string $name + * @return Action|null + */ + protected function getParent(string $name): ?Action + { + if ($pos = strrpos($name, '.')) { + $parentName = substr($name, 0, $pos); + + $parent = $this->getAction($parentName); + if (!$parent) { + $parent = new Action($parentName); + $this->addAction($parent); + } + + return $parent; + } + + return null; + } +} diff --git a/system/src/Grav/Framework/Acl/PermissionsReader.php b/system/src/Grav/Framework/Acl/PermissionsReader.php new file mode 100644 index 0000000..0560361 --- /dev/null +++ b/system/src/Grav/Framework/Acl/PermissionsReader.php @@ -0,0 +1,186 @@ +content(); + $actions = $content['actions'] ?? []; + $types = $content['types'] ?? []; + + return static::fromArray($actions, $types); + } + + /** + * @param array $actions + * @param array $types + * @return Action[] + */ + public static function fromArray(array $actions, array $types): array + { + static::initTypes($types); + + $list = []; + foreach (static::read($actions) as $type => $data) { + $list[$type] = new Action($type, $data); + } + + return $list; + } + + /** + * @param array $actions + * @param string $prefix + * @return array + */ + public static function read(array $actions, string $prefix = ''): array + { + $list = []; + foreach ($actions as $name => $action) { + $prefixName = $prefix . $name; + $list[$prefixName] = null; + + // Support nested sets of actions. + if (isset($action['actions']) && is_array($action['actions'])) { + $innerList = static::read($action['actions'], "{$prefixName}."); + + $list += $innerList; + } + + unset($action['actions']); + + // Add defaults if they exist. + $action = static::addDefaults($action); + + // Build flat list of actions. + $list[$prefixName] = $action; + } + + return $list; + } + + /** + * @param array $types + * @return void + */ + protected static function initTypes(array $types) + { + static::$types = []; + + $dependencies = []; + foreach ($types as $type => $defaults) { + $current = array_fill_keys((array)($defaults['use'] ?? null), null); + $defType = $defaults['type'] ?? $type; + if ($type !== $defType) { + $current[$defaults['type']] = null; + } + + $dependencies[$type] = (object)$current; + } + + // Build dependency tree. + foreach ($dependencies as $type => $dep) { + foreach (get_object_vars($dep) as $k => &$val) { + if (null === $val) { + $val = $dependencies[$k] ?? new stdClass(); + } + } + unset($val); + } + + $encoded = json_encode($dependencies); + if ($encoded === false) { + throw new RuntimeException('json_encode(): failed to encode dependencies'); + } + $dependencies = json_decode($encoded, true); + + foreach (static::getDependencies($dependencies) as $type) { + $defaults = $types[$type] ?? null; + if ($defaults) { + static::$types[$type] = static::addDefaults($defaults); + } + } + } + + /** + * @param array $dependencies + * @return array + */ + protected static function getDependencies(array $dependencies): array + { + $list = [[]]; + foreach ($dependencies as $name => $deps) { + $current = $deps ? static::getDependencies($deps) : []; + $current[] = $name; + + $list[] = $current; + } + + return array_unique(array_merge(...$list)); + } + + /** + * @param array $action + * @return array + */ + protected static function addDefaults(array $action): array + { + $scopes = []; + + // Add used properties. + $use = (array)($action['use'] ?? null); + foreach ($use as $type) { + if (isset(static::$types[$type])) { + $used = static::$types[$type]; + unset($used['type']); + $scopes[] = $used; + } + } + unset($action['use']); + + // Add type defaults. + $type = $action['type'] ?? 'default'; + $defaults = static::$types[$type] ?? null; + if (is_array($defaults)) { + $scopes[] = $defaults; + } + + if ($scopes) { + $scopes[] = $action; + + $action = array_replace_recursive(...$scopes); + + $newType = $defaults['type'] ?? null; + if ($newType && $newType !== $type) { + $action['type'] = $newType; + } + } + + return $action; + } +} diff --git a/system/src/Grav/Framework/Acl/RecursiveActionIterator.php b/system/src/Grav/Framework/Acl/RecursiveActionIterator.php new file mode 100644 index 0000000..3c38612 --- /dev/null +++ b/system/src/Grav/Framework/Acl/RecursiveActionIterator.php @@ -0,0 +1,64 @@ + + */ +class RecursiveActionIterator implements RecursiveIterator, \Countable +{ + use Constructor, Iterator, Countable; + + public $items; + + /** + * @see \Iterator::key() + * @return string + */ + #[\ReturnTypeWillChange] + public function key() + { + /** @var Action $current */ + $current = $this->current(); + + return $current->name; + } + + /** + * @see \RecursiveIterator::hasChildren() + * @return bool + */ + public function hasChildren(): bool + { + /** @var Action $current */ + $current = $this->current(); + + return $current->hasChildren(); + } + + /** + * @see \RecursiveIterator::getChildren() + * @return RecursiveActionIterator + */ + public function getChildren(): self + { + /** @var Action $current */ + $current = $this->current(); + + return new static($current->getChildren()); + } +} diff --git a/system/src/Grav/Framework/Cache/AbstractCache.php b/system/src/Grav/Framework/Cache/AbstractCache.php new file mode 100644 index 0000000..1a3fadc --- /dev/null +++ b/system/src/Grav/Framework/Cache/AbstractCache.php @@ -0,0 +1,32 @@ +init($namespace, $defaultLifetime); + } +} diff --git a/system/src/Grav/Framework/Cache/Adapter/ChainCache.php b/system/src/Grav/Framework/Cache/Adapter/ChainCache.php new file mode 100644 index 0000000..2957841 --- /dev/null +++ b/system/src/Grav/Framework/Cache/Adapter/ChainCache.php @@ -0,0 +1,210 @@ +getMessage(), $e->getCode(), $e); + } + + if (!$caches) { + throw new InvalidArgumentException('At least one cache must be specified'); + } + + foreach ($caches as $cache) { + if (!$cache instanceof CacheInterface) { + throw new InvalidArgumentException( + sprintf( + "The class '%s' does not implement the '%s' interface", + get_class($cache), + CacheInterface::class + ) + ); + } + } + + $this->caches = array_values($caches); + $this->count = count($caches); + } + + /** + * @inheritdoc + */ + public function doGet($key, $miss) + { + foreach ($this->caches as $i => $cache) { + $value = $cache->doGet($key, $miss); + if ($value !== $miss) { + while (--$i >= 0) { + // Update all the previous caches with missing value. + $this->caches[$i]->doSet($key, $value, $this->getDefaultLifetime()); + } + + return $value; + } + } + + return $miss; + } + + /** + * @inheritdoc + */ + public function doSet($key, $value, $ttl) + { + $success = true; + $i = $this->count; + + while ($i--) { + $success = $this->caches[$i]->doSet($key, $value, $ttl) && $success; + } + + return $success; + } + + /** + * @inheritdoc + */ + public function doDelete($key) + { + $success = true; + $i = $this->count; + + while ($i--) { + $success = $this->caches[$i]->doDelete($key) && $success; + } + + return $success; + } + + /** + * @inheritdoc + */ + public function doClear() + { + $success = true; + $i = $this->count; + + while ($i--) { + $success = $this->caches[$i]->doClear() && $success; + } + + return $success; + } + + /** + * @inheritdoc + */ + public function doGetMultiple($keys, $miss) + { + $list = []; + /** + * @var int $i + * @var CacheInterface $cache + */ + foreach ($this->caches as $i => $cache) { + $list[$i] = $cache->doGetMultiple($keys, $miss); + + $keys = array_diff_key($keys, $list[$i]); + + if (!$keys) { + break; + } + } + + // Update all the previous caches with missing values. + $values = []; + /** + * @var int $i + * @var CacheInterface $items + */ + foreach (array_reverse($list) as $i => $items) { + $values += $items; + if ($i && $values) { + $this->caches[$i-1]->doSetMultiple($values, $this->getDefaultLifetime()); + } + } + + return $values; + } + + /** + * @inheritdoc + */ + public function doSetMultiple($values, $ttl) + { + $success = true; + $i = $this->count; + + while ($i--) { + $success = $this->caches[$i]->doSetMultiple($values, $ttl) && $success; + } + + return $success; + } + + /** + * @inheritdoc + */ + public function doDeleteMultiple($keys) + { + $success = true; + $i = $this->count; + + while ($i--) { + $success = $this->caches[$i]->doDeleteMultiple($keys) && $success; + } + + return $success; + } + + /** + * @inheritdoc + */ + public function doHas($key) + { + foreach ($this->caches as $cache) { + if ($cache->doHas($key)) { + return true; + } + } + + return false; + } +} diff --git a/system/src/Grav/Framework/Cache/Adapter/DoctrineCache.php b/system/src/Grav/Framework/Cache/Adapter/DoctrineCache.php new file mode 100644 index 0000000..14117de --- /dev/null +++ b/system/src/Grav/Framework/Cache/Adapter/DoctrineCache.php @@ -0,0 +1,118 @@ +getMessage(), $e->getCode(), $e); + } + + // Set namespace to Doctrine Cache provider if it was given. + $namespace = $this->getNamespace(); + if ($namespace) { + $doctrineCache->setNamespace($namespace); + } + + $this->driver = $doctrineCache; + } + + /** + * @inheritdoc + */ + public function doGet($key, $miss) + { + $value = $this->driver->fetch($key); + + // Doctrine cache does not differentiate between no result and cached 'false'. Make sure that we do. + return $value !== false || $this->driver->contains($key) ? $value : $miss; + } + + /** + * @inheritdoc + */ + public function doSet($key, $value, $ttl) + { + return $this->driver->save($key, $value, (int) $ttl); + } + + /** + * @inheritdoc + */ + public function doDelete($key) + { + return $this->driver->delete($key); + } + + /** + * @inheritdoc + */ + public function doClear() + { + return $this->driver->deleteAll(); + } + + /** + * @inheritdoc + */ + public function doGetMultiple($keys, $miss) + { + return $this->driver->fetchMultiple($keys); + } + + /** + * @inheritdoc + */ + public function doSetMultiple($values, $ttl) + { + return $this->driver->saveMultiple($values, (int) $ttl); + } + + /** + * @inheritdoc + */ + public function doDeleteMultiple($keys) + { + return $this->driver->deleteMultiple($keys); + } + + /** + * @inheritdoc + */ + public function doHas($key) + { + return $this->driver->contains($key); + } +} diff --git a/system/src/Grav/Framework/Cache/Adapter/FileCache.php b/system/src/Grav/Framework/Cache/Adapter/FileCache.php new file mode 100644 index 0000000..d2058d5 --- /dev/null +++ b/system/src/Grav/Framework/Cache/Adapter/FileCache.php @@ -0,0 +1,266 @@ +initFileCache($namespace, $folder ?? ''); + } catch (\Psr\SimpleCache\InvalidArgumentException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + } + + /** + * @inheritdoc + */ + public function doGet($key, $miss) + { + $now = time(); + $file = $this->getFile($key); + + if (!file_exists($file) || !$h = @fopen($file, 'rb')) { + return $miss; + } + + if ($now >= (int) $expiresAt = fgets($h)) { + fclose($h); + @unlink($file); + } else { + $i = rawurldecode(rtrim((string)fgets($h))); + $value = stream_get_contents($h) ?: ''; + fclose($h); + + if ($i === $key) { + return unserialize($value, ['allowed_classes' => true]); + } + } + + return $miss; + } + + /** + * @inheritdoc + * @throws CacheException + */ + public function doSet($key, $value, $ttl) + { + $expiresAt = time() + (int)$ttl; + + $result = $this->write( + $this->getFile($key, true), + $expiresAt . "\n" . rawurlencode($key) . "\n" . serialize($value), + $expiresAt + ); + + if (!$result && !is_writable($this->directory)) { + throw new CacheException(sprintf('Cache directory is not writable (%s)', $this->directory)); + } + + return $result; + } + + /** + * @inheritdoc + */ + public function doDelete($key) + { + $file = $this->getFile($key); + + $result = false; + if (file_exists($file)) { + $result = @unlink($file); + $result &= !file_exists($file); + } + + return $result; + } + + /** + * @inheritdoc + */ + public function doClear() + { + $result = true; + $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->directory, FilesystemIterator::SKIP_DOTS)); + + foreach ($iterator as $file) { + $result = ($file->isDir() || @unlink($file) || !file_exists($file)) && $result; + } + + return $result; + } + + /** + * @inheritdoc + */ + public function doHas($key) + { + $file = $this->getFile($key); + + return file_exists($file) && (@filemtime($file) > time() || $this->doGet($key, null)); + } + + /** + * @param string $key + * @param bool $mkdir + * @return string + */ + protected function getFile($key, $mkdir = false) + { + $hash = str_replace('/', '-', base64_encode(hash('sha256', static::class . $key, true))); + $dir = $this->directory . $hash[0] . DIRECTORY_SEPARATOR . $hash[1] . DIRECTORY_SEPARATOR; + + if ($mkdir) { + $this->mkdir($dir); + } + + return $dir . substr($hash, 2, 20); + } + + /** + * @param string $namespace + * @param string $directory + * @return void + * @throws InvalidArgumentException + */ + protected function initFileCache($namespace, $directory) + { + if ($directory === '') { + $directory = sys_get_temp_dir() . '/grav-cache'; + } else { + $directory = realpath($directory) ?: $directory; + } + + if (isset($namespace[0])) { + if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) { + throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0])); + } + $directory .= DIRECTORY_SEPARATOR . $namespace; + } + + $this->mkdir($directory); + + $directory .= DIRECTORY_SEPARATOR; + // On Windows the whole path is limited to 258 chars + if ('\\' === DIRECTORY_SEPARATOR && strlen($directory) > 234) { + throw new InvalidArgumentException(sprintf('Cache folder is too long (%s)', $directory)); + } + $this->directory = $directory; + } + + /** + * @param string $file + * @param string $data + * @param int|null $expiresAt + * @return bool + */ + private function write($file, $data, $expiresAt = null) + { + set_error_handler(__CLASS__.'::throwError'); + + try { + if ($this->tmp === null) { + $this->tmp = $this->directory . uniqid('', true); + } + + file_put_contents($this->tmp, $data); + + if ($expiresAt !== null) { + touch($this->tmp, $expiresAt); + } + + return rename($this->tmp, $file); + } finally { + restore_error_handler(); + } + } + + /** + * @param string $dir + * @return void + * @throws RuntimeException + */ + private function mkdir($dir) + { + // Silence error for open_basedir; should fail in mkdir instead. + if (@is_dir($dir)) { + return; + } + + $success = @mkdir($dir, 0777, true); + + if (!$success) { + // Take yet another look, make sure that the folder doesn't exist. + clearstatcache(true, $dir); + if (!@is_dir($dir)) { + throw new RuntimeException(sprintf('Unable to create directory: %s', $dir)); + } + } + } + + /** + * @param int $type + * @param string $message + * @param string $file + * @param int $line + * @return bool + * @internal + * @throws ErrorException + */ + public static function throwError($type, $message, $file, $line) + { + throw new ErrorException($message, 0, $type, $file, $line); + } + + /** + * @return void + */ + #[\ReturnTypeWillChange] + public function __destruct() + { + if ($this->tmp !== null && file_exists($this->tmp)) { + unlink($this->tmp); + } + } +} diff --git a/system/src/Grav/Framework/Cache/Adapter/MemoryCache.php b/system/src/Grav/Framework/Cache/Adapter/MemoryCache.php new file mode 100644 index 0000000..6196368 --- /dev/null +++ b/system/src/Grav/Framework/Cache/Adapter/MemoryCache.php @@ -0,0 +1,83 @@ +cache)) { + return $miss; + } + + return $this->cache[$key]; + } + + /** + * @param string $key + * @param mixed $value + * @param int $ttl + * @return bool + */ + public function doSet($key, $value, $ttl) + { + $this->cache[$key] = $value; + + return true; + } + + /** + * @param string $key + * @return bool + */ + public function doDelete($key) + { + unset($this->cache[$key]); + + return true; + } + + /** + * @return bool + */ + public function doClear() + { + $this->cache = []; + + return true; + } + + /** + * @param string $key + * @return bool + */ + public function doHas($key) + { + return array_key_exists($key, $this->cache); + } +} diff --git a/system/src/Grav/Framework/Cache/Adapter/SessionCache.php b/system/src/Grav/Framework/Cache/Adapter/SessionCache.php new file mode 100644 index 0000000..7159685 --- /dev/null +++ b/system/src/Grav/Framework/Cache/Adapter/SessionCache.php @@ -0,0 +1,107 @@ +doGetStored($key); + + return $stored ? $stored[self::VALUE] : $miss; + } + + /** + * @param string $key + * @param mixed $value + * @param int $ttl + * @return bool + */ + public function doSet($key, $value, $ttl) + { + $stored = [self::VALUE => $value]; + if (null !== $ttl) { + $stored[self::LIFETIME] = time() + $ttl; + } + + $_SESSION[$this->getNamespace()][$key] = $stored; + + return true; + } + + /** + * @param string $key + * @return bool + */ + public function doDelete($key) + { + unset($_SESSION[$this->getNamespace()][$key]); + + return true; + } + + /** + * @return bool + */ + public function doClear() + { + unset($_SESSION[$this->getNamespace()]); + + return true; + } + + /** + * @param string $key + * @return bool + */ + public function doHas($key) + { + return $this->doGetStored($key) !== null; + } + + /** + * @return string + */ + public function getNamespace() + { + return 'cache-' . parent::getNamespace(); + } + + /** + * @param string $key + * @return mixed|null + */ + protected function doGetStored($key) + { + $stored = $_SESSION[$this->getNamespace()][$key] ?? null; + + if (isset($stored[self::LIFETIME]) && $stored[self::LIFETIME] < time()) { + unset($_SESSION[$this->getNamespace()][$key]); + $stored = null; + } + + return $stored ?: null; + } +} diff --git a/system/src/Grav/Framework/Cache/CacheInterface.php b/system/src/Grav/Framework/Cache/CacheInterface.php new file mode 100644 index 0000000..c095f3d --- /dev/null +++ b/system/src/Grav/Framework/Cache/CacheInterface.php @@ -0,0 +1,71 @@ + $values + * @param int|null $ttl + * @return mixed + */ + public function doSetMultiple($values, $ttl); + + /** + * @param string[] $keys + * @return mixed + */ + public function doDeleteMultiple($keys); + + /** + * @param string $key + * @return mixed + */ + public function doHas($key); +} diff --git a/system/src/Grav/Framework/Cache/CacheTrait.php b/system/src/Grav/Framework/Cache/CacheTrait.php new file mode 100644 index 0000000..f7eeb04 --- /dev/null +++ b/system/src/Grav/Framework/Cache/CacheTrait.php @@ -0,0 +1,373 @@ +namespace = (string) $namespace; + $this->defaultLifetime = $this->convertTtl($defaultLifetime); + $this->miss = new stdClass; + } + + /** + * @param bool $validation + * @return void + */ + public function setValidation($validation) + { + $this->validation = (bool) $validation; + } + + /** + * @return string + */ + protected function getNamespace() + { + return $this->namespace; + } + + /** + * @return int|null + */ + protected function getDefaultLifetime() + { + return $this->defaultLifetime; + } + + /** + * @param string $key + * @param mixed|null $default + * @return mixed|null + * @throws InvalidArgumentException + */ + public function get($key, $default = null) + { + $this->validateKey($key); + + $value = $this->doGet($key, $this->miss); + + return $value !== $this->miss ? $value : $default; + } + + /** + * @param string $key + * @param mixed $value + * @param null|int|DateInterval $ttl + * @return bool + * @throws InvalidArgumentException + */ + public function set($key, $value, $ttl = null) + { + $this->validateKey($key); + + $ttl = $this->convertTtl($ttl); + + // If a negative or zero TTL is provided, the item MUST be deleted from the cache. + return null !== $ttl && $ttl <= 0 ? $this->doDelete($key) : $this->doSet($key, $value, $ttl); + } + + /** + * @param string $key + * @return bool + * @throws InvalidArgumentException + */ + public function delete($key) + { + $this->validateKey($key); + + return $this->doDelete($key); + } + + /** + * @return bool + */ + public function clear() + { + return $this->doClear(); + } + + /** + * @param iterable $keys + * @param mixed|null $default + * @return iterable + * @throws InvalidArgumentException + */ + public function getMultiple($keys, $default = null) + { + if ($keys instanceof Traversable) { + $keys = iterator_to_array($keys, false); + } elseif (!is_array($keys)) { + $isObject = is_object($keys); + throw new InvalidArgumentException( + sprintf( + 'Cache keys must be array or Traversable, "%s" given', + $isObject ? get_class($keys) : gettype($keys) + ) + ); + } + + if (empty($keys)) { + return []; + } + + $this->validateKeys($keys); + $keys = array_unique($keys); + $keys = array_combine($keys, $keys); + + $list = $this->doGetMultiple($keys, $this->miss); + + // Make sure that values are returned in the same order as the keys were given. + $values = []; + foreach ($keys as $key) { + if (!array_key_exists($key, $list) || $list[$key] === $this->miss) { + $values[$key] = $default; + } else { + $values[$key] = $list[$key]; + } + } + + return $values; + } + + /** + * @param iterable $values + * @param null|int|DateInterval $ttl + * @return bool + * @throws InvalidArgumentException + */ + public function setMultiple($values, $ttl = null) + { + if ($values instanceof Traversable) { + $values = iterator_to_array($values, true); + } elseif (!is_array($values)) { + $isObject = is_object($values); + throw new InvalidArgumentException( + sprintf( + 'Cache values must be array or Traversable, "%s" given', + $isObject ? get_class($values) : gettype($values) + ) + ); + } + + $keys = array_keys($values); + + if (empty($keys)) { + return true; + } + + $this->validateKeys($keys); + + $ttl = $this->convertTtl($ttl); + + // If a negative or zero TTL is provided, the item MUST be deleted from the cache. + return null !== $ttl && $ttl <= 0 ? $this->doDeleteMultiple($keys) : $this->doSetMultiple($values, $ttl); + } + + /** + * @param iterable $keys + * @return bool + * @throws InvalidArgumentException + */ + public function deleteMultiple($keys) + { + if ($keys instanceof Traversable) { + $keys = iterator_to_array($keys, false); + } elseif (!is_array($keys)) { + $isObject = is_object($keys); + throw new InvalidArgumentException( + sprintf( + 'Cache keys must be array or Traversable, "%s" given', + $isObject ? get_class($keys) : gettype($keys) + ) + ); + } + + if (empty($keys)) { + return true; + } + + $this->validateKeys($keys); + + return $this->doDeleteMultiple($keys); + } + + /** + * @param string $key + * @return bool + * @throws InvalidArgumentException + */ + public function has($key) + { + $this->validateKey($key); + + return $this->doHas($key); + } + + /** + * @param array $keys + * @param mixed $miss + * @return array + */ + public function doGetMultiple($keys, $miss) + { + $results = []; + + foreach ($keys as $key) { + $value = $this->doGet($key, $miss); + if ($value !== $miss) { + $results[$key] = $value; + } + } + + return $results; + } + + /** + * @param array $values + * @param int|null $ttl + * @return bool + */ + public function doSetMultiple($values, $ttl) + { + $success = true; + + foreach ($values as $key => $value) { + $success = $this->doSet($key, $value, $ttl) && $success; + } + + return $success; + } + + /** + * @param array $keys + * @return bool + */ + public function doDeleteMultiple($keys) + { + $success = true; + + foreach ($keys as $key) { + $success = $this->doDelete($key) && $success; + } + + return $success; + } + + /** + * @param string|mixed $key + * @return void + * @throws InvalidArgumentException + */ + protected function validateKey($key) + { + if (!is_string($key)) { + throw new InvalidArgumentException( + sprintf( + 'Cache key must be string, "%s" given', + is_object($key) ? get_class($key) : gettype($key) + ) + ); + } + if (!isset($key[0])) { + throw new InvalidArgumentException('Cache key length must be greater than zero'); + } + if (strlen($key) > 64) { + throw new InvalidArgumentException( + sprintf('Cache key length must be less than 65 characters, key had %d characters', strlen($key)) + ); + } + if (strpbrk($key, '{}()/\@:') !== false) { + throw new InvalidArgumentException( + sprintf('Cache key "%s" contains reserved characters {}()/\@:', $key) + ); + } + } + + /** + * @param array $keys + * @return void + * @throws InvalidArgumentException + */ + protected function validateKeys($keys) + { + if (!$this->validation) { + return; + } + + foreach ($keys as $key) { + $this->validateKey($key); + } + } + + /** + * @param null|int|DateInterval $ttl + * @return int|null + * @throws InvalidArgumentException + */ + protected function convertTtl($ttl) + { + if ($ttl === null) { + return $this->getDefaultLifetime(); + } + + if (is_int($ttl)) { + return $ttl; + } + + if ($ttl instanceof DateInterval) { + $date = DateTime::createFromFormat('U', '0'); + $ttl = $date ? (int)$date->add($ttl)->format('U') : 0; + } + + throw new InvalidArgumentException( + sprintf( + 'Expiration date must be an integer, a DateInterval or null, "%s" given', + is_object($ttl) ? get_class($ttl) : gettype($ttl) + ) + ); + } +} diff --git a/system/src/Grav/Framework/Cache/Exception/CacheException.php b/system/src/Grav/Framework/Cache/Exception/CacheException.php new file mode 100644 index 0000000..4c4b8b9 --- /dev/null +++ b/system/src/Grav/Framework/Cache/Exception/CacheException.php @@ -0,0 +1,21 @@ + + * @implements FileCollectionInterface + */ +class AbstractFileCollection extends AbstractLazyCollection implements FileCollectionInterface +{ + /** @var string */ + protected $path; + /** @var RecursiveDirectoryIterator|RecursiveUniformResourceIterator */ + protected $iterator; + /** @var callable */ + protected $createObjectFunction; + /** @var callable|null */ + protected $filterFunction; + /** @var int */ + protected $flags; + /** @var int */ + protected $nestingLimit; + + /** + * @param string $path + */ + protected function __construct($path) + { + $this->path = $path; + $this->flags = self::INCLUDE_FILES | self::INCLUDE_FOLDERS; + $this->nestingLimit = 0; + $this->createObjectFunction = [$this, 'createObject']; + + $this->setIterator(); + } + + /** + * @return string + */ + public function getPath() + { + return $this->path; + } + + /** + * @param Criteria $criteria + * @return ArrayCollection + * @phpstan-return ArrayCollection + * @todo Implement lazy matching + */ + public function matching(Criteria $criteria) + { + $expr = $criteria->getWhereExpression(); + + $oldFilter = $this->filterFunction; + if ($expr) { + $visitor = new ClosureExpressionVisitor(); + $filter = $visitor->dispatch($expr); + $this->addFilter($filter); + } + + $filtered = $this->doInitializeByIterator($this->iterator, $this->nestingLimit); + $this->filterFunction = $oldFilter; + + if ($orderings = $criteria->getOrderings()) { + $next = null; + /** + * @var string $field + * @var string $ordering + */ + foreach (array_reverse($orderings) as $field => $ordering) { + $next = ClosureExpressionVisitor::sortByField($field, $ordering === Criteria::DESC ? -1 : 1, $next); + } + /** @phpstan-ignore-next-line */ + if (null === $next) { + throw new RuntimeException('Criteria is missing orderings'); + } + + uasort($filtered, $next); + } else { + ksort($filtered); + } + + $offset = $criteria->getFirstResult(); + $length = $criteria->getMaxResults(); + + if ($offset || $length) { + $filtered = array_slice($filtered, (int)$offset, $length); + } + + return new ArrayCollection($filtered); + } + + /** + * @return void + */ + protected function setIterator() + { + $iteratorFlags = RecursiveDirectoryIterator::SKIP_DOTS + FilesystemIterator::UNIX_PATHS + + FilesystemIterator::CURRENT_AS_SELF + FilesystemIterator::FOLLOW_SYMLINKS; + + if (strpos($this->path, '://')) { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $this->iterator = $locator->getRecursiveIterator($this->path, $iteratorFlags); + } else { + $this->iterator = new RecursiveDirectoryIterator($this->path, $iteratorFlags); + } + } + + /** + * @param callable $filterFunction + * @return $this + */ + protected function addFilter(callable $filterFunction) + { + if ($this->filterFunction) { + $oldFilterFunction = $this->filterFunction; + $this->filterFunction = function ($expr) use ($oldFilterFunction, $filterFunction) { + return $oldFilterFunction($expr) && $filterFunction($expr); + }; + } else { + $this->filterFunction = $filterFunction; + } + + return $this; + } + + /** + * {@inheritDoc} + */ + protected function doInitialize() + { + $filtered = $this->doInitializeByIterator($this->iterator, $this->nestingLimit); + ksort($filtered); + + $this->collection = new ArrayCollection($filtered); + } + + /** + * @param SeekableIterator $iterator + * @param int $nestingLimit + * @return array + * @phpstan-param SeekableIterator $iterator + */ + protected function doInitializeByIterator(SeekableIterator $iterator, $nestingLimit) + { + $children = []; + $objects = []; + $filter = $this->filterFunction; + $objectFunction = $this->createObjectFunction; + + /** @var RecursiveDirectoryIterator $file */ + foreach ($iterator as $file) { + // Skip files if they shouldn't be included. + if (!($this->flags & static::INCLUDE_FILES) && $file->isFile()) { + continue; + } + + // Apply main filter. + if ($filter && !$filter($file)) { + continue; + } + + // Include children if the recursive flag is set. + if (($this->flags & static::RECURSIVE) && $nestingLimit > 0 && $file->hasChildren()) { + $children[] = $file->getChildren(); + } + + // Skip folders if they shouldn't be included. + if (!($this->flags & static::INCLUDE_FOLDERS) && $file->isDir()) { + continue; + } + + $object = $objectFunction($file); + $objects[$object->key] = $object; + } + + if ($children) { + $objects += $this->doInitializeChildren($children, $nestingLimit - 1); + } + + return $objects; + } + + /** + * @param array $children + * @param int $nestingLimit + * @return array + */ + protected function doInitializeChildren(array $children, $nestingLimit) + { + $objects = []; + foreach ($children as $iterator) { + $objects += $this->doInitializeByIterator($iterator, $nestingLimit); + } + + return $objects; + } + + /** + * @param RecursiveDirectoryIterator $file + * @return object + */ + protected function createObject($file) + { + return (object) [ + 'key' => $file->getSubPathname(), + 'type' => $file->isDir() ? 'folder' : 'file:' . $file->getExtension(), + 'url' => method_exists($file, 'getUrl') ? $file->getUrl() : null, + 'pathname' => $file->getPathname(), + 'mtime' => $file->getMTime() + ]; + } +} diff --git a/system/src/Grav/Framework/Collection/AbstractIndexCollection.php b/system/src/Grav/Framework/Collection/AbstractIndexCollection.php new file mode 100644 index 0000000..1c2da8c --- /dev/null +++ b/system/src/Grav/Framework/Collection/AbstractIndexCollection.php @@ -0,0 +1,574 @@ + + */ +abstract class AbstractIndexCollection implements CollectionInterface +{ + use Serializable; + + /** + * @var array + * @phpstan-var array + */ + private $entries; + + /** + * Initializes a new IndexCollection. + * + * @param array $entries + * @phpstan-param array $entries + */ + public function __construct(array $entries = []) + { + $this->entries = $entries; + } + + /** + * {@inheritDoc} + */ + public function toArray() + { + return $this->loadElements($this->entries); + } + + /** + * {@inheritDoc} + */ + public function first() + { + $value = reset($this->entries); + $key = (string)key($this->entries); + + return $this->loadElement($key, $value); + } + + /** + * {@inheritDoc} + */ + public function last() + { + $value = end($this->entries); + $key = (string)key($this->entries); + + return $this->loadElement($key, $value); + } + + /** + * {@inheritDoc} + */ + #[\ReturnTypeWillChange] + public function key() + { + /** @phpstan-var TKey */ + return (string)key($this->entries); + } + + /** + * {@inheritDoc} + */ + #[\ReturnTypeWillChange] + public function next() + { + $value = next($this->entries); + $key = (string)key($this->entries); + + return $this->loadElement($key, $value); + } + + /** + * {@inheritDoc} + */ + #[\ReturnTypeWillChange] + public function current() + { + $value = current($this->entries); + $key = (string)key($this->entries); + + return $this->loadElement($key, $value); + } + + /** + * {@inheritDoc} + */ + public function remove($key) + { + if (!array_key_exists($key, $this->entries)) { + return null; + } + + $value = $this->entries[$key]; + unset($this->entries[$key]); + + return $this->loadElement((string)$key, $value); + } + + /** + * {@inheritDoc} + */ + public function removeElement($element) + { + $key = $this->isAllowedElement($element) ? $this->getCurrentKey($element) : null; + + if (null !== $key || !isset($this->entries[$key])) { + return false; + } + + unset($this->entries[$key]); + + return true; + } + + /** + * Required by interface ArrayAccess. + * + * @param string|int|null $offset + * @return bool + * @phpstan-param TKey|null $offset + */ + #[\ReturnTypeWillChange] + public function offsetExists($offset) + { + /** @phpstan-ignore-next-line phpstan bug? */ + return $offset !== null ? $this->containsKey($offset) : false; + } + + /** + * Required by interface ArrayAccess. + * + * @param string|int|null $offset + * @return mixed + * @phpstan-param TKey|null $offset + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + /** @phpstan-ignore-next-line phpstan bug? */ + return $offset !== null ? $this->get($offset) : null; + } + + /** + * Required by interface ArrayAccess. + * + * @param string|int|null $offset + * @param mixed $value + * @return void + * @phpstan-param TKey|null $offset + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + if (null === $offset) { + $this->add($value); + } else { + /** @phpstan-ignore-next-line phpstan bug? */ + $this->set($offset, $value); + } + } + + /** + * Required by interface ArrayAccess. + * + * @param string|int|null $offset + * @return void + * @phpstan-param TKey|null $offset + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + if ($offset !== null) { + /** @phpstan-ignore-next-line phpstan bug? */ + $this->remove($offset); + } + } + + /** + * {@inheritDoc} + */ + public function containsKey($key) + { + return isset($this->entries[$key]) || array_key_exists($key, $this->entries); + } + + /** + * {@inheritDoc} + */ + public function contains($element) + { + $key = $this->isAllowedElement($element) ? $this->getCurrentKey($element) : null; + + return $key && isset($this->entries[$key]); + } + + /** + * {@inheritDoc} + */ + public function exists(Closure $p) + { + return $this->loadCollection($this->entries)->exists($p); + } + + /** + * {@inheritDoc} + */ + public function indexOf($element) + { + $key = $this->isAllowedElement($element) ? $this->getCurrentKey($element) : null; + + return $key && isset($this->entries[$key]) ? $key : false; + } + + /** + * {@inheritDoc} + */ + public function get($key) + { + if (!isset($this->entries[$key])) { + return null; + } + + return $this->loadElement((string)$key, $this->entries[$key]); + } + + /** + * {@inheritDoc} + */ + public function getKeys() + { + return array_keys($this->entries); + } + + /** + * {@inheritDoc} + */ + public function getValues() + { + return array_values($this->loadElements($this->entries)); + } + + /** + * {@inheritDoc} + */ + #[\ReturnTypeWillChange] + public function count() + { + return count($this->entries); + } + + /** + * {@inheritDoc} + */ + public function set($key, $value) + { + if (!$this->isAllowedElement($value)) { + throw new InvalidArgumentException('Invalid argument $value'); + } + + $this->entries[$key] = $this->getElementMeta($value); + } + + /** + * {@inheritDoc} + */ + public function add($element) + { + if (!$this->isAllowedElement($element)) { + throw new InvalidArgumentException('Invalid argument $element'); + } + + $this->entries[$this->getCurrentKey($element)] = $this->getElementMeta($element); + + return true; + } + + /** + * {@inheritDoc} + */ + public function isEmpty() + { + return empty($this->entries); + } + + /** + * Required by interface IteratorAggregate. + * + * {@inheritDoc} + * @phpstan-return Iterator + */ + #[\ReturnTypeWillChange] + public function getIterator() + { + return new ArrayIterator($this->loadElements()); + } + + /** + * {@inheritDoc} + */ + public function map(Closure $func) + { + return $this->loadCollection($this->entries)->map($func); + } + + /** + * {@inheritDoc} + */ + public function filter(Closure $p) + { + return $this->loadCollection($this->entries)->filter($p); + } + + /** + * {@inheritDoc} + */ + public function forAll(Closure $p) + { + return $this->loadCollection($this->entries)->forAll($p); + } + + /** + * {@inheritDoc} + */ + public function partition(Closure $p) + { + return $this->loadCollection($this->entries)->partition($p); + } + + /** + * Returns a string representation of this object. + * + * @return string + */ + #[\ReturnTypeWillChange] + public function __toString() + { + return __CLASS__ . '@' . spl_object_hash($this); + } + + /** + * {@inheritDoc} + */ + public function clear() + { + $this->entries = []; + } + + /** + * {@inheritDoc} + */ + public function slice($offset, $length = null) + { + return $this->loadElements(array_slice($this->entries, $offset, $length, true)); + } + + /** + * @param int $start + * @param int|null $limit + * @return static + * @phpstan-return static + */ + public function limit($start, $limit = null) + { + return $this->createFrom(array_slice($this->entries, $start, $limit, true)); + } + + /** + * Reverse the order of the items. + * + * @return static + * @phpstan-return static + */ + public function reverse() + { + return $this->createFrom(array_reverse($this->entries)); + } + + /** + * Shuffle items. + * + * @return static + * @phpstan-return static + */ + public function shuffle() + { + $keys = $this->getKeys(); + shuffle($keys); + + return $this->createFrom(array_replace(array_flip($keys), $this->entries)); + } + + /** + * Select items from collection. + * + * Collection is returned in the order of $keys given to the function. + * + * @param array $keys + * @return static + * @phpstan-return static + */ + public function select(array $keys) + { + $list = []; + foreach ($keys as $key) { + if (isset($this->entries[$key])) { + $list[$key] = $this->entries[$key]; + } + } + + return $this->createFrom($list); + } + + /** + * Un-select items from collection. + * + * @param array $keys + * @return static + * @phpstan-return static + */ + public function unselect(array $keys) + { + return $this->select(array_diff($this->getKeys(), $keys)); + } + + /** + * Split collection into chunks. + * + * @param int $size Size of each chunk. + * @return array + * @phpstan-return array> + */ + public function chunk($size) + { + /** @phpstan-var array> */ + return $this->loadCollection($this->entries)->chunk($size); + } + + /** + * @return array + */ + public function __serialize(): array + { + return [ + 'entries' => $this->entries + ]; + } + + /** + * @param array $data + * @return void + */ + public function __unserialize(array $data): void + { + $this->entries = $data['entries']; + } + + /** + * Implements JsonSerializable interface. + * + * @return array + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return $this->loadCollection()->jsonSerialize(); + } + + /** + * Creates a new instance from the specified elements. + * + * This method is provided for derived classes to specify how a new + * instance should be created when constructor semantics have changed. + * + * @param array $entries Elements. + * @return static + * @phpstan-return static + */ + protected function createFrom(array $entries) + { + return new static($entries); + } + + /** + * @return array + */ + protected function getEntries(): array + { + return $this->entries; + } + + /** + * @param array $entries + * @return void + * @phpstan-param array $entries + */ + protected function setEntries(array $entries): void + { + $this->entries = $entries; + } + + /** + * @param FlexObjectInterface $element + * @return string + * @phpstan-param T $element + * @phpstan-return TKey + */ + protected function getCurrentKey($element) + { + return $element->getKey(); + } + + /** + * @param string $key + * @param mixed $value + * @return mixed|null + */ + abstract protected function loadElement($key, $value); + + /** + * @param array|null $entries + * @return array + * @phpstan-return array + */ + abstract protected function loadElements(array $entries = null): array; + + /** + * @param array|null $entries + * @return CollectionInterface + * @phpstan-return C + */ + abstract protected function loadCollection(array $entries = null): CollectionInterface; + + /** + * @param mixed $value + * @return bool + */ + abstract protected function isAllowedElement($value): bool; + + /** + * @param mixed $element + * @return mixed + */ + abstract protected function getElementMeta($element); +} diff --git a/system/src/Grav/Framework/Collection/AbstractLazyCollection.php b/system/src/Grav/Framework/Collection/AbstractLazyCollection.php new file mode 100644 index 0000000..806939c --- /dev/null +++ b/system/src/Grav/Framework/Collection/AbstractLazyCollection.php @@ -0,0 +1,97 @@ + + * @implements CollectionInterface + */ +abstract class AbstractLazyCollection extends BaseAbstractLazyCollection implements CollectionInterface +{ + /** + * @par ArrayCollection + * @phpstan-var ArrayCollection + */ + protected $collection; + + /** + * {@inheritDoc} + * @phpstan-return ArrayCollection + */ + public function reverse() + { + $this->initialize(); + + return $this->collection->reverse(); + } + + /** + * {@inheritDoc} + * @phpstan-return ArrayCollection + */ + public function shuffle() + { + $this->initialize(); + + return $this->collection->shuffle(); + } + + /** + * {@inheritDoc} + */ + public function chunk($size) + { + $this->initialize(); + + return $this->collection->chunk($size); + } + + /** + * {@inheritDoc} + * @phpstan-param array $keys + * @phpstan-return ArrayCollection + */ + public function select(array $keys) + { + $this->initialize(); + + return $this->collection->select($keys); + } + + /** + * {@inheritDoc} + * @phpstan-param array $keys + * @phpstan-return ArrayCollection + */ + public function unselect(array $keys) + { + $this->initialize(); + + return $this->collection->unselect($keys); + } + + /** + * @return array + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + $this->initialize(); + + return $this->collection->jsonSerialize(); + } +} diff --git a/system/src/Grav/Framework/Collection/ArrayCollection.php b/system/src/Grav/Framework/Collection/ArrayCollection.php new file mode 100644 index 0000000..7d8c7ac --- /dev/null +++ b/system/src/Grav/Framework/Collection/ArrayCollection.php @@ -0,0 +1,117 @@ + + * @implements CollectionInterface + */ +class ArrayCollection extends BaseArrayCollection implements CollectionInterface +{ + /** + * Reverse the order of the items. + * + * @return static + * @phpstan-return static + */ + public function reverse() + { + $keys = array_reverse($this->toArray()); + + /** @phpstan-var static */ + return $this->createFrom($keys); + } + + /** + * Shuffle items. + * + * @return static + * @phpstan-return static + */ + public function shuffle() + { + $keys = $this->getKeys(); + shuffle($keys); + $keys = array_replace(array_flip($keys), $this->toArray()); + + /** @phpstan-var static */ + return $this->createFrom($keys); + } + + /** + * Split collection into chunks. + * + * @param int $size Size of each chunk. + * @return array + * @phpstan-return array> + */ + public function chunk($size) + { + /** @phpstan-var array> */ + return array_chunk($this->toArray(), $size, true); + } + + /** + * Select items from collection. + * + * Collection is returned in the order of $keys given to the function. + * + * @param array $keys + * @return static + * @phpstan-param TKey[] $keys + * @phpstan-return static + */ + public function select(array $keys) + { + $list = []; + foreach ($keys as $key) { + if ($this->containsKey($key)) { + $list[$key] = $this->get($key); + } + } + + /** @phpstan-var static */ + return $this->createFrom($list); + } + + /** + * Un-select items from collection. + * + * @param array $keys + * @return static + * @phpstan-param TKey[] $keys + * @phpstan-return static + */ + public function unselect(array $keys) + { + $list = array_diff($this->getKeys(), $keys); + + /** @phpstan-var static */ + return $this->select($list); + } + + /** + * Implements JsonSerializable interface. + * + * @return array + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return $this->toArray(); + } +} diff --git a/system/src/Grav/Framework/Collection/CollectionInterface.php b/system/src/Grav/Framework/Collection/CollectionInterface.php new file mode 100644 index 0000000..d112057 --- /dev/null +++ b/system/src/Grav/Framework/Collection/CollectionInterface.php @@ -0,0 +1,69 @@ + + */ +interface CollectionInterface extends Collection, JsonSerializable +{ + /** + * Reverse the order of the items. + * + * @return CollectionInterface + * @phpstan-return static + */ + public function reverse(); + + /** + * Shuffle items. + * + * @return CollectionInterface + * @phpstan-return static + */ + public function shuffle(); + + /** + * Split collection into chunks. + * + * @param int $size Size of each chunk. + * @return array + * @phpstan-return array> + */ + public function chunk($size); + + /** + * Select items from collection. + * + * Collection is returned in the order of $keys given to the function. + * + * @param array $keys + * @return CollectionInterface + * @phpstan-return static + */ + public function select(array $keys); + + /** + * Un-select items from collection. + * + * @param array $keys + * @return CollectionInterface + * @phpstan-return static + */ + public function unselect(array $keys); +} diff --git a/system/src/Grav/Framework/Collection/FileCollection.php b/system/src/Grav/Framework/Collection/FileCollection.php new file mode 100644 index 0000000..8fe254d --- /dev/null +++ b/system/src/Grav/Framework/Collection/FileCollection.php @@ -0,0 +1,97 @@ + + */ +class FileCollection extends AbstractFileCollection +{ + /** + * @param string $path + * @param int $flags + */ + public function __construct($path, $flags = null) + { + parent::__construct($path); + + $this->flags = (int)($flags ?: self::INCLUDE_FILES | self::INCLUDE_FOLDERS | self::RECURSIVE); + + $this->setIterator(); + $this->setFilter(); + $this->setObjectBuilder(); + $this->setNestingLimit(); + } + + /** + * @return int + */ + public function getFlags() + { + return $this->flags; + } + + /** + * @return int + */ + public function getNestingLimit() + { + return $this->nestingLimit; + } + + /** + * @param int $limit + * @return $this + */ + public function setNestingLimit($limit = 99) + { + $this->nestingLimit = (int) $limit; + + return $this; + } + + /** + * @param callable|null $filterFunction + * @return $this + */ + public function setFilter(callable $filterFunction = null) + { + $this->filterFunction = $filterFunction; + + return $this; + } + + /** + * @param callable $filterFunction + * @return $this + */ + public function addFilter(callable $filterFunction) + { + parent::addFilter($filterFunction); + + return $this; + } + + /** + * @param callable|null $objectFunction + * @return $this + */ + public function setObjectBuilder(callable $objectFunction = null) + { + $this->createObjectFunction = $objectFunction ?: [$this, 'createObject']; + + return $this; + } +} diff --git a/system/src/Grav/Framework/Collection/FileCollectionInterface.php b/system/src/Grav/Framework/Collection/FileCollectionInterface.php new file mode 100644 index 0000000..92ac164 --- /dev/null +++ b/system/src/Grav/Framework/Collection/FileCollectionInterface.php @@ -0,0 +1,33 @@ + + * @extends Selectable + */ +interface FileCollectionInterface extends CollectionInterface, Selectable +{ + public const INCLUDE_FILES = 1; + public const INCLUDE_FOLDERS = 2; + public const RECURSIVE = 4; + + /** + * @return string + */ + public function getPath(); +} diff --git a/system/src/Grav/Framework/Compat/Serializable.php b/system/src/Grav/Framework/Compat/Serializable.php new file mode 100644 index 0000000..a060fef --- /dev/null +++ b/system/src/Grav/Framework/Compat/Serializable.php @@ -0,0 +1,47 @@ +__serialize()); + } + + /** + * @param string $serialized + * @return void + */ + final public function unserialize($serialized): void + { + $this->__unserialize(unserialize($serialized, ['allowed_classes' => $this->getUnserializeAllowedClasses()])); + } + + /** + * @return array|bool + */ + protected function getUnserializeAllowedClasses() + { + return false; + } +} diff --git a/system/src/Grav/Framework/ContentBlock/ContentBlock.php b/system/src/Grav/Framework/ContentBlock/ContentBlock.php new file mode 100644 index 0000000..3ba8abe --- /dev/null +++ b/system/src/Grav/Framework/ContentBlock/ContentBlock.php @@ -0,0 +1,303 @@ +setContent('my inner content'); + * $outerBlock = ContentBlock::create(); + * $outerBlock->setContent(sprintf('Inside my outer block I have %s.', $innerBlock->getToken())); + * $outerBlock->addBlock($innerBlock); + * echo $outerBlock; + * + * @package Grav\Framework\ContentBlock + */ +class ContentBlock implements ContentBlockInterface +{ + use Serializable; + + /** @var int */ + protected $version = 1; + /** @var string */ + protected $id; + /** @var string */ + protected $tokenTemplate = '@@BLOCK-%s@@'; + /** @var string */ + protected $content = ''; + /** @var array */ + protected $blocks = []; + /** @var string */ + protected $checksum; + /** @var bool */ + protected $cached = true; + + /** + * @param string|null $id + * @return static + */ + public static function create($id = null) + { + return new static($id); + } + + /** + * @param array $serialized + * @return ContentBlockInterface + * @throws InvalidArgumentException + */ + public static function fromArray(array $serialized) + { + try { + $type = $serialized['_type'] ?? null; + $id = $serialized['id'] ?? null; + + if (!$type || !$id || !is_a($type, ContentBlockInterface::class, true)) { + throw new InvalidArgumentException('Bad data'); + } + + /** @var ContentBlockInterface $instance */ + $instance = new $type($id); + $instance->build($serialized); + } catch (Exception $e) { + throw new InvalidArgumentException(sprintf('Cannot unserialize Block: %s', $e->getMessage()), $e->getCode(), $e); + } + + return $instance; + } + + /** + * Block constructor. + * + * @param string|null $id + */ + public function __construct($id = null) + { + $this->id = $id ? (string) $id : $this->generateId(); + } + + /** + * @return string + */ + public function getId() + { + return $this->id; + } + + /** + * @return string + */ + public function getToken() + { + return sprintf($this->tokenTemplate, $this->getId()); + } + + /** + * @return array + */ + public function toArray() + { + $blocks = []; + /** @var ContentBlockInterface $block */ + foreach ($this->blocks as $block) { + $blocks[$block->getId()] = $block->toArray(); + } + + $array = [ + '_type' => get_class($this), + '_version' => $this->version, + 'id' => $this->id, + 'cached' => $this->cached + ]; + + if ($this->checksum) { + $array['checksum'] = $this->checksum; + } + + if ($this->content) { + $array['content'] = $this->content; + } + + if ($blocks) { + $array['blocks'] = $blocks; + } + + return $array; + } + + /** + * @return string + */ + public function toString() + { + if (!$this->blocks) { + return (string) $this->content; + } + + $tokens = []; + $replacements = []; + foreach ($this->blocks as $block) { + $tokens[] = $block->getToken(); + $replacements[] = $block->toString(); + } + + return str_replace($tokens, $replacements, (string) $this->content); + } + + /** + * @return string + */ + #[\ReturnTypeWillChange] + public function __toString() + { + try { + return $this->toString(); + } catch (Exception $e) { + return sprintf('Error while rendering block: %s', $e->getMessage()); + } + } + + /** + * @param array $serialized + * @return void + * @throws RuntimeException + */ + public function build(array $serialized) + { + $this->checkVersion($serialized); + + $this->id = $serialized['id'] ?? $this->generateId(); + $this->checksum = $serialized['checksum'] ?? null; + $this->cached = $serialized['cached'] ?? null; + + if (isset($serialized['content'])) { + $this->setContent($serialized['content']); + } + + $blocks = isset($serialized['blocks']) ? (array) $serialized['blocks'] : []; + foreach ($blocks as $block) { + $this->addBlock(self::fromArray($block)); + } + } + + /** + * @return bool + */ + public function isCached() + { + if (!$this->cached) { + return false; + } + + foreach ($this->blocks as $block) { + if (!$block->isCached()) { + return false; + } + } + + return true; + } + + /** + * @return $this + */ + public function disableCache() + { + $this->cached = false; + + return $this; + } + + /** + * @param string $checksum + * @return $this + */ + public function setChecksum($checksum) + { + $this->checksum = $checksum; + + return $this; + } + + /** + * @return string + */ + public function getChecksum() + { + return $this->checksum; + } + + /** + * @param string $content + * @return $this + */ + public function setContent($content) + { + $this->content = $content; + + return $this; + } + + /** + * @param ContentBlockInterface $block + * @return $this + */ + public function addBlock(ContentBlockInterface $block) + { + $this->blocks[$block->getId()] = $block; + + return $this; + } + + /** + * @return array + */ + final public function __serialize(): array + { + return $this->toArray(); + } + + /** + * @param array $data + * @return void + */ + final public function __unserialize(array $data): void + { + $this->build($data); + } + + /** + * @return string + */ + protected function generateId() + { + return uniqid('', true); + } + + /** + * @param array $serialized + * @return void + * @throws RuntimeException + */ + protected function checkVersion(array $serialized) + { + $version = isset($serialized['_version']) ? (int) $serialized['_version'] : 1; + if ($version !== $this->version) { + throw new RuntimeException(sprintf('Unsupported version %s', $version)); + } + } +} diff --git a/system/src/Grav/Framework/ContentBlock/ContentBlockInterface.php b/system/src/Grav/Framework/ContentBlock/ContentBlockInterface.php new file mode 100644 index 0000000..0a18cd0 --- /dev/null +++ b/system/src/Grav/Framework/ContentBlock/ContentBlockInterface.php @@ -0,0 +1,90 @@ +getAssetsFast(); + + $this->sortAssets($assets['styles']); + $this->sortAssets($assets['scripts']); + $this->sortAssets($assets['links']); + $this->sortAssets($assets['html']); + + return $assets; + } + + /** + * @return array + */ + public function getFrameworks() + { + $assets = $this->getAssetsFast(); + + return array_keys($assets['frameworks']); + } + + /** + * @param string $location + * @return array + */ + public function getStyles($location = 'head') + { + return $this->getAssetsInLocation('styles', $location); + } + + /** + * @param string $location + * @return array + */ + public function getScripts($location = 'head') + { + return $this->getAssetsInLocation('scripts', $location); + } + + /** + * @param string $location + * @return array + */ + public function getLinks($location = 'head') + { + return $this->getAssetsInLocation('links', $location); + } + + /** + * @param string $location + * @return array + */ + public function getHtml($location = 'bottom') + { + return $this->getAssetsInLocation('html', $location); + } + + /** + * @return array + */ + public function toArray() + { + $array = parent::toArray(); + + if ($this->frameworks) { + $array['frameworks'] = $this->frameworks; + } + if ($this->styles) { + $array['styles'] = $this->styles; + } + if ($this->scripts) { + $array['scripts'] = $this->scripts; + } + if ($this->links) { + $array['links'] = $this->links; + } + if ($this->html) { + $array['html'] = $this->html; + } + + return $array; + } + + /** + * @param array $serialized + * @return void + * @throws RuntimeException + */ + public function build(array $serialized) + { + parent::build($serialized); + + $this->frameworks = isset($serialized['frameworks']) ? (array) $serialized['frameworks'] : []; + $this->styles = isset($serialized['styles']) ? (array) $serialized['styles'] : []; + $this->scripts = isset($serialized['scripts']) ? (array) $serialized['scripts'] : []; + $this->links = isset($serialized['links']) ? (array) $serialized['links'] : []; + $this->html = isset($serialized['html']) ? (array) $serialized['html'] : []; + } + + /** + * @param string $framework + * @return $this + */ + public function addFramework($framework) + { + $this->frameworks[$framework] = 1; + + return $this; + } + + /** + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + * + * @example $block->addStyle('assets/js/my.js'); + * @example $block->addStyle(['href' => 'assets/js/my.js', 'media' => 'screen']); + */ + public function addStyle($element, $priority = 0, $location = 'head') + { + if (!is_array($element)) { + $element = ['href' => (string) $element]; + } + if (empty($element['href'])) { + return false; + } + if (!isset($this->styles[$location])) { + $this->styles[$location] = []; + } + + $id = !empty($element['id']) ? ['id' => (string) $element['id']] : []; + $href = $element['href']; + $type = !empty($element['type']) ? (string) $element['type'] : 'text/css'; + $media = !empty($element['media']) ? (string) $element['media'] : null; + unset( + $element['tag'], + $element['id'], + $element['rel'], + $element['content'], + $element['href'], + $element['type'], + $element['media'] + ); + + $this->styles[$location][md5($href) . sha1($href)] = [ + ':type' => 'file', + ':priority' => (int) $priority, + 'href' => $href, + 'type' => $type, + 'media' => $media, + 'element' => $element + ] + $id; + + return true; + } + + /** + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addInlineStyle($element, $priority = 0, $location = 'head') + { + if (!is_array($element)) { + $element = ['content' => (string) $element]; + } + if (empty($element['content'])) { + return false; + } + if (!isset($this->styles[$location])) { + $this->styles[$location] = []; + } + + $content = (string) $element['content']; + $type = !empty($element['type']) ? (string) $element['type'] : 'text/css'; + + unset($element['content'], $element['type']); + + $this->styles[$location][md5($content) . sha1($content)] = [ + ':type' => 'inline', + ':priority' => (int) $priority, + 'content' => $content, + 'type' => $type, + 'element' => $element + ]; + + return true; + } + + /** + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addScript($element, $priority = 0, $location = 'head') + { + if (!is_array($element)) { + $element = ['src' => (string) $element]; + } + if (empty($element['src'])) { + return false; + } + if (!isset($this->scripts[$location])) { + $this->scripts[$location] = []; + } + + $src = $element['src']; + $type = !empty($element['type']) ? (string) $element['type'] : 'text/javascript'; + $loading = !empty($element['loading']) ? (string) $element['loading'] : null; + $defer = !empty($element['defer']); + $async = !empty($element['async']); + $handle = !empty($element['handle']) ? (string) $element['handle'] : ''; + + unset($element['src'], $element['type'], $element['loading'], $element['defer'], $element['async'], $element['handle']); + + $this->scripts[$location][md5($src) . sha1($src)] = [ + ':type' => 'file', + ':priority' => (int) $priority, + 'src' => $src, + 'type' => $type, + 'loading' => $loading, + 'defer' => $defer, + 'async' => $async, + 'handle' => $handle, + 'element' => $element + ]; + + return true; + } + + /** + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addInlineScript($element, $priority = 0, $location = 'head') + { + if (!is_array($element)) { + $element = ['content' => (string) $element]; + } + if (empty($element['content'])) { + return false; + } + if (!isset($this->scripts[$location])) { + $this->scripts[$location] = []; + } + + $content = (string) $element['content']; + $type = !empty($element['type']) ? (string) $element['type'] : 'text/javascript'; + $loading = !empty($element['loading']) ? (string) $element['loading'] : null; + + unset($element['content'], $element['type'], $element['loading']); + + $this->scripts[$location][md5($content) . sha1($content)] = [ + ':type' => 'inline', + ':priority' => (int) $priority, + 'content' => $content, + 'type' => $type, + 'loading' => $loading, + 'element' => $element + ]; + + return true; + } + + /** + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addModule($element, $priority = 0, $location = 'head') + { + if (!is_array($element)) { + $element = ['src' => (string) $element]; + } + + $element['type'] = 'module'; + + return $this->addScript($element, $priority, $location); + } + + /** + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addInlineModule($element, $priority = 0, $location = 'head') + { + if (!is_array($element)) { + $element = ['content' => (string) $element]; + } + + $element['type'] = 'module'; + + return $this->addInlineScript($element, $priority, $location); + } + + /** + * @param array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addLink($element, $priority = 0, $location = 'head') + { + if (!is_array($element) || empty($element['rel']) || empty($element['href'])) { + return false; + } + + if (!isset($this->links[$location])) { + $this->links[$location] = []; + } + + $rel = (string) $element['rel']; + $href = (string) $element['href']; + + unset($element['rel'], $element['href']); + + $this->links[$location][md5($href) . sha1($href)] = [ + ':type' => 'file', + ':priority' => (int) $priority, + 'href' => $href, + 'rel' => $rel, + 'element' => $element, + ]; + + return true; + } + + /** + * @param string $html + * @param int $priority + * @param string $location + * @return bool + */ + public function addHtml($html, $priority = 0, $location = 'bottom') + { + if (empty($html) || !is_string($html)) { + return false; + } + if (!isset($this->html[$location])) { + $this->html[$location] = []; + } + + $this->html[$location][md5($html) . sha1($html)] = [ + ':priority' => (int) $priority, + 'html' => $html + ]; + + return true; + } + + /** + * @return array + */ + protected function getAssetsFast() + { + $assets = [ + 'frameworks' => $this->frameworks, + 'styles' => $this->styles, + 'scripts' => $this->scripts, + 'links' => $this->links, + 'html' => $this->html + ]; + + foreach ($this->blocks as $block) { + if ($block instanceof self) { + $blockAssets = $block->getAssetsFast(); + $assets['frameworks'] += $blockAssets['frameworks']; + + foreach ($blockAssets['styles'] as $location => $styles) { + if (!isset($assets['styles'][$location])) { + $assets['styles'][$location] = $styles; + } elseif ($styles) { + $assets['styles'][$location] += $styles; + } + } + + foreach ($blockAssets['scripts'] as $location => $scripts) { + if (!isset($assets['scripts'][$location])) { + $assets['scripts'][$location] = $scripts; + } elseif ($scripts) { + $assets['scripts'][$location] += $scripts; + } + } + + foreach ($blockAssets['links'] as $location => $links) { + if (!isset($assets['links'][$location])) { + $assets['links'][$location] = $links; + } elseif ($links) { + $assets['links'][$location] += $links; + } + } + + foreach ($blockAssets['html'] as $location => $htmls) { + if (!isset($assets['html'][$location])) { + $assets['html'][$location] = $htmls; + } elseif ($htmls) { + $assets['html'][$location] += $htmls; + } + } + } + } + + return $assets; + } + + /** + * @param string $type + * @param string $location + * @return array + */ + protected function getAssetsInLocation($type, $location) + { + $assets = $this->getAssetsFast(); + + if (empty($assets[$type][$location])) { + return []; + } + + $styles = $assets[$type][$location]; + $this->sortAssetsInLocation($styles); + + return $styles; + } + + /** + * @param array $items + * @return void + */ + protected function sortAssetsInLocation(array &$items) + { + $count = 0; + foreach ($items as &$item) { + $item[':order'] = ++$count; + } + unset($item); + + uasort( + $items, + static function ($a, $b) { + return $a[':priority'] <=> $b[':priority'] ?: $a[':order'] <=> $b[':order']; + } + ); + } + + /** + * @param array $array + * @return void + */ + protected function sortAssets(array &$array) + { + foreach ($array as &$items) { + $this->sortAssetsInLocation($items); + } + } +} diff --git a/system/src/Grav/Framework/ContentBlock/HtmlBlockInterface.php b/system/src/Grav/Framework/ContentBlock/HtmlBlockInterface.php new file mode 100644 index 0000000..f619607 --- /dev/null +++ b/system/src/Grav/Framework/ContentBlock/HtmlBlockInterface.php @@ -0,0 +1,130 @@ +addStyle('assets/js/my.js'); + * @example $block->addStyle(['href' => 'assets/js/my.js', 'media' => 'screen']); + */ + public function addStyle($element, $priority = 0, $location = 'head'); + + /** + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addInlineStyle($element, $priority = 0, $location = 'head'); + + /** + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addScript($element, $priority = 0, $location = 'head'); + + /** + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addInlineScript($element, $priority = 0, $location = 'head'); + + + /** + * Shortcut for writing addScript(['type' => 'module', 'src' => ...]). + * + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addModule($element, $priority = 0, $location = 'head'); + + /** + * Shortcut for writing addInlineScript(['type' => 'module', 'content' => ...]). + * + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addInlineModule($element, $priority = 0, $location = 'head'); + + /** + * @param array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addLink($element, $priority = 0, $location = 'head'); + + /** + * @param string $html + * @param int $priority + * @param string $location + * @return bool + */ + public function addHtml($html, $priority = 0, $location = 'bottom'); +} diff --git a/system/src/Grav/Framework/Contracts/Media/MediaObjectInterface.php b/system/src/Grav/Framework/Contracts/Media/MediaObjectInterface.php new file mode 100644 index 0000000..75b80f0 --- /dev/null +++ b/system/src/Grav/Framework/Contracts/Media/MediaObjectInterface.php @@ -0,0 +1,52 @@ +|ArrayAccess + * @phpstan-pure + */ + public function getIdentifierMeta(); +} diff --git a/system/src/Grav/Framework/Contracts/Relationships/RelationshipInterface.php b/system/src/Grav/Framework/Contracts/Relationships/RelationshipInterface.php new file mode 100644 index 0000000..c0a7edf --- /dev/null +++ b/system/src/Grav/Framework/Contracts/Relationships/RelationshipInterface.php @@ -0,0 +1,81 @@ + + */ +interface RelationshipInterface extends Countable, IteratorAggregate, JsonSerializable, Serializable +{ + /** + * @return string + * @phpstan-pure + */ + public function getName(): string; + + /** + * @return string + * @phpstan-pure + */ + public function getType(): string; + + /** + * @return bool + * @phpstan-pure + */ + public function isModified(): bool; + + /** + * @return string + * @phpstan-pure + */ + public function getCardinality(): string; + + /** + * @return P + * @phpstan-pure + */ + public function getParent(): IdentifierInterface; + + /** + * @param string $id + * @param string|null $type + * @return bool + * @phpstan-pure + */ + public function has(string $id, string $type = null): bool; + + /** + * @param T $identifier + * @return bool + * @phpstan-pure + */ + public function hasIdentifier(IdentifierInterface $identifier): bool; + + /** + * @param T $identifier + * @return bool + */ + public function addIdentifier(IdentifierInterface $identifier): bool; + + /** + * @param T|null $identifier + * @return bool + */ + public function removeIdentifier(IdentifierInterface $identifier = null): bool; + + /** + * @return iterable + */ + public function getIterator(): iterable; +} diff --git a/system/src/Grav/Framework/Contracts/Relationships/RelationshipsInterface.php b/system/src/Grav/Framework/Contracts/Relationships/RelationshipsInterface.php new file mode 100644 index 0000000..4bd90a3 --- /dev/null +++ b/system/src/Grav/Framework/Contracts/Relationships/RelationshipsInterface.php @@ -0,0 +1,53 @@ +> + * @extends Iterator> + */ +interface RelationshipsInterface extends Countable, ArrayAccess, Iterator, JsonSerializable +{ + /** + * @return bool + * @phpstan-pure + */ + public function isModified(): bool; + + /** + * @return array + */ + public function getModified(): array; + + /** + * @return int + * @phpstan-pure + */ + public function count(): int; + + /** + * @param string $offset + * @return RelationshipInterface|null + */ + public function offsetGet($offset): ?RelationshipInterface; + + /** + * @return RelationshipInterface|null + */ + public function current(): ?RelationshipInterface; + + /** + * @return string + * @phpstan-pure + */ + public function key(): string; +} diff --git a/system/src/Grav/Framework/Contracts/Relationships/ToManyRelationshipInterface.php b/system/src/Grav/Framework/Contracts/Relationships/ToManyRelationshipInterface.php new file mode 100644 index 0000000..723bef6 --- /dev/null +++ b/system/src/Grav/Framework/Contracts/Relationships/ToManyRelationshipInterface.php @@ -0,0 +1,55 @@ + + */ +interface ToManyRelationshipInterface extends RelationshipInterface +{ + /** + * @param positive-int $pos + * @return IdentifierInterface|null + */ + public function getNthIdentifier(int $pos): ?IdentifierInterface; + + /** + * @param string $id + * @param string|null $type + * @return T|null + * @phpstan-pure + */ + public function getIdentifier(string $id, string $type = null): ?IdentifierInterface; + + /** + * @param string $id + * @param string|null $type + * @return T|null + * @phpstan-pure + */ + public function getObject(string $id, string $type = null): ?object; + + /** + * @param iterable $identifiers + * @return bool + */ + public function addIdentifiers(iterable $identifiers): bool; + + /** + * @param iterable $identifiers + * @return bool + */ + public function replaceIdentifiers(iterable $identifiers): bool; + + /** + * @param iterable $identifiers + * @return bool + */ + public function removeIdentifiers(iterable $identifiers): bool; +} diff --git a/system/src/Grav/Framework/Contracts/Relationships/ToOneRelationshipInterface.php b/system/src/Grav/Framework/Contracts/Relationships/ToOneRelationshipInterface.php new file mode 100644 index 0000000..0e6aeb9 --- /dev/null +++ b/system/src/Grav/Framework/Contracts/Relationships/ToOneRelationshipInterface.php @@ -0,0 +1,37 @@ + + */ +interface ToOneRelationshipInterface extends RelationshipInterface +{ + /** + * @param string|null $id + * @param string|null $type + * @return T|null + * @phpstan-pure + */ + public function getIdentifier(string $id = null, string $type = null): ?IdentifierInterface; + + /** + * @param string|null $id + * @param string|null $type + * @return T|null + * @phpstan-pure + */ + public function getObject(string $id = null, string $type = null): ?object; + + /** + * @param T|null $identifier + * @return bool + */ + public function replaceIdentifier(IdentifierInterface $identifier = null): bool; +} diff --git a/system/src/Grav/Framework/Controller/Traits/ControllerResponseTrait.php b/system/src/Grav/Framework/Controller/Traits/ControllerResponseTrait.php new file mode 100644 index 0000000..0840283 --- /dev/null +++ b/system/src/Grav/Framework/Controller/Traits/ControllerResponseTrait.php @@ -0,0 +1,307 @@ + 599) { + $code = 500; + } + $headers = $headers ?? []; + + return new Response($code, $headers, $content); + } + + /** + * @param array $content + * @param int|null $code + * @param array|null $headers + * @return Response + */ + protected function createJsonResponse(array $content, int $code = null, array $headers = null): ResponseInterface + { + $code = $code ?? $content['code'] ?? 200; + if (null === $code || $code < 100 || $code > 599) { + $code = 200; + } + $headers = ($headers ?? []) + [ + 'Content-Type' => 'application/json', + 'Cache-Control' => 'no-store, max-age=0' + ]; + + return new Response($code, $headers, json_encode($content)); + } + + /** + * @param string $filename + * @param string|resource|StreamInterface $resource + * @param array|null $headers + * @param array|null $options + * @return ResponseInterface + */ + protected function createDownloadResponse(string $filename, $resource, array $headers = null, array $options = null): ResponseInterface + { + // Required for IE, otherwise Content-Disposition may be ignored + if (ini_get('zlib.output_compression')) { + @ini_set('zlib.output_compression', 'Off'); + } + + $headers = $headers ?? []; + $options = $options ?? ['force_download' => true]; + + $file_parts = Utils::pathinfo($filename); + + if (!isset($headers['Content-Type'])) { + $mimetype = Utils::getMimeByExtension($file_parts['extension']); + + $headers['Content-Type'] = $mimetype; + } + + // TODO: add multipart download support. + //$headers['Accept-Ranges'] = 'bytes'; + + if (!empty($options['force_download'])) { + $headers['Content-Disposition'] = 'attachment; filename="' . $file_parts['basename'] . '"'; + } + + if (!isset($headers['Content-Length'])) { + $realpath = realpath($filename); + if ($realpath) { + $headers['Content-Length'] = filesize($realpath); + } + } + + $headers += [ + 'Expires' => 'Mon, 26 Jul 1997 05:00:00 GMT', + 'Last-Modified' => gmdate('D, d M Y H:i:s') . ' GMT', + 'Cache-Control' => 'no-store, no-cache, must-revalidate', + 'Pragma' => 'no-cache' + ]; + + return new Response(200, $headers, $resource); + } + + /** + * @param string $url + * @param int|null $code + * @return Response + */ + protected function createRedirectResponse(string $url, int $code = null): ResponseInterface + { + if (null === $code || $code < 301 || $code > 307) { + $code = (int)$this->getConfig()->get('system.pages.redirect_default_code', 302); + } + + $ext = Utils::pathinfo($url, PATHINFO_EXTENSION); + $accept = $this->getAccept(['application/json', 'text/html']); + if ($ext === 'json' || $accept === 'application/json') { + return $this->createJsonResponse(['code' => $code, 'status' => 'redirect', 'redirect' => $url]); + } + + return new Response($code, ['Location' => $url]); + } + + /** + * @param Throwable $e + * @return ResponseInterface + */ + protected function createErrorResponse(Throwable $e): ResponseInterface + { + $response = $this->getErrorJson($e); + $message = $response['message']; + $code = $response['code']; + $reason = $e instanceof RequestException ? $e->getHttpReason() : null; + $accept = $this->getAccept(['application/json', 'text/html']); + + $request = $this->getRequest(); + $context = $request->getAttributes(); + + /** @var Route $route */ + $route = $context['route'] ?? null; + + $ext = $route ? $route->getExtension() : null; + if ($ext !== 'json' && $accept === 'text/html') { + $method = $request->getMethod(); + + // On POST etc, redirect back to the previous page. + if ($method !== 'GET' && $method !== 'HEAD') { + $this->setMessage($message, 'error'); + $referer = $request->getHeaderLine('Referer'); + + return $this->createRedirectResponse($referer, 303); + } + + // TODO: improve error page + return $this->createHtmlResponse($response['message'], $code); + } + + return new Response($code, ['Content-Type' => 'application/json'], json_encode($response), '1.1', $reason); + } + + /** + * @param Throwable $e + * @return ResponseInterface + */ + protected function createJsonErrorResponse(Throwable $e): ResponseInterface + { + $response = $this->getErrorJson($e); + $reason = $e instanceof RequestException ? $e->getHttpReason() : null; + + return new Response($response['code'], ['Content-Type' => 'application/json'], json_encode($response), '1.1', $reason); + } + + /** + * @param Throwable $e + * @return array + */ + protected function getErrorJson(Throwable $e): array + { + $code = $this->getErrorCode($e instanceof RequestException ? $e->getHttpCode() : $e->getCode()); + if ($e instanceof ValidationException) { + $message = $e->getMessage(); + } else { + $message = htmlspecialchars($e->getMessage(), ENT_QUOTES | ENT_HTML5, 'UTF-8'); + } + + $extra = $e instanceof JsonSerializable ? $e->jsonSerialize() : []; + + $response = [ + 'code' => $code, + 'status' => 'error', + 'message' => $message, + 'redirect' => null, + 'error' => [ + 'code' => $code, + 'message' => $message + ] + $extra + ]; + + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + if ($debugger->enabled()) { + $response['error'] += [ + 'type' => get_class($e), + 'file' => $e->getFile(), + 'line' => $e->getLine(), + 'trace' => explode("\n", $e->getTraceAsString()) + ]; + } + + return $response; + } + + /** + * @param int $code + * @return int + */ + protected function getErrorCode(int $code): int + { + static $errorCodes = [ + 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, + 422, 423, 424, 425, 426, 428, 429, 431, 451, 500, 501, 502, 503, 504, 505, 506, 507, 508, 511 + ]; + + if (!in_array($code, $errorCodes, true)) { + $code = 500; + } + + return $code; + } + + /** + * @param array $compare + * @return mixed + */ + protected function getAccept(array $compare) + { + $accepted = []; + foreach ($this->getRequest()->getHeader('Accept') as $accept) { + foreach (explode(',', $accept) as $item) { + if (!$item) { + continue; + } + + $split = explode(';q=', $item); + $mime = array_shift($split); + $priority = array_shift($split) ?? 1.0; + + $accepted[$mime] = $priority; + } + } + + arsort($accepted); + + // TODO: add support for image/* etc + $list = array_intersect($compare, array_keys($accepted)); + if (!$list && (isset($accepted['*/*']) || isset($accepted['*']))) { + return reset($compare); + } + + return reset($list); + } + + /** + * @return ServerRequestInterface + */ + abstract protected function getRequest(): ServerRequestInterface; + + /** + * @param string $message + * @param string $type + * @return $this + */ + abstract protected function setMessage(string $message, string $type = 'info'); + + /** + * @return Config + */ + abstract protected function getConfig(): Config; +} diff --git a/system/src/Grav/Framework/DI/Container.php b/system/src/Grav/Framework/DI/Container.php new file mode 100644 index 0000000..45d0384 --- /dev/null +++ b/system/src/Grav/Framework/DI/Container.php @@ -0,0 +1,35 @@ +offsetGet($id); + } + + /** + * @param string $id + * @return bool + */ + public function has($id): bool + { + return $this->offsetExists($id); + } +} diff --git a/system/src/Grav/Framework/File/AbstractFile.php b/system/src/Grav/Framework/File/AbstractFile.php new file mode 100644 index 0000000..e81c419 --- /dev/null +++ b/system/src/Grav/Framework/File/AbstractFile.php @@ -0,0 +1,444 @@ +filesystem = $filesystem ?? Filesystem::getInstance(); + $this->setFilepath($filepath); + } + + /** + * Unlock file when the object gets destroyed. + */ + #[\ReturnTypeWillChange] + public function __destruct() + { + if ($this->isLocked()) { + $this->unlock(); + } + } + + /** + * @return void + */ + #[\ReturnTypeWillChange] + public function __clone() + { + $this->handle = null; + $this->locked = false; + } + + /** + * @return array + */ + final public function __serialize(): array + { + return ['filesystem_normalize' => $this->filesystem->getNormalization()] + $this->doSerialize(); + } + + /** + * @param array $data + * @return void + */ + final public function __unserialize(array $data): void + { + $this->filesystem = Filesystem::getInstance($data['filesystem_normalize'] ?? null); + + $this->doUnserialize($data); + } + + /** + * {@inheritdoc} + * @see FileInterface::getFilePath() + */ + public function getFilePath(): string + { + return $this->filepath; + } + + /** + * {@inheritdoc} + * @see FileInterface::getPath() + */ + public function getPath(): string + { + if (null === $this->path) { + $this->setPathInfo(); + } + + return $this->path ?? ''; + } + + /** + * {@inheritdoc} + * @see FileInterface::getFilename() + */ + public function getFilename(): string + { + if (null === $this->filename) { + $this->setPathInfo(); + } + + return $this->filename ?? ''; + } + + /** + * {@inheritdoc} + * @see FileInterface::getBasename() + */ + public function getBasename(): string + { + if (null === $this->basename) { + $this->setPathInfo(); + } + + return $this->basename ?? ''; + } + + /** + * {@inheritdoc} + * @see FileInterface::getExtension() + */ + public function getExtension(bool $withDot = false): string + { + if (null === $this->extension) { + $this->setPathInfo(); + } + + return ($withDot ? '.' : '') . $this->extension; + } + + /** + * {@inheritdoc} + * @see FileInterface::exists() + */ + public function exists(): bool + { + return is_file($this->filepath); + } + + /** + * {@inheritdoc} + * @see FileInterface::getCreationTime() + */ + public function getCreationTime(): int + { + return is_file($this->filepath) ? (int)filectime($this->filepath) : time(); + } + + /** + * {@inheritdoc} + * @see FileInterface::getModificationTime() + */ + public function getModificationTime(): int + { + return is_file($this->filepath) ? (int)filemtime($this->filepath) : time(); + } + + /** + * {@inheritdoc} + * @see FileInterface::lock() + */ + public function lock(bool $block = true): bool + { + if (!$this->handle) { + if (!$this->mkdir($this->getPath())) { + throw new RuntimeException('Creating directory failed for ' . $this->filepath); + } + $this->handle = @fopen($this->filepath, 'cb+') ?: null; + if (!$this->handle) { + $error = error_get_last(); + $message = $error['message'] ?? 'Unknown error'; + + throw new RuntimeException("Opening file for writing failed on error {$message}"); + } + } + + $lock = $block ? LOCK_EX : LOCK_EX | LOCK_NB; + + // Some filesystems do not support file locks, only fail if another process holds the lock. + $this->locked = flock($this->handle, $lock, $wouldBlock) || !$wouldBlock; + + return $this->locked; + } + + /** + * {@inheritdoc} + * @see FileInterface::unlock() + */ + public function unlock(): bool + { + if (!$this->handle) { + return false; + } + + if ($this->locked) { + flock($this->handle, LOCK_UN | LOCK_NB); + $this->locked = false; + } + + fclose($this->handle); + $this->handle = null; + + return true; + } + + /** + * {@inheritdoc} + * @see FileInterface::isLocked() + */ + public function isLocked(): bool + { + return $this->locked; + } + + /** + * {@inheritdoc} + * @see FileInterface::isReadable() + */ + public function isReadable(): bool + { + return is_readable($this->filepath) && is_file($this->filepath); + } + + /** + * {@inheritdoc} + * @see FileInterface::isWritable() + */ + public function isWritable(): bool + { + if (!file_exists($this->filepath)) { + return $this->isWritablePath($this->getPath()); + } + + return is_writable($this->filepath) && is_file($this->filepath); + } + + /** + * {@inheritdoc} + * @see FileInterface::load() + */ + public function load() + { + return file_get_contents($this->filepath); + } + + /** + * {@inheritdoc} + * @see FileInterface::save() + */ + public function save($data): void + { + $filepath = $this->filepath; + $dir = $this->getPath(); + + if (!$this->mkdir($dir)) { + throw new RuntimeException('Creating directory failed for ' . $filepath); + } + + try { + if ($this->handle) { + $tmp = true; + // As we are using non-truncating locking, make sure that the file is empty before writing. + if (@ftruncate($this->handle, 0) === false || @fwrite($this->handle, $data) === false) { + // Writing file failed, throw an error. + $tmp = false; + } + } else { + // Support for symlinks. + $realpath = is_link($filepath) ? realpath($filepath) : $filepath; + if ($realpath === false) { + throw new RuntimeException('Failed to save file ' . $filepath); + } + + // Create file with a temporary name and rename it to make the save action atomic. + $tmp = $this->tempname($realpath); + if (@file_put_contents($tmp, $data) === false) { + $tmp = false; + } elseif (@rename($tmp, $realpath) === false) { + @unlink($tmp); + $tmp = false; + } + } + } catch (Exception $e) { + $tmp = false; + } + + if ($tmp === false) { + throw new RuntimeException('Failed to save file ' . $filepath); + } + + // Touch the directory as well, thus marking it modified. + @touch($dir); + } + + /** + * {@inheritdoc} + * @see FileInterface::rename() + */ + public function rename(string $path): bool + { + if ($this->exists() && !@rename($this->filepath, $path)) { + return false; + } + + $this->setFilepath($path); + + return true; + } + + /** + * {@inheritdoc} + * @see FileInterface::delete() + */ + public function delete(): bool + { + return @unlink($this->filepath); + } + + /** + * @param string $dir + * @return bool + * @throws RuntimeException + * @internal + */ + protected function mkdir(string $dir): bool + { + // Silence error for open_basedir; should fail in mkdir instead. + if (@is_dir($dir)) { + return true; + } + + $success = @mkdir($dir, 0777, true); + + if (!$success) { + // Take yet another look, make sure that the folder doesn't exist. + clearstatcache(true, $dir); + if (!@is_dir($dir)) { + return false; + } + } + + return true; + } + + /** + * @return array + */ + protected function doSerialize(): array + { + return [ + 'filepath' => $this->filepath + ]; + } + + /** + * @param array $serialized + * @return void + */ + protected function doUnserialize(array $serialized): void + { + $this->setFilepath($serialized['filepath']); + } + + /** + * @param string $filepath + */ + protected function setFilepath(string $filepath): void + { + $this->filepath = $filepath; + $this->filename = null; + $this->basename = null; + $this->path = null; + $this->extension = null; + } + + protected function setPathInfo(): void + { + /** @var array $pathInfo */ + $pathInfo = $this->filesystem->pathinfo($this->filepath); + + $this->filename = $pathInfo['filename'] ?? null; + $this->basename = $pathInfo['basename'] ?? null; + $this->path = $pathInfo['dirname'] ?? null; + $this->extension = $pathInfo['extension'] ?? null; + } + + /** + * @param string $dir + * @return bool + * @internal + */ + protected function isWritablePath(string $dir): bool + { + if ($dir === '') { + return false; + } + + if (!file_exists($dir)) { + // Recursively look up in the directory tree. + return $this->isWritablePath($this->filesystem->parent($dir)); + } + + return is_dir($dir) && is_writable($dir); + } + + /** + * @param string $filename + * @param int $length + * @return string + */ + protected function tempname(string $filename, int $length = 5) + { + do { + $test = $filename . substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, $length); + } while (file_exists($test)); + + return $test; + } +} diff --git a/system/src/Grav/Framework/File/CsvFile.php b/system/src/Grav/Framework/File/CsvFile.php new file mode 100644 index 0000000..543a792 --- /dev/null +++ b/system/src/Grav/Framework/File/CsvFile.php @@ -0,0 +1,40 @@ +formatter = $formatter; + } + + /** + * {@inheritdoc} + * @see FileInterface::load() + */ + public function load() + { + $raw = parent::load(); + + try { + if (!is_string($raw)) { + throw new RuntimeException('Bad Data'); + } + + return $this->formatter->decode($raw); + } catch (RuntimeException $e) { + throw new RuntimeException(sprintf("Failed to load file '%s': %s", $this->getFilePath(), $e->getMessage()), $e->getCode(), $e); + } + } + + /** + * {@inheritdoc} + * @see FileInterface::save() + */ + public function save($data): void + { + if (is_string($data)) { + // Make sure that the string is valid data. + try { + $this->formatter->decode($data); + } catch (RuntimeException $e) { + throw new RuntimeException(sprintf("Failed to save file '%s': %s", $this->getFilePath(), $e->getMessage()), $e->getCode(), $e); + } + $encoded = $data; + } else { + $encoded = $this->formatter->encode($data); + } + + parent::save($encoded); + } +} diff --git a/system/src/Grav/Framework/File/File.php b/system/src/Grav/Framework/File/File.php new file mode 100644 index 0000000..578b28e --- /dev/null +++ b/system/src/Grav/Framework/File/File.php @@ -0,0 +1,35 @@ +config = $config; + } + + /** + * @return string + */ + public function getMimeType(): string + { + $mime = $this->getConfig('mime'); + + return is_string($mime) ? $mime : 'application/octet-stream'; + } + + /** + * {@inheritdoc} + * @see FileFormatterInterface::getDefaultFileExtension() + */ + public function getDefaultFileExtension(): string + { + $extensions = $this->getSupportedFileExtensions(); + + // Call fails on bad configuration. + return reset($extensions) ?: ''; + } + + /** + * {@inheritdoc} + * @see FileFormatterInterface::getSupportedFileExtensions() + */ + public function getSupportedFileExtensions(): array + { + $extensions = $this->getConfig('file_extension'); + + // Call fails on bad configuration. + return is_string($extensions) ? [$extensions] : $extensions; + } + + /** + * {@inheritdoc} + * @see FileFormatterInterface::encode() + */ + abstract public function encode($data): string; + + /** + * {@inheritdoc} + * @see FileFormatterInterface::decode() + */ + abstract public function decode($data); + + + /** + * @return array + */ + public function __serialize(): array + { + return ['config' => $this->config]; + } + + /** + * @param array $data + * @return void + */ + public function __unserialize(array $data): void + { + $this->config = $data['config']; + } + + /** + * Get either full configuration or a single option. + * + * @param string|null $name Configuration option (optional) + * @return mixed + */ + protected function getConfig(string $name = null) + { + if (null !== $name) { + return $this->config[$name] ?? null; + } + + return $this->config; + } +} diff --git a/system/src/Grav/Framework/File/Formatter/CsvFormatter.php b/system/src/Grav/Framework/File/Formatter/CsvFormatter.php new file mode 100644 index 0000000..9bdd662 --- /dev/null +++ b/system/src/Grav/Framework/File/Formatter/CsvFormatter.php @@ -0,0 +1,170 @@ + ['.csv', '.tsv'], + 'delimiter' => ',', + 'mime' => 'text/x-csv' + ]; + + parent::__construct($config); + } + + /** + * Returns delimiter used to both encode and decode CSV. + * + * @return string + */ + public function getDelimiter(): string + { + // Call fails on bad configuration. + return $this->getConfig('delimiter'); + } + + /** + * @param array $data + * @param string|null $delimiter + * @return string + * @see FileFormatterInterface::encode() + */ + public function encode($data, $delimiter = null): string + { + if (count($data) === 0) { + return ''; + } + $delimiter = $delimiter ?? $this->getDelimiter(); + $header = array_keys(reset($data)); + + // Encode the field names + $string = $this->encodeLine($header, $delimiter); + + // Encode the data + foreach ($data as $row) { + $string .= $this->encodeLine($row, $delimiter); + } + + return $string; + } + + /** + * @param string $data + * @param string|null $delimiter + * @return array + * @see FileFormatterInterface::decode() + */ + public function decode($data, $delimiter = null): array + { + $delimiter = $delimiter ?? $this->getDelimiter(); + $lines = preg_split('/\r\n|\r|\n/', $data); + if ($lines === false) { + throw new RuntimeException('Decoding CSV failed'); + } + + // Get the field names + $headerStr = array_shift($lines); + if (!$headerStr) { + throw new RuntimeException('CSV header missing'); + } + + $header = str_getcsv($headerStr, $delimiter); + + // Allow for replacing a null string with null/empty value + $null_replace = $this->getConfig('null'); + + // Get the data + $list = []; + $line = null; + try { + foreach ($lines as $line) { + if (!empty($line)) { + $csv_line = str_getcsv($line, $delimiter); + + if ($null_replace) { + array_walk($csv_line, static function (&$el) use ($null_replace) { + $el = str_replace($null_replace, "\0", $el); + }); + } + + $list[] = array_combine($header, $csv_line); + } + } + } catch (Exception $e) { + throw new RuntimeException('Badly formatted CSV line: ' . $line); + } + + return $list; + } + + /** + * @param array $line + * @param string $delimiter + * @return string + */ + protected function encodeLine(array $line, string $delimiter): string + { + foreach ($line as $key => &$value) { + // Oops, we need to convert the line to a string. + if (!is_scalar($value)) { + if (is_array($value) || $value instanceof JsonSerializable || $value instanceof stdClass) { + $value = json_encode($value); + } elseif (is_object($value)) { + if (method_exists($value, 'toJson')) { + $value = $value->toJson(); + } elseif (method_exists($value, 'toArray')) { + $value = json_encode($value->toArray()); + } + } + } + + $value = $this->escape((string)$value); + } + unset($value); + + return implode($delimiter, $line). "\n"; + } + + /** + * @param string $value + * @return string + */ + protected function escape(string $value) + { + if (preg_match('/[,"\r\n]/u', $value)) { + $value = '"' . preg_replace('/"/', '""', $value) . '"'; + } + + return $value; + } +} diff --git a/system/src/Grav/Framework/File/Formatter/FormatterInterface.php b/system/src/Grav/Framework/File/Formatter/FormatterInterface.php new file mode 100644 index 0000000..757e229 --- /dev/null +++ b/system/src/Grav/Framework/File/Formatter/FormatterInterface.php @@ -0,0 +1,12 @@ + '.ini' + ]; + + parent::__construct($config); + } + + /** + * {@inheritdoc} + * @see FileFormatterInterface::encode() + */ + public function encode($data): string + { + $string = ''; + foreach ($data as $key => $value) { + $string .= $key . '="' . preg_replace( + ['/"/', '/\\\/', "/\t/", "/\n/", "/\r/"], + ['\"', '\\\\', '\t', '\n', '\r'], + $value + ) . "\"\n"; + } + + return $string; + } + + /** + * {@inheritdoc} + * @see FileFormatterInterface::decode() + */ + public function decode($data): array + { + $decoded = @parse_ini_string($data); + + if ($decoded === false) { + throw new RuntimeException('Decoding INI failed'); + } + + return $decoded; + } +} diff --git a/system/src/Grav/Framework/File/Formatter/JsonFormatter.php b/system/src/Grav/Framework/File/Formatter/JsonFormatter.php new file mode 100644 index 0000000..972958a --- /dev/null +++ b/system/src/Grav/Framework/File/Formatter/JsonFormatter.php @@ -0,0 +1,170 @@ + JSON_FORCE_OBJECT, + 'JSON_HEX_QUOT' => JSON_HEX_QUOT, + 'JSON_HEX_TAG' => JSON_HEX_TAG, + 'JSON_HEX_AMP' => JSON_HEX_AMP, + 'JSON_HEX_APOS' => JSON_HEX_APOS, + 'JSON_INVALID_UTF8_IGNORE' => JSON_INVALID_UTF8_IGNORE, + 'JSON_INVALID_UTF8_SUBSTITUTE' => JSON_INVALID_UTF8_SUBSTITUTE, + 'JSON_NUMERIC_CHECK' => JSON_NUMERIC_CHECK, + 'JSON_PARTIAL_OUTPUT_ON_ERROR' => JSON_PARTIAL_OUTPUT_ON_ERROR, + 'JSON_PRESERVE_ZERO_FRACTION' => JSON_PRESERVE_ZERO_FRACTION, + 'JSON_PRETTY_PRINT' => JSON_PRETTY_PRINT, + 'JSON_UNESCAPED_LINE_TERMINATORS' => JSON_UNESCAPED_LINE_TERMINATORS, + 'JSON_UNESCAPED_SLASHES' => JSON_UNESCAPED_SLASHES, + 'JSON_UNESCAPED_UNICODE' => JSON_UNESCAPED_UNICODE, + //'JSON_THROW_ON_ERROR' => JSON_THROW_ON_ERROR // PHP 7.3 + ]; + + /** @var array */ + protected $decodeOptions = [ + 'JSON_BIGINT_AS_STRING' => JSON_BIGINT_AS_STRING, + 'JSON_INVALID_UTF8_IGNORE' => JSON_INVALID_UTF8_IGNORE, + 'JSON_INVALID_UTF8_SUBSTITUTE' => JSON_INVALID_UTF8_SUBSTITUTE, + 'JSON_OBJECT_AS_ARRAY' => JSON_OBJECT_AS_ARRAY, + //'JSON_THROW_ON_ERROR' => JSON_THROW_ON_ERROR // PHP 7.3 + ]; + + public function __construct(array $config = []) + { + $config += [ + 'file_extension' => '.json', + 'encode_options' => 0, + 'decode_assoc' => true, + 'decode_depth' => 512, + 'decode_options' => 0 + ]; + + parent::__construct($config); + } + + /** + * Returns options used in encode() function. + * + * @return int + */ + public function getEncodeOptions(): int + { + $options = $this->getConfig('encode_options'); + if (!is_int($options)) { + if (is_string($options)) { + $list = preg_split('/[\s,|]+/', $options); + $options = 0; + if ($list) { + foreach ($list as $option) { + if (isset($this->encodeOptions[$option])) { + $options += $this->encodeOptions[$option]; + } + } + } + } else { + $options = 0; + } + } + + return $options; + } + + /** + * Returns options used in decode() function. + * + * @return int + */ + public function getDecodeOptions(): int + { + $options = $this->getConfig('decode_options'); + if (!is_int($options)) { + if (is_string($options)) { + $list = preg_split('/[\s,|]+/', $options); + $options = 0; + if ($list) { + foreach ($list as $option) { + if (isset($this->decodeOptions[$option])) { + $options += $this->decodeOptions[$option]; + } + } + } + } else { + $options = 0; + } + } + + return $options; + } + + /** + * Returns recursion depth used in decode() function. + * + * @return int + * @phpstan-return positive-int + */ + public function getDecodeDepth(): int + { + return $this->getConfig('decode_depth'); + } + + /** + * Returns true if JSON objects will be converted into associative arrays. + * + * @return bool + */ + public function getDecodeAssoc(): bool + { + return $this->getConfig('decode_assoc'); + } + + /** + * {@inheritdoc} + * @see FileFormatterInterface::encode() + */ + public function encode($data): string + { + $encoded = @json_encode($data, $this->getEncodeOptions()); + + if ($encoded === false && json_last_error() !== JSON_ERROR_NONE) { + throw new RuntimeException('Encoding JSON failed: ' . json_last_error_msg()); + } + + return $encoded ?: ''; + } + + /** + * {@inheritdoc} + * @see FileFormatterInterface::decode() + */ + public function decode($data) + { + $decoded = @json_decode($data, $this->getDecodeAssoc(), $this->getDecodeDepth(), $this->getDecodeOptions()); + + if (null === $decoded && json_last_error() !== JSON_ERROR_NONE) { + throw new RuntimeException('Decoding JSON failed: ' . json_last_error_msg()); + } + + return $decoded; + } +} diff --git a/system/src/Grav/Framework/File/Formatter/MarkdownFormatter.php b/system/src/Grav/Framework/File/Formatter/MarkdownFormatter.php new file mode 100644 index 0000000..cf16cf7 --- /dev/null +++ b/system/src/Grav/Framework/File/Formatter/MarkdownFormatter.php @@ -0,0 +1,161 @@ + '.md', + 'header' => 'header', + 'body' => 'markdown', + 'raw' => 'frontmatter', + 'yaml' => ['inline' => 20] + ]; + + parent::__construct($config); + + $this->headerFormatter = $headerFormatter ?? new YamlFormatter($config['yaml']); + } + + /** + * Returns header field used in both encode() and decode(). + * + * @return string + */ + public function getHeaderField(): string + { + return $this->getConfig('header'); + } + + /** + * Returns body field used in both encode() and decode(). + * + * @return string + */ + public function getBodyField(): string + { + return $this->getConfig('body'); + } + + /** + * Returns raw field used in both encode() and decode(). + * + * @return string + */ + public function getRawField(): string + { + return $this->getConfig('raw'); + } + + /** + * Returns header formatter object used in both encode() and decode(). + * + * @return FileFormatterInterface + */ + public function getHeaderFormatter(): FileFormatterInterface + { + return $this->headerFormatter; + } + + /** + * {@inheritdoc} + * @see FileFormatterInterface::encode() + */ + public function encode($data): string + { + $headerVar = $this->getHeaderField(); + $bodyVar = $this->getBodyField(); + + $header = isset($data[$headerVar]) ? (array) $data[$headerVar] : []; + $body = isset($data[$bodyVar]) ? (string) $data[$bodyVar] : ''; + + // Create Markdown file with YAML header. + $encoded = ''; + if ($header) { + $encoded = "---\n" . trim($this->getHeaderFormatter()->encode($data['header'])) . "\n---\n\n"; + } + $encoded .= $body; + + // Normalize line endings to Unix style. + $encoded = preg_replace("/(\r\n|\r)/u", "\n", $encoded); + if (null === $encoded) { + throw new RuntimeException('Encoding markdown failed'); + } + + return $encoded; + } + + /** + * {@inheritdoc} + * @see FileFormatterInterface::decode() + */ + public function decode($data): array + { + $headerVar = $this->getHeaderField(); + $bodyVar = $this->getBodyField(); + $rawVar = $this->getRawField(); + + // Define empty content + $content = [ + $headerVar => [], + $bodyVar => '' + ]; + + $headerRegex = "/^---\n(.+?)\n---\n{0,}(.*)$/uis"; + + // Normalize line endings to Unix style. + $data = preg_replace("/(\r\n|\r)/u", "\n", $data); + if (null === $data) { + throw new RuntimeException('Decoding markdown failed'); + } + + // Parse header. + preg_match($headerRegex, ltrim($data), $matches); + if (empty($matches)) { + $content[$bodyVar] = $data; + } else { + // Normalize frontmatter. + $frontmatter = preg_replace("/\n\t/", "\n ", $matches[1]); + if ($rawVar) { + $content[$rawVar] = $frontmatter; + } + $content[$headerVar] = $this->getHeaderFormatter()->decode($frontmatter); + $content[$bodyVar] = $matches[2]; + } + + return $content; + } + + public function __serialize(): array + { + return parent::__serialize() + ['headerFormatter' => $this->headerFormatter]; + } + + public function __unserialize(array $data): void + { + parent::__unserialize($data); + + $this->headerFormatter = $data['headerFormatter'] ?? new YamlFormatter(['inline' => 20]); + } +} diff --git a/system/src/Grav/Framework/File/Formatter/SerializeFormatter.php b/system/src/Grav/Framework/File/Formatter/SerializeFormatter.php new file mode 100644 index 0000000..2ed8b93 --- /dev/null +++ b/system/src/Grav/Framework/File/Formatter/SerializeFormatter.php @@ -0,0 +1,98 @@ + '.ser', + 'decode_options' => ['allowed_classes' => [stdClass::class]] + ]; + + parent::__construct($config); + } + + /** + * Returns options used in decode(). + * + * By default only allow stdClass class. + * + * @return array + */ + public function getOptions() + { + return $this->getConfig('decode_options'); + } + + /** + * {@inheritdoc} + * @see FileFormatterInterface::encode() + */ + public function encode($data): string + { + return serialize($this->preserveLines($data, ["\n", "\r"], ['\\n', '\\r'])); + } + + /** + * {@inheritdoc} + * @see FileFormatterInterface::decode() + */ + public function decode($data) + { + $classes = $this->getOptions()['allowed_classes'] ?? false; + $decoded = @unserialize($data, ['allowed_classes' => $classes]); + + if ($decoded === false && $data !== serialize(false)) { + throw new RuntimeException('Decoding serialized data failed'); + } + + return $this->preserveLines($decoded, ['\\n', '\\r'], ["\n", "\r"]); + } + + /** + * Preserve new lines, recursive function. + * + * @param mixed $data + * @param array $search + * @param array $replace + * @return mixed + */ + protected function preserveLines($data, array $search, array $replace) + { + if (is_string($data)) { + $data = str_replace($search, $replace, $data); + } elseif (is_array($data)) { + foreach ($data as &$value) { + $value = $this->preserveLines($value, $search, $replace); + } + unset($value); + } + + return $data; + } +} diff --git a/system/src/Grav/Framework/File/Formatter/YamlFormatter.php b/system/src/Grav/Framework/File/Formatter/YamlFormatter.php new file mode 100644 index 0000000..9a0e2be --- /dev/null +++ b/system/src/Grav/Framework/File/Formatter/YamlFormatter.php @@ -0,0 +1,129 @@ + '.yaml', + 'inline' => 5, + 'indent' => 2, + 'native' => true, + 'compat' => true + ]; + + parent::__construct($config); + } + + /** + * @return int + */ + public function getInlineOption(): int + { + return $this->getConfig('inline'); + } + + /** + * @return int + */ + public function getIndentOption(): int + { + return $this->getConfig('indent'); + } + + /** + * @return bool + */ + public function useNativeDecoder(): bool + { + return $this->getConfig('native'); + } + + /** + * @return bool + */ + public function useCompatibleDecoder(): bool + { + return $this->getConfig('compat'); + } + + /** + * @param array $data + * @param int|null $inline + * @param int|null $indent + * @return string + * @see FileFormatterInterface::encode() + */ + public function encode($data, $inline = null, $indent = null): string + { + try { + return YamlParser::dump( + $data, + $inline ? (int) $inline : $this->getInlineOption(), + $indent ? (int) $indent : $this->getIndentOption(), + YamlParser::DUMP_EXCEPTION_ON_INVALID_TYPE + ); + } catch (DumpException $e) { + throw new RuntimeException('Encoding YAML failed: ' . $e->getMessage(), 0, $e); + } + } + + /** + * {@inheritdoc} + * @see FileFormatterInterface::decode() + */ + public function decode($data): array + { + // Try native PECL YAML PHP extension first if available. + if (function_exists('yaml_parse') && $this->useNativeDecoder()) { + // Safely decode YAML. + $saved = @ini_get('yaml.decode_php'); + @ini_set('yaml.decode_php', '0'); + $decoded = @yaml_parse($data); + if ($saved !== false) { + @ini_set('yaml.decode_php', $saved); + } + + if ($decoded !== false) { + return (array) $decoded; + } + } + + try { + return (array) YamlParser::parse($data); + } catch (ParseException $e) { + if ($this->useCompatibleDecoder()) { + return (array) FallbackYamlParser::parse($data); + } + + throw new RuntimeException('Decoding YAML failed: ' . $e->getMessage(), 0, $e); + } + } +} diff --git a/system/src/Grav/Framework/File/IniFile.php b/system/src/Grav/Framework/File/IniFile.php new file mode 100644 index 0000000..3039623 --- /dev/null +++ b/system/src/Grav/Framework/File/IniFile.php @@ -0,0 +1,40 @@ +setNormalization() + * @return Filesystem + */ + public static function getInstance(bool $normalize = null): Filesystem + { + if ($normalize === true) { + $instance = &static::$safe; + } elseif ($normalize === false) { + $instance = &static::$unsafe; + } else { + $instance = &static::$default; + } + + if (null === $instance) { + $instance = new static($normalize); + } + + return $instance; + } + + /** + * Always use Filesystem::getInstance() instead. + * + * @param bool|null $normalize + * @internal + */ + protected function __construct(bool $normalize = null) + { + $this->normalize = $normalize; + } + + /** + * Set path normalization. + * + * Default option enables normalization for the streams only, but you can force the normalization to be either + * on or off for every path. Disabling path normalization speeds up the calls, but may cause issues if paths were + * not normalized. + * + * @param bool|null $normalize + * @return Filesystem + */ + public function setNormalization(bool $normalize = null): self + { + return static::getInstance($normalize); + } + + /** + * @return bool|null + */ + public function getNormalization(): ?bool + { + return $this->normalize; + } + + /** + * Force all paths to be normalized. + * + * @return self + */ + public function unsafe(): self + { + return static::getInstance(true); + } + + /** + * Force all paths not to be normalized (speeds up the calls if given paths are known to be normalized). + * + * @return self + */ + public function safe(): self + { + return static::getInstance(false); + } + + /** + * {@inheritdoc} + * @see FilesystemInterface::parent() + */ + public function parent(string $path, int $levels = 1): string + { + [$scheme, $path] = $this->getSchemeAndHierarchy($path); + + if ($this->normalize !== false) { + $path = $this->normalizePathPart($path); + } + + if ($path === '' || $path === '.') { + return ''; + } + + [$scheme, $parent] = $this->dirnameInternal($scheme, $path, $levels); + + return $parent !== $path ? $this->toString($scheme, $parent) : ''; + } + + /** + * {@inheritdoc} + * @see FilesystemInterface::normalize() + */ + public function normalize(string $path): string + { + [$scheme, $path] = $this->getSchemeAndHierarchy($path); + + $path = $this->normalizePathPart($path); + + return $this->toString($scheme, $path); + } + + /** + * {@inheritdoc} + * @see FilesystemInterface::basename() + */ + public function basename(string $path, ?string $suffix = null): string + { + // Escape path. + $path = str_replace(['%2F', '%5C'], '/', rawurlencode($path)); + + return rawurldecode($suffix ? basename($path, $suffix) : basename($path)); + } + + /** + * {@inheritdoc} + * @see FilesystemInterface::dirname() + */ + public function dirname(string $path, int $levels = 1): string + { + [$scheme, $path] = $this->getSchemeAndHierarchy($path); + + if ($this->normalize || ($scheme && null === $this->normalize)) { + $path = $this->normalizePathPart($path); + } + + [$scheme, $path] = $this->dirnameInternal($scheme, $path, $levels); + + return $this->toString($scheme, $path); + } + + /** + * Gets full path with trailing slash. + * + * @param string $path + * @param int $levels + * @return string + * @phpstan-param positive-int $levels + */ + public function pathname(string $path, int $levels = 1): string + { + $path = $this->dirname($path, $levels); + + return $path !== '.' ? $path . '/' : ''; + } + + /** + * {@inheritdoc} + * @see FilesystemInterface::pathinfo() + */ + public function pathinfo(string $path, ?int $options = null) + { + [$scheme, $path] = $this->getSchemeAndHierarchy($path); + + if ($this->normalize || ($scheme && null === $this->normalize)) { + $path = $this->normalizePathPart($path); + } + + return $this->pathinfoInternal($scheme, $path, $options); + } + + /** + * @param string|null $scheme + * @param string $path + * @param int $levels + * @return array + * @phpstan-param positive-int $levels + */ + protected function dirnameInternal(?string $scheme, string $path, int $levels = 1): array + { + $path = dirname($path, $levels); + + if (null !== $scheme && $path === '.') { + return [$scheme, '']; + } + + // In Windows dirname() may return backslashes, fix that. + if (DIRECTORY_SEPARATOR !== '/') { + $path = str_replace('\\', '/', $path); + } + + return [$scheme, $path]; + } + + /** + * @param string|null $scheme + * @param string $path + * @param int|null $options + * @return array|string + */ + protected function pathinfoInternal(?string $scheme, string $path, ?int $options = null) + { + $path = str_replace(['%2F', '%5C'], ['/', '\\'], rawurlencode($path)); + + if (null === $options) { + $info = pathinfo($path); + } else { + $info = pathinfo($path, $options); + } + + if (!is_array($info)) { + return rawurldecode($info); + } + + $info = array_map('rawurldecode', $info); + + if (null !== $scheme) { + $info['scheme'] = $scheme; + + /** @phpstan-ignore-next-line because pathinfo('') doesn't have dirname */ + $dirname = $info['dirname'] ?? '.'; + + if ('' !== $dirname && '.' !== $dirname) { + // In Windows dirname may be using backslashes, fix that. + if (DIRECTORY_SEPARATOR !== '/') { + $dirname = str_replace(DIRECTORY_SEPARATOR, '/', $dirname); + } + + $info['dirname'] = $scheme . '://' . $dirname; + } else { + $info = ['dirname' => $scheme . '://'] + $info; + } + } + + return $info; + } + + /** + * Gets a 2-tuple of scheme (may be null) and hierarchical part of a filename (e.g. file:///tmp -> array(file, tmp)). + * + * @param string $filename + * @return array + */ + protected function getSchemeAndHierarchy(string $filename): array + { + $components = explode('://', $filename, 2); + + return 2 === count($components) ? $components : [null, $components[0]]; + } + + /** + * @param string|null $scheme + * @param string $path + * @return string + */ + protected function toString(?string $scheme, string $path): string + { + if ($scheme) { + return $scheme . '://' . $path; + } + + return $path; + } + + /** + * @param string $path + * @return string + * @throws RuntimeException + */ + protected function normalizePathPart(string $path): string + { + // Quick check for empty path. + if ($path === '' || $path === '.') { + return ''; + } + + // Quick check for root. + if ($path === '/') { + return '/'; + } + + // If the last character is not '/' or any of '\', './', '//' and '..' are not found, path is clean and we're done. + if ($path[-1] !== '/' && !preg_match('`(\\\\|\./|//|\.\.)`', $path)) { + return $path; + } + + // Convert backslashes + $path = strtr($path, ['\\' => '/']); + + $parts = explode('/', $path); + + // Keep absolute paths. + $root = ''; + if ($parts[0] === '') { + $root = '/'; + array_shift($parts); + } + + $list = []; + foreach ($parts as $i => $part) { + // Remove empty parts: // and /./ + if ($part === '' || $part === '.') { + continue; + } + + // Resolve /../ by removing path part. + if ($part === '..') { + $test = array_pop($list); + if ($test === null) { + // Oops, user tried to access something outside of our root folder. + throw new RuntimeException("Bad path {$path}"); + } + } else { + $list[] = $part; + } + } + + // Build path back together. + return $root . implode('/', $list); + } +} diff --git a/system/src/Grav/Framework/Filesystem/Interfaces/FilesystemInterface.php b/system/src/Grav/Framework/Filesystem/Interfaces/FilesystemInterface.php new file mode 100644 index 0000000..f5135bd --- /dev/null +++ b/system/src/Grav/Framework/Filesystem/Interfaces/FilesystemInterface.php @@ -0,0 +1,84 @@ += 1). + * @return string Returns parent path. + * @throws RuntimeException + * @phpstan-param positive-int $levels + * @api + */ + public function parent(string $path, int $levels = 1): string; + + /** + * Normalize path by cleaning up `\`, `/./`, `//` and `/../`. + * + * @param string $path A filename or path, does not need to exist as a file. + * @return string Returns normalized path. + * @throws RuntimeException + * @api + */ + public function normalize(string $path): string; + + /** + * Unicode-safe and stream-safe `\basename()` replacement. + * + * @param string $path A filename or path, does not need to exist as a file. + * @param string|null $suffix If the filename ends in suffix this will also be cut off. + * @return string + * @api + */ + public function basename(string $path, ?string $suffix = null): string; + + /** + * Unicode-safe and stream-safe `\dirname()` replacement. + * + * @see http://php.net/manual/en/function.dirname.php + * + * @param string $path A filename or path, does not need to exist as a file. + * @param int $levels The number of parent directories to go up (>= 1). + * @return string Returns path to the directory. + * @throws RuntimeException + * @phpstan-param positive-int $levels + * @api + */ + public function dirname(string $path, int $levels = 1): string; + + /** + * Unicode-safe and stream-safe `\pathinfo()` replacement. + * + * @see http://php.net/manual/en/function.pathinfo.php + * + * @param string $path A filename or path, does not need to exist as a file. + * @param int|null $options A PATHINFO_* constant. + * @return array|string + * @api + */ + public function pathinfo(string $path, ?int $options = null); +} diff --git a/system/src/Grav/Framework/Flex/Flex.php b/system/src/Grav/Framework/Flex/Flex.php new file mode 100644 index 0000000..c78a42c --- /dev/null +++ b/system/src/Grav/Framework/Flex/Flex.php @@ -0,0 +1,334 @@ + blueprint file, ...] + * @param array $config + */ + public function __construct(array $types, array $config) + { + $this->config = $config; + $this->types = []; + + foreach ($types as $type => $blueprint) { + if (!file_exists($blueprint)) { + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $debugger->addMessage(sprintf('Flex: blueprint for flex type %s is missing', $type), 'error'); + + continue; + } + $this->addDirectoryType($type, $blueprint); + } + } + + /** + * @param string $type + * @param string $blueprint + * @param array $config + * @return $this + */ + public function addDirectoryType(string $type, string $blueprint, array $config = []) + { + $config = array_replace_recursive(['enabled' => true], $this->config, $config); + + $this->types[$type] = new FlexDirectory($type, $blueprint, $config); + + return $this; + } + + /** + * @param FlexDirectory $directory + * @return $this + */ + public function addDirectory(FlexDirectory $directory) + { + $this->types[$directory->getFlexType()] = $directory; + + return $this; + } + + /** + * @param string $type + * @return bool + */ + public function hasDirectory(string $type): bool + { + return isset($this->types[$type]); + } + + /** + * @param array|string[]|null $types + * @param bool $keepMissing + * @return array + */ + public function getDirectories(array $types = null, bool $keepMissing = false): array + { + if ($types === null) { + return $this->types; + } + + // Return the directories in the given order. + $directories = []; + foreach ($types as $type) { + $directories[$type] = $this->types[$type] ?? null; + } + + return $keepMissing ? $directories : array_filter($directories); + } + + /** + * @param string $type + * @return FlexDirectory|null + */ + public function getDirectory(string $type): ?FlexDirectory + { + return $this->types[$type] ?? null; + } + + /** + * @param string $type + * @param array|null $keys + * @param string|null $keyField + * @return FlexCollectionInterface|null + * @phpstan-return FlexCollectionInterface|null + */ + public function getCollection(string $type, array $keys = null, string $keyField = null): ?FlexCollectionInterface + { + $directory = $type ? $this->getDirectory($type) : null; + + return $directory ? $directory->getCollection($keys, $keyField) : null; + } + + /** + * @param array $keys + * @param array $options In addition to the options in getObjects(), following options can be passed: + * collection_class: Class to be used to create the collection. Defaults to ObjectCollection. + * @return FlexCollectionInterface + * @throws RuntimeException + * @phpstan-return FlexCollectionInterface + */ + public function getMixedCollection(array $keys, array $options = []): FlexCollectionInterface + { + $collectionClass = $options['collection_class'] ?? ObjectCollection::class; + if (!is_a($collectionClass, FlexCollectionInterface::class, true)) { + throw new RuntimeException(sprintf('Cannot create collection: Class %s does not exist', $collectionClass)); + } + + $objects = $this->getObjects($keys, $options); + + return new $collectionClass($objects); + } + + /** + * @param array $keys + * @param array $options Following optional options can be passed: + * types: List of allowed types. + * type: Allowed type if types isn't defined, otherwise acts as default_type. + * default_type: Set default type for objects given without type (only used if key_field isn't set). + * keep_missing: Set to true if you want to return missing objects as null. + * key_field: Key field which is used to match the objects. + * @return array + */ + public function getObjects(array $keys, array $options = []): array + { + $type = $options['type'] ?? null; + $defaultType = $options['default_type'] ?? $type ?? null; + $keyField = $options['key_field'] ?? 'flex_key'; + + // Prepare empty result lists for all requested Flex types. + $types = $options['types'] ?? (array)$type ?: null; + if ($types) { + $types = array_fill_keys($types, []); + } + $strict = isset($types); + + $guessed = []; + if ($keyField === 'flex_key') { + // We need to split Flex key lookups into individual directories. + $undefined = []; + $keyFieldFind = 'storage_key'; + + foreach ($keys as $flexKey) { + if (!$flexKey) { + continue; + } + + $flexKey = (string)$flexKey; + // Normalize key and type using fallback to default type if it was set. + [$key, $type, $guess] = $this->resolveKeyAndType($flexKey, $defaultType); + + if ($type === '' && $types) { + // Add keys which are not associated to any Flex type. They will be included to every Flex type. + foreach ($types as $type => &$array) { + $array[] = $key; + $guessed[$key][] = "{$type}.obj:{$key}"; + } + unset($array); + } elseif (!$strict || isset($types[$type])) { + // Collect keys by their Flex type. If allowed types are defined, only include values from those types. + $types[$type][] = $key; + if ($guess) { + $guessed[$key][] = "{$type}.obj:{$key}"; + } + } + } + } else { + // We are using a specific key field, make every key undefined. + $undefined = $keys; + $keyFieldFind = $keyField; + } + + if (!$types) { + return []; + } + + $list = [[]]; + foreach ($types as $type => $typeKeys) { + // Also remember to look up keys from undefined Flex types. + $lookupKeys = $undefined ? array_merge($typeKeys, $undefined) : $typeKeys; + + $collection = $this->getCollection($type, $lookupKeys, $keyFieldFind); + if ($collection && $keyFieldFind !== $keyField) { + $collection = $collection->withKeyField($keyField); + } + + $list[] = $collection ? $collection->toArray() : []; + } + + // Merge objects from individual types back together. + $list = array_merge(...$list); + + // Use the original key ordering. + if (!$guessed) { + $list = array_replace(array_fill_keys($keys, null), $list); + } else { + // We have mixed keys, we need to map flex keys back to storage keys. + $results = []; + foreach ($keys as $key) { + $flexKey = $guessed[$key] ?? $key; + if (is_array($flexKey)) { + $result = null; + foreach ($flexKey as $tryKey) { + if ($result = $list[$tryKey] ?? null) { + // Use the first matching object (conflicting objects will be ignored for now). + break; + } + } + } else { + $result = $list[$flexKey] ?? null; + } + + $results[$key] = $result; + } + + $list = $results; + } + + // Remove missing objects if not asked to keep them. + if (empty($options['keep_missing'])) { + $list = array_filter($list); + } + + return $list; + } + + /** + * @param string $key + * @param string|null $type + * @param string|null $keyField + * @return FlexObjectInterface|null + */ + public function getObject(string $key, string $type = null, string $keyField = null): ?FlexObjectInterface + { + if (null === $type && null === $keyField) { + // Special handling for quick Flex key lookups. + $keyField = 'storage_key'; + [$key, $type] = $this->resolveKeyAndType($key, $type); + } else { + $type = $this->resolveType($type); + } + + if ($type === '' || $key === '') { + return null; + } + + $directory = $this->getDirectory($type); + + return $directory ? $directory->getObject($key, $keyField) : null; + } + + /** + * @return int + */ + public function count(): int + { + return count($this->types); + } + + /** + * @param string $flexKey + * @param string|null $type + * @return array + */ + protected function resolveKeyAndType(string $flexKey, string $type = null): array + { + $guess = false; + if (strpos($flexKey, ':') !== false) { + [$type, $key] = explode(':', $flexKey, 2); + + $type = $this->resolveType($type); + } else { + $key = $flexKey; + $type = (string)$type; + $guess = true; + } + + return [$key, $type, $guess]; + } + + /** + * @param string|null $type + * @return string + */ + protected function resolveType(string $type = null): string + { + if (null !== $type && strpos($type, '.') !== false) { + return preg_replace('|\.obj$|', '', $type) ?? $type; + } + + return $type ?? ''; + } +} diff --git a/system/src/Grav/Framework/Flex/FlexCollection.php b/system/src/Grav/Framework/Flex/FlexCollection.php new file mode 100644 index 0000000..3e9302c --- /dev/null +++ b/system/src/Grav/Framework/Flex/FlexCollection.php @@ -0,0 +1,733 @@ + + * @implements FlexCollectionInterface + */ +class FlexCollection extends ObjectCollection implements FlexCollectionInterface +{ + /** @var FlexDirectory */ + private $_flexDirectory; + + /** @var string */ + private $_keyField = 'storage_key'; + + /** + * Get list of cached methods. + * + * @return array Returns a list of methods with their caching information. + */ + public static function getCachedMethods(): array + { + return [ + 'getTypePrefix' => true, + 'getType' => true, + 'getFlexDirectory' => true, + 'hasFlexFeature' => true, + 'getFlexFeatures' => true, + 'getCacheKey' => true, + 'getCacheChecksum' => false, + 'getTimestamp' => true, + 'hasProperty' => true, + 'getProperty' => true, + 'hasNestedProperty' => true, + 'getNestedProperty' => true, + 'orderBy' => true, + + 'render' => false, + 'isAuthorized' => 'session', + 'search' => true, + 'sort' => true, + 'getDistinctValues' => true + ]; + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::createFromArray() + */ + public static function createFromArray(array $entries, FlexDirectory $directory, string $keyField = null) + { + $instance = new static($entries, $directory); + $instance->setKeyField($keyField); + + return $instance; + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::__construct() + */ + public function __construct(array $entries = [], FlexDirectory $directory = null) + { + // @phpstan-ignore-next-line + if (get_class($this) === __CLASS__) { + user_error('Using ' . __CLASS__ . ' directly is deprecated since Grav 1.7, use \Grav\Common\Flex\Types\Generic\GenericCollection or your own class instead', E_USER_DEPRECATED); + } + + parent::__construct($entries); + + if ($directory) { + $this->setFlexDirectory($directory)->setKey($directory->getFlexType()); + } + } + + /** + * {@inheritdoc} + * @see FlexCommonInterface::hasFlexFeature() + */ + public function hasFlexFeature(string $name): bool + { + return in_array($name, $this->getFlexFeatures(), true); + } + + /** + * {@inheritdoc} + * @see FlexCommonInterface::hasFlexFeature() + */ + public function getFlexFeatures(): array + { + /** @var array $implements */ + $implements = class_implements($this); + + $list = []; + foreach ($implements as $interface) { + if ($pos = strrpos($interface, '\\')) { + $interface = substr($interface, $pos+1); + } + + $list[] = Inflector::hyphenize(str_replace('Interface', '', $interface)); + } + + return $list; + + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::search() + */ + public function search(string $search, $properties = null, array $options = null) + { + $directory = $this->getFlexDirectory(); + $properties = $directory->getSearchProperties($properties); + $options = $directory->getSearchOptions($options); + + $matching = $this->call('search', [$search, $properties, $options]); + $matching = array_filter($matching); + + if ($matching) { + arsort($matching, SORT_NUMERIC); + } + + /** @var string[] $array */ + $array = array_keys($matching); + + /** @phpstan-var static */ + return $this->select($array); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::sort() + */ + public function sort(array $order) + { + $criteria = Criteria::create()->orderBy($order); + + /** @phpstan-var FlexCollectionInterface $matching */ + $matching = $this->matching($criteria); + + return $matching; + } + + /** + * @param array $filters + * @return static + * @phpstan-return static + */ + public function filterBy(array $filters) + { + $expr = Criteria::expr(); + $criteria = Criteria::create(); + + foreach ($filters as $key => $value) { + $criteria->andWhere($expr->eq($key, $value)); + } + + /** @phpstan-var static */ + return $this->matching($criteria); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getFlexType() + */ + public function getFlexType(): string + { + return $this->_flexDirectory->getFlexType(); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getFlexDirectory() + */ + public function getFlexDirectory(): FlexDirectory + { + return $this->_flexDirectory; + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getTimestamp() + */ + public function getTimestamp(): int + { + $timestamps = $this->getTimestamps(); + + return $timestamps ? max($timestamps) : time(); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getFlexDirectory() + */ + public function getCacheKey(): string + { + return $this->getTypePrefix() . $this->getFlexType() . '.' . sha1((string)json_encode($this->call('getKey'))); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getFlexDirectory() + */ + public function getCacheChecksum(): string + { + $list = []; + /** + * @var string $key + * @var FlexObjectInterface $object + */ + foreach ($this as $key => $object) { + $list[$key] = $object->getCacheChecksum(); + } + + return sha1((string)json_encode($list)); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getFlexDirectory() + */ + public function getTimestamps(): array + { + /** @var int[] $timestamps */ + $timestamps = $this->call('getTimestamp'); + + return $timestamps; + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getFlexDirectory() + */ + public function getStorageKeys(): array + { + /** @var string[] $keys */ + $keys = $this->call('getStorageKey'); + + return $keys; + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getFlexDirectory() + */ + public function getFlexKeys(): array + { + /** @var string[] $keys */ + $keys = $this->call('getFlexKey'); + + return $keys; + } + + /** + * Get all the values in property. + * + * Supports either single scalar values or array of scalar values. + * + * @param string $property Object property to be used to make groups. + * @param string|null $separator Separator, defaults to '.' + * @return array + */ + public function getDistinctValues(string $property, string $separator = null): array + { + $list = []; + + /** @var FlexObjectInterface $element */ + foreach ($this->getIterator() as $element) { + $value = (array)$element->getNestedProperty($property, null, $separator); + foreach ($value as $v) { + if (is_scalar($v)) { + $t = gettype($v) . (string)$v; + $list[$t] = $v; + } + } + } + + return array_values($list); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::withKeyField() + */ + public function withKeyField(string $keyField = null) + { + $keyField = $keyField ?: 'key'; + if ($keyField === $this->getKeyField()) { + return $this; + } + + $entries = []; + foreach ($this as $key => $object) { + // TODO: remove hardcoded logic + if ($keyField === 'storage_key') { + $entries[$object->getStorageKey()] = $object; + } elseif ($keyField === 'flex_key') { + $entries[$object->getFlexKey()] = $object; + } elseif ($keyField === 'key') { + $entries[$object->getKey()] = $object; + } + } + + return $this->createFrom($entries, $keyField); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getIndex() + */ + public function getIndex() + { + /** @phpstan-var FlexIndexInterface */ + return $this->getFlexDirectory()->getIndex($this->getKeys(), $this->getKeyField()); + } + + /** + * @inheritdoc} + * @see FlexCollectionInterface::getCollection() + * @return $this + */ + public function getCollection() + { + return $this; + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::render() + */ + public function render(string $layout = null, array $context = []) + { + if (!$layout) { + $config = $this->getTemplateConfig(); + $layout = $config['collection']['defaults']['layout'] ?? 'default'; + } + + $type = $this->getFlexType(); + + $grav = Grav::instance(); + + /** @var Debugger $debugger */ + $debugger = $grav['debugger']; + $debugger->startTimer('flex-collection-' . ($debugKey = uniqid($type, false)), 'Render Collection ' . $type . ' (' . $layout . ')'); + + $key = null; + foreach ($context as $value) { + if (!is_scalar($value)) { + $key = false; + break; + } + } + + if ($key !== false) { + $key = md5($this->getCacheKey() . '.' . $layout . json_encode($context)); + $cache = $this->getCache('render'); + } else { + $cache = null; + } + + try { + $data = $cache && $key ? $cache->get($key) : null; + + $block = $data ? HtmlBlock::fromArray($data) : null; + } catch (InvalidArgumentException $e) { + $debugger->addException($e); + $block = null; + } catch (\InvalidArgumentException $e) { + $debugger->addException($e); + $block = null; + } + + $checksum = $this->getCacheChecksum(); + if ($block && $checksum !== $block->getChecksum()) { + $block = null; + } + + if (!$block) { + $block = HtmlBlock::create($key ?: null); + $block->setChecksum($checksum); + if (!$key) { + $block->disableCache(); + } + + $event = new Event([ + 'type' => 'flex', + 'directory' => $this->getFlexDirectory(), + 'collection' => $this, + 'layout' => &$layout, + 'context' => &$context + ]); + $this->triggerEvent('onRender', $event); + + $output = $this->getTemplate($layout)->render( + [ + 'grav' => $grav, + 'config' => $grav['config'], + 'block' => $block, + 'directory' => $this->getFlexDirectory(), + 'collection' => $this, + 'layout' => $layout + ] + $context + ); + + if ($debugger->enabled() && + !($grav['uri']->getContentType() === 'application/json' || $grav['uri']->extension() === 'json')) { + $output = "\n\n{$output}\n\n"; + } + + $block->setContent($output); + + try { + $cache && $key && $block->isCached() && $cache->set($key, $block->toArray()); + } catch (InvalidArgumentException $e) { + $debugger->addException($e); + } + } + + $debugger->stopTimer('flex-collection-' . $debugKey); + + return $block; + } + + /** + * @param FlexDirectory $type + * @return $this + */ + public function setFlexDirectory(FlexDirectory $type) + { + $this->_flexDirectory = $type; + + return $this; + } + + /** + * @param string $key + * @return array + */ + public function getMetaData($key): array + { + $object = $this->get($key); + + return $object instanceof FlexObjectInterface ? $object->getMetaData() : []; + } + + /** + * @param string|null $namespace + * @return CacheInterface + */ + public function getCache(string $namespace = null) + { + return $this->_flexDirectory->getCache($namespace); + } + + /** + * @return string + */ + public function getKeyField(): string + { + return $this->_keyField; + } + + /** + * @param string $action + * @param string|null $scope + * @param UserInterface|null $user + * @return static + * @phpstan-return static + */ + public function isAuthorized(string $action, string $scope = null, UserInterface $user = null) + { + $list = $this->call('isAuthorized', [$action, $scope, $user]); + $list = array_filter($list); + + /** @var string[] $keys */ + $keys = array_keys($list); + + /** @phpstan-var static */ + return $this->select($keys); + } + + /** + * @param string $value + * @param string $field + * @return FlexObjectInterface|null + * @phpstan-return T|null + */ + public function find($value, $field = 'id') + { + if ($value) { + foreach ($this as $element) { + if (mb_strtolower($element->getProperty($field)) === mb_strtolower($value)) { + return $element; + } + } + } + + return null; + } + + /** + * @return array + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + $elements = []; + + /** + * @var string $key + * @var array|FlexObject $object + */ + foreach ($this->getElements() as $key => $object) { + $elements[$key] = is_array($object) ? $object : $object->jsonSerialize(); + } + + return $elements; + } + + /** + * @return array + */ + #[\ReturnTypeWillChange] + public function __debugInfo() + { + return [ + 'type:private' => $this->getFlexType(), + 'key:private' => $this->getKey(), + 'objects_key:private' => $this->getKeyField(), + 'objects:private' => $this->getElements() + ]; + } + + /** + * Creates a new instance from the specified elements. + * + * This method is provided for derived classes to specify how a new + * instance should be created when constructor semantics have changed. + * + * @param array $elements Elements. + * @param string|null $keyField + * @return static + * @phpstan-return static + * @throws \InvalidArgumentException + */ + protected function createFrom(array $elements, $keyField = null) + { + $collection = new static($elements, $this->_flexDirectory); + $collection->setKeyField($keyField ?: $this->_keyField); + + return $collection; + } + + /** + * @return string + */ + protected function getTypePrefix(): string + { + return 'c.'; + } + + /** + * @return array + */ + protected function getTemplateConfig(): array + { + $config = $this->getFlexDirectory()->getConfig('site.templates', []); + $defaults = array_replace($config['defaults'] ?? [], $config['collection']['defaults'] ?? []); + $config['collection']['defaults'] = $defaults; + + return $config; + } + + /** + * @param string $layout + * @return array + */ + protected function getTemplatePaths(string $layout): array + { + $config = $this->getTemplateConfig(); + $type = $this->getFlexType(); + $defaults = $config['collection']['defaults'] ?? []; + + $ext = $defaults['ext'] ?? '.html.twig'; + $types = array_unique(array_merge([$type], (array)($defaults['type'] ?? null))); + $paths = $config['collection']['paths'] ?? [ + 'flex/{TYPE}/collection/{LAYOUT}{EXT}', + 'flex-objects/layouts/{TYPE}/collection/{LAYOUT}{EXT}' + ]; + $table = ['TYPE' => '%1$s', 'LAYOUT' => '%2$s', 'EXT' => '%3$s']; + + $lookups = []; + foreach ($paths as $path) { + $path = Utils::simpleTemplate($path, $table); + foreach ($types as $type) { + $lookups[] = sprintf($path, $type, $layout, $ext); + } + } + + return array_unique($lookups); + } + + /** + * @param string $layout + * @return Template|TemplateWrapper + * @throws LoaderError + * @throws SyntaxError + */ + protected function getTemplate($layout) + { + $grav = Grav::instance(); + + /** @var Twig $twig */ + $twig = $grav['twig']; + + try { + return $twig->twig()->resolveTemplate($this->getTemplatePaths($layout)); + } catch (LoaderError $e) { + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $debugger->addException($e); + + return $twig->twig()->resolveTemplate(['flex/404.html.twig']); + } + } + + /** + * @param string $type + * @return FlexDirectory + */ + protected function getRelatedDirectory($type): ?FlexDirectory + { + /** @var Flex $flex */ + $flex = Grav::instance()['flex']; + + return $flex->getDirectory($type); + } + + /** + * @param string|null $keyField + * @return void + */ + protected function setKeyField($keyField = null): void + { + $this->_keyField = $keyField ?? 'storage_key'; + } + + // DEPRECATED METHODS + + /** + * @param bool $prefix + * @return string + * @deprecated 1.6 Use `->getFlexType()` instead. + */ + public function getType($prefix = false) + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use ->getFlexType() method instead', E_USER_DEPRECATED); + + $type = $prefix ? $this->getTypePrefix() : ''; + + return $type . $this->getFlexType(); + } + + /** + * @param string $name + * @param object|null $event + * @return $this + * @deprecated 1.7, moved to \Grav\Common\Flex\Traits\FlexObjectTrait + */ + public function triggerEvent(string $name, $event = null) + { + user_error(__METHOD__ . '() is deprecated since Grav 1.7, moved to \Grav\Common\Flex\Traits\FlexObjectTrait', E_USER_DEPRECATED); + + if (null === $event) { + $event = new Event([ + 'type' => 'flex', + 'directory' => $this->getFlexDirectory(), + 'collection' => $this + ]); + } + if (strpos($name, 'onFlexCollection') !== 0 && strpos($name, 'on') === 0) { + $name = 'onFlexCollection' . substr($name, 2); + } + + $grav = Grav::instance(); + if ($event instanceof Event) { + $grav->fireEvent($name, $event); + } else { + $grav->dispatchEvent($event); + } + + + return $this; + } +} diff --git a/system/src/Grav/Framework/Flex/FlexDirectory.php b/system/src/Grav/Framework/Flex/FlexDirectory.php new file mode 100644 index 0000000..2871597 --- /dev/null +++ b/system/src/Grav/Framework/Flex/FlexDirectory.php @@ -0,0 +1,1187 @@ +[] + */ + protected $indexes = []; + /** + * @var FlexCollectionInterface|null + * @phpstan-var FlexCollectionInterface|null + */ + protected $collection; + /** @var bool */ + protected $enabled; + /** @var array */ + protected $defaults; + /** @var Config */ + protected $config; + /** @var FlexStorageInterface */ + protected $storage; + /** @var CacheInterface[] */ + protected $cache; + /** @var FlexObjectInterface[] */ + protected $objects; + /** @var string */ + protected $objectClassName; + /** @var string */ + protected $collectionClassName; + /** @var string */ + protected $indexClassName; + + /** @var string|null */ + private $_authorize; + + /** + * FlexDirectory constructor. + * @param string $type + * @param string $blueprint_file + * @param array $defaults + */ + public function __construct(string $type, string $blueprint_file, array $defaults = []) + { + $this->type = $type; + $this->blueprints = []; + $this->blueprint_file = $blueprint_file; + $this->defaults = $defaults; + $this->enabled = !empty($defaults['enabled']); + $this->objects = []; + } + + /** + * @return bool + */ + public function isListed(): bool + { + $grav = Grav::instance(); + + /** @var Flex $flex */ + $flex = $grav['flex']; + $directory = $flex->getDirectory($this->type); + + return null !== $directory; + } + + /** + * @return bool + */ + public function isEnabled(): bool + { + return $this->enabled; + } + + /** + * @return string + */ + public function getFlexType(): string + { + return $this->type; + } + + /** + * @return string + */ + public function getTitle(): string + { + return $this->getBlueprintInternal()->get('title', ucfirst($this->getFlexType())); + } + + /** + * @return string + */ + public function getDescription(): string + { + return $this->getBlueprintInternal()->get('description', ''); + } + + /** + * @param string|null $name + * @param mixed $default + * @return mixed + */ + public function getConfig(string $name = null, $default = null) + { + if (null === $this->config) { + $config = $this->getBlueprintInternal()->get('config', []); + $config = is_array($config) ? array_replace_recursive($config, $this->defaults, $this->getDirectoryConfig($config['admin']['views']['configure']['form'] ?? $config['admin']['configure']['form'] ?? null)) : null; + if (!is_array($config)) { + throw new RuntimeException('Bad configuration'); + } + + $this->config = new Config($config); + } + + return null === $name ? $this->config : $this->config->get($name, $default); + } + + /** + * @param string|string[]|null $properties + * @return array + */ + public function getSearchProperties($properties = null): array + { + if (null !== $properties) { + return (array)$properties; + } + + $properties = $this->getConfig('data.search.fields'); + if (!$properties) { + $fields = $this->getConfig('admin.views.list.fields') ?? $this->getConfig('admin.list.fields', []); + foreach ($fields as $property => $value) { + if (!empty($value['link'])) { + $properties[] = $property; + } + } + } + + return $properties; + } + + /** + * @param array|null $options + * @return array + */ + public function getSearchOptions(array $options = null): array + { + if (empty($options['merge'])) { + return $options ?? (array)$this->getConfig('data.search.options'); + } + + unset($options['merge']); + + return $options + (array)$this->getConfig('data.search.options'); + } + + /** + * @param string|null $name + * @param array $options + * @return FlexFormInterface + * @internal + */ + public function getDirectoryForm(string $name = null, array $options = []) + { + $name = $name ?: $this->getConfig('admin.views.configure.form', '') ?: $this->getConfig('admin.configure.form', ''); + + return new FlexDirectoryForm($name ?? '', $this, $options); + } + + /** + * @return Blueprint + * @internal + */ + public function getDirectoryBlueprint() + { + $name = 'configure'; + + $type = $this->getBlueprint(); + $overrides = $type->get("blueprints/{$name}"); + + $path = "blueprints://flex/shared/{$name}.yaml"; + $blueprint = new Blueprint($path); + $blueprint->load(); + if (isset($overrides['fields'])) { + $blueprint->embed('form/fields/tabs/fields', $overrides['fields']); + } + $blueprint->init(); + + return $blueprint; + } + + /** + * @param string $name + * @param array $data + * @return void + * @throws Exception + * @internal + */ + public function saveDirectoryConfig(string $name, array $data) + { + $grav = Grav::instance(); + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + + $filename = $this->getDirectoryConfigUri($name); + if (file_exists($filename)) { + $filename = $locator->findResource($filename, true); + } else { + $filesystem = Filesystem::getInstance(); + $dirname = $filesystem->dirname($filename); + $basename = $filesystem->basename($filename); + $dirname = $locator->findResource($dirname, true) ?: $locator->findResource($dirname, true, true); + $filename = "{$dirname}/{$basename}"; + } + + $file = YamlFile::instance($filename); + if (!empty($data)) { + $file->save($data); + } else { + $file->delete(); + } + } + + /** + * @param string $name + * @return array + * @internal + */ + public function loadDirectoryConfig(string $name): array + { + $grav = Grav::instance(); + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + $uri = $this->getDirectoryConfigUri($name); + + // If configuration is found in main configuration, use it. + if (str_starts_with($uri, 'config://')) { + $path = str_replace('/', '.', substr($uri, 9, -5)); + + return (array)$grav['config']->get($path); + } + + // Load the configuration file. + $filename = $locator->findResource($uri, true); + if ($filename === false) { + return []; + } + + $file = YamlFile::instance($filename); + + return $file->content(); + } + + /** + * @param string|null $name + * @return string + */ + public function getDirectoryConfigUri(string $name = null): string + { + $name = $name ?: $this->getFlexType(); + $blueprint = $this->getBlueprint(); + + return $blueprint->get('blueprints/views/configure/file') ?? $blueprint->get('blueprints/configure/file') ?? "config://flex/{$name}.yaml"; + } + + /** + * @param string|null $name + * @return array + */ + protected function getDirectoryConfig(string $name = null): array + { + $grav = Grav::instance(); + + /** @var Config $config */ + $config = $grav['config']; + $name = $name ?: $this->getFlexType(); + + return $config->get("flex.{$name}", []); + } + + /** + * Returns a new uninitialized instance of blueprint. + * + * Always use $object->getBlueprint() or $object->getForm()->getBlueprint() instead. + * + * @param string $type + * @param string $context + * @return Blueprint + */ + public function getBlueprint(string $type = '', string $context = '') + { + return clone $this->getBlueprintInternal($type, $context); + } + + /** + * @param string $view + * @return string + */ + public function getBlueprintFile(string $view = ''): string + { + $file = $this->blueprint_file; + if ($view !== '') { + $file = preg_replace('/\.yaml/', "/{$view}.yaml", $file); + } + + return (string)$file; + } + + /** + * Get collection. In the site this will be filtered by the default filters (published etc). + * + * Use $directory->getIndex() if you want unfiltered collection. + * + * @param array|null $keys Array of keys. + * @param string|null $keyField Field to be used as the key. + * @return FlexCollectionInterface + * @phpstan-return FlexCollectionInterface + */ + public function getCollection(array $keys = null, string $keyField = null): FlexCollectionInterface + { + // Get all selected entries. + $index = $this->getIndex($keys, $keyField); + + if (!Utils::isAdminPlugin()) { + // If not in admin, filter the list by using default filters. + $filters = (array)$this->getConfig('site.filter', []); + + foreach ($filters as $filter) { + $index = $index->{$filter}(); + } + } + + return $index; + } + + /** + * Get the full collection of all stored objects. + * + * Use $directory->getCollection() if you want a filtered collection. + * + * @param array|null $keys Array of keys. + * @param string|null $keyField Field to be used as the key. + * @return FlexIndexInterface + * @phpstan-return FlexIndexInterface + */ + public function getIndex(array $keys = null, string $keyField = null): FlexIndexInterface + { + $keyField = $keyField ?? ''; + $index = $this->indexes[$keyField] ?? $this->loadIndex($keyField); + $index = clone $index; + + if (null !== $keys) { + /** @var FlexIndexInterface $index */ + $index = $index->select($keys); + } + + return $index->getIndex(); + } + + /** + * Returns an object if it exists. If no arguments are passed (or both of them are null), method creates a new empty object. + * + * Note: It is not safe to use the object without checking if the user can access it. + * + * @param string|null $key + * @param string|null $keyField Field to be used as the key. + * @return FlexObjectInterface|null + */ + public function getObject($key = null, string $keyField = null): ?FlexObjectInterface + { + if (null === $key) { + return $this->createObject([], ''); + } + + $keyField = $keyField ?? ''; + $index = $this->indexes[$keyField] ?? $this->loadIndex($keyField); + + return $index->get($key); + } + + /** + * @param string|null $namespace + * @return CacheInterface + */ + public function getCache(string $namespace = null) + { + $namespace = $namespace ?: 'index'; + $cache = $this->cache[$namespace] ?? null; + + if (null === $cache) { + try { + $grav = Grav::instance(); + + /** @var Cache $gravCache */ + $gravCache = $grav['cache']; + $config = $this->getConfig('object.cache.' . $namespace); + if (empty($config['enabled'])) { + $cache = new MemoryCache('flex-objects-' . $this->getFlexType()); + } else { + $lifetime = $config['lifetime'] ?? 60; + + $key = $gravCache->getKey(); + if (Utils::isAdminPlugin()) { + $key = substr($key, 0, -1); + } + $cache = new DoctrineCache($gravCache->getCacheDriver(), 'flex-objects-' . $this->getFlexType() . $key, $lifetime); + } + } catch (Exception $e) { + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $debugger->addException($e); + + $cache = new MemoryCache('flex-objects-' . $this->getFlexType()); + } + + // Disable cache key validation. + $cache->setValidation(false); + $this->cache[$namespace] = $cache; + } + + return $cache; + } + + /** + * @return $this + */ + public function clearCache() + { + $grav = Grav::instance(); + + /** @var Debugger $debugger */ + $debugger = $grav['debugger']; + $debugger->addMessage(sprintf('Flex: Clearing all %s cache', $this->type), 'debug'); + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + $locator->clearCache(); + + $this->getCache('index')->clear(); + $this->getCache('object')->clear(); + $this->getCache('render')->clear(); + + $this->indexes = []; + $this->objects = []; + + return $this; + } + + /** + * @param string|null $key + * @return string|null + */ + public function getStorageFolder(string $key = null): ?string + { + return $this->getStorage()->getStoragePath($key); + } + + /** + * @param string|null $key + * @return string|null + */ + public function getMediaFolder(string $key = null): ?string + { + return $this->getStorage()->getMediaPath($key); + } + + /** + * @return FlexStorageInterface + */ + public function getStorage(): FlexStorageInterface + { + if (null === $this->storage) { + $this->storage = $this->createStorage(); + } + + return $this->storage; + } + + /** + * @param array $data + * @param string $key + * @param bool $validate + * @return FlexObjectInterface + */ + public function createObject(array $data, string $key = '', bool $validate = false): FlexObjectInterface + { + /** @phpstan-var class-string $className */ + $className = $this->objectClassName ?: $this->getObjectClass(); + if (!is_a($className, FlexObjectInterface::class, true)) { + throw new \RuntimeException('Bad object class: ' . $className); + } + + return new $className($data, $key, $this, $validate); + } + + /** + * @param array $entries + * @param string|null $keyField + * @return FlexCollectionInterface + * @phpstan-return FlexCollectionInterface + */ + public function createCollection(array $entries, string $keyField = null): FlexCollectionInterface + { + /** phpstan-var class-string $className */ + $className = $this->collectionClassName ?: $this->getCollectionClass(); + if (!is_a($className, FlexCollectionInterface::class, true)) { + throw new \RuntimeException('Bad collection class: ' . $className); + } + + return $className::createFromArray($entries, $this, $keyField); + } + + /** + * @param array $entries + * @param string|null $keyField + * @return FlexIndexInterface + * @phpstan-return FlexIndexInterface + */ + public function createIndex(array $entries, string $keyField = null): FlexIndexInterface + { + /** @phpstan-var class-string $className */ + $className = $this->indexClassName ?: $this->getIndexClass(); + if (!is_a($className, FlexIndexInterface::class, true)) { + throw new \RuntimeException('Bad index class: ' . $className); + } + + return $className::createFromArray($entries, $this, $keyField); + } + + /** + * @return string + */ + public function getObjectClass(): string + { + if (!$this->objectClassName) { + $this->objectClassName = $this->getConfig('data.object', GenericObject::class); + } + + return $this->objectClassName; + } + + /** + * @return string + */ + public function getCollectionClass(): string + { + if (!$this->collectionClassName) { + $this->collectionClassName = $this->getConfig('data.collection', GenericCollection::class); + } + + return $this->collectionClassName; + } + + + /** + * @return string + */ + public function getIndexClass(): string + { + if (!$this->indexClassName) { + $this->indexClassName = $this->getConfig('data.index', GenericIndex::class); + } + + return $this->indexClassName; + } + + /** + * @param array $entries + * @param string|null $keyField + * @return FlexCollectionInterface + * @phpstan-return FlexCollectionInterface + */ + public function loadCollection(array $entries, string $keyField = null): FlexCollectionInterface + { + return $this->createCollection($this->loadObjects($entries), $keyField); + } + + /** + * @param array $entries + * @return FlexObjectInterface[] + * @internal + */ + public function loadObjects(array $entries): array + { + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + + $keys = []; + $rows = []; + $fetch = []; + + // Build lookup arrays with storage keys for the objects. + foreach ($entries as $key => $value) { + $k = $value['storage_key'] ?? ''; + if ($k === '') { + continue; + } + $v = $this->objects[$k] ?? null; + $keys[$k] = $key; + $rows[$k] = $v; + if (!$v) { + $fetch[] = $k; + } + } + + // Attempt to fetch missing rows from the cache. + if ($fetch) { + $rows = (array)array_replace($rows, $this->loadCachedObjects($fetch)); + } + + // Read missing rows from the storage. + $updated = []; + $storage = $this->getStorage(); + $rows = $storage->readRows($rows, $updated); + + // Create objects from the rows. + $isListed = $this->isListed(); + $list = []; + foreach ($rows as $storageKey => $row) { + $usedKey = $keys[$storageKey]; + + if ($row instanceof FlexObjectInterface) { + $object = $row; + } else { + if ($row === null) { + $debugger->addMessage(sprintf('Flex: Object %s was not found from %s storage', $storageKey, $this->type), 'debug'); + continue; + } + + if (isset($row['__ERROR'])) { + $message = sprintf('Flex: Object %s is broken in %s storage: %s', $storageKey, $this->type, $row['__ERROR']); + $debugger->addException(new RuntimeException($message)); + $debugger->addMessage($message, 'error'); + continue; + } + + if (!isset($row['__META'])) { + $row['__META'] = [ + 'storage_key' => $storageKey, + 'storage_timestamp' => $entries[$usedKey]['storage_timestamp'] ?? 0, + ]; + } + + $key = $row['__META']['key'] ?? $entries[$usedKey]['key'] ?? $usedKey; + $object = $this->createObject($row, $key, false); + $this->objects[$storageKey] = $object; + if ($isListed) { + // If unserialize works for the object, serialize the object to speed up the loading. + $updated[$storageKey] = $object; + } + } + + $list[$usedKey] = $object; + } + + // Store updated rows to the cache. + if ($updated) { + $cache = $this->getCache('object'); + if (!$cache instanceof MemoryCache) { + ///** @var Debugger $debugger */ + //$debugger = Grav::instance()['debugger']; + //$debugger->addMessage(sprintf('Flex: Caching %d %s', \count($entries), $this->type), 'debug'); + } + try { + $cache->setMultiple($updated); + } catch (InvalidArgumentException $e) { + $debugger->addException($e); + // TODO: log about the issue. + } + } + + if ($fetch) { + $debugger->stopTimer('flex-objects'); + } + + return $list; + } + + protected function loadCachedObjects(array $fetch): array + { + if (!$fetch) { + return []; + } + + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + + $cache = $this->getCache('object'); + + // Attempt to fetch missing rows from the cache. + $fetched = []; + try { + $loading = count($fetch); + + $debugger->startTimer('flex-objects', sprintf('Flex: Loading %d %s', $loading, $this->type)); + + $fetched = (array)$cache->getMultiple($fetch); + if ($fetched) { + $index = $this->loadIndex('storage_key'); + + // Make sure cached objects are up to date: compare against index checksum/timestamp. + /** + * @var string $key + * @var mixed $value + */ + foreach ($fetched as $key => $value) { + if ($value instanceof FlexObjectInterface) { + $objectMeta = $value->getMetaData(); + } else { + $objectMeta = $value['__META'] ?? []; + } + $indexMeta = $index->getMetaData($key); + + $indexChecksum = $indexMeta['checksum'] ?? $indexMeta['storage_timestamp'] ?? null; + $objectChecksum = $objectMeta['checksum'] ?? $objectMeta['storage_timestamp'] ?? null; + if ($indexChecksum !== $objectChecksum) { + unset($fetched[$key]); + } + } + } + + } catch (InvalidArgumentException $e) { + $debugger->addException($e); + } + + return $fetched; + } + + /** + * @return void + */ + public function reloadIndex(): void + { + $this->getCache('index')->clear(); + $this->getIndex()::loadEntriesFromStorage($this->getStorage()); + + $this->indexes = []; + $this->objects = []; + } + + /** + * @param string $scope + * @param string $action + * @return string + */ + public function getAuthorizeRule(string $scope, string $action): string + { + if (!$this->_authorize) { + $config = $this->getConfig('admin.permissions'); + if ($config) { + $this->_authorize = array_key_first($config) . '.%2$s'; + } else { + $this->_authorize = '%1$s.flex-object.%2$s'; + } + } + + return sprintf($this->_authorize, $scope, $action); + } + + /** + * @param string $type_view + * @param string $context + * @return Blueprint + */ + protected function getBlueprintInternal(string $type_view = '', string $context = '') + { + if (!isset($this->blueprints[$type_view])) { + if (!file_exists($this->blueprint_file)) { + throw new RuntimeException(sprintf('Flex: Blueprint file for %s is missing', $this->type)); + } + + $parts = explode('.', rtrim($type_view, '.'), 2); + $type = array_shift($parts); + $view = array_shift($parts) ?: ''; + + $blueprint = new Blueprint($this->getBlueprintFile($view)); + $blueprint->addDynamicHandler('data', function (array &$field, $property, array &$call) { + $this->dynamicDataField($field, $property, $call); + }); + $blueprint->addDynamicHandler('flex', function (array &$field, $property, array &$call) { + $this->dynamicFlexField($field, $property, $call); + }); + $blueprint->addDynamicHandler('authorize', function (array &$field, $property, array &$call) { + $this->dynamicAuthorizeField($field, $property, $call); + }); + + if ($context) { + $blueprint->setContext($context); + } + + $blueprint->load($type ?: null); + if ($blueprint->get('type') === 'flex-objects' && isset(Grav::instance()['admin'])) { + $blueprintBase = (new Blueprint('plugin://flex-objects/blueprints/flex-objects.yaml'))->load(); + $blueprint->extend($blueprintBase, true); + } + + $this->blueprints[$type_view] = $blueprint; + } + + return $this->blueprints[$type_view]; + } + + /** + * @param array $field + * @param string $property + * @param array $call + * @return void + */ + protected function dynamicDataField(array &$field, $property, array $call) + { + $params = $call['params']; + if (is_array($params)) { + $function = array_shift($params); + } else { + $function = $params; + $params = []; + } + + $object = $call['object']; + if ($function === '\Grav\Common\Page\Pages::pageTypes') { + $params = [$object instanceof PageInterface && $object->isModule() ? 'modular' : 'standard']; + } + + $data = null; + if (is_callable($function)) { + $data = call_user_func_array($function, $params); + } + + // If function returns a value, + if (null !== $data) { + if (is_array($data) && isset($field[$property]) && is_array($field[$property])) { + // Combine field and @data-field together. + $field[$property] += $data; + } else { + // Or create/replace field with @data-field. + $field[$property] = $data; + } + } + } + + /** + * @param array $field + * @param string $property + * @param array $call + * @return void + */ + protected function dynamicFlexField(array &$field, $property, array $call): void + { + $params = (array)$call['params']; + $object = $call['object'] ?? null; + $method = array_shift($params); + $not = false; + if (str_starts_with($method, '!')) { + $method = substr($method, 1); + $not = true; + } elseif (str_starts_with($method, 'not ')) { + $method = substr($method, 4); + $not = true; + } + $method = trim($method); + + if ($object && method_exists($object, $method)) { + $value = $object->{$method}(...$params); + if (is_array($value) && isset($field[$property]) && is_array($field[$property])) { + $value = $this->mergeArrays($field[$property], $value); + } + $value = $not ? !$value : $value; + + if ($property === 'ignore' && $value) { + Blueprint::addPropertyRecursive($field, 'validate', ['ignore' => true]); + } else { + $field[$property] = $value; + } + } + } + + /** + * @param array $field + * @param string $property + * @param array $call + * @return void + */ + protected function dynamicAuthorizeField(array &$field, $property, array $call): void + { + $params = (array)$call['params']; + $object = $call['object'] ?? null; + $permission = array_shift($params); + $not = false; + if (str_starts_with($permission, '!')) { + $permission = substr($permission, 1); + $not = true; + } elseif (str_starts_with($permission, 'not ')) { + $permission = substr($permission, 4); + $not = true; + } + $permission = trim($permission); + + if ($object) { + $value = $object->isAuthorized($permission) ?? false; + + $field[$property] = $not ? !$value : $value; + } + } + + /** + * @param array $array1 + * @param array $array2 + * @return array + */ + protected function mergeArrays(array $array1, array $array2): array + { + foreach ($array2 as $key => $value) { + if (is_array($value) && isset($array1[$key]) && is_array($array1[$key])) { + $array1[$key] = $this->mergeArrays($array1[$key], $value); + } else { + $array1[$key] = $value; + } + } + + return $array1; + } + + /** + * @return FlexStorageInterface + */ + protected function createStorage(): FlexStorageInterface + { + $this->collection = $this->createCollection([]); + + $storage = $this->getConfig('data.storage'); + + if (!is_array($storage)) { + $storage = ['options' => ['folder' => $storage]]; + } + + $className = $storage['class'] ?? SimpleStorage::class; + $options = $storage['options'] ?? []; + + if (!is_a($className, FlexStorageInterface::class, true)) { + throw new \RuntimeException('Bad storage class: ' . $className); + } + + return new $className($options); + } + + /** + * @param string $keyField + * @return FlexIndexInterface + * @phpstan-return FlexIndexInterface + */ + protected function loadIndex(string $keyField): FlexIndexInterface + { + static $i = 0; + + $index = $this->indexes[$keyField] ?? null; + if (null !== $index) { + return $index; + } + + $index = $this->indexes['storage_key'] ?? null; + if (null === $index) { + $i++; + $j = $i; + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $debugger->startTimer('flex-keys-' . $this->type . $j, "Flex: Loading {$this->type} index"); + + $storage = $this->getStorage(); + $cache = $this->getCache('index'); + + try { + $keys = $cache->get('__keys'); + } catch (InvalidArgumentException $e) { + $debugger->addException($e); + $keys = null; + } + + if (!is_array($keys)) { + /** @phpstan-var class-string $className */ + $className = $this->getIndexClass(); + $keys = $className::loadEntriesFromStorage($storage); + if (!$cache instanceof MemoryCache) { + $debugger->addMessage( + sprintf('Flex: Caching %s index of %d objects', $this->type, count($keys)), + 'debug' + ); + } + try { + $cache->set('__keys', $keys); + } catch (InvalidArgumentException $e) { + $debugger->addException($e); + // TODO: log about the issue. + } + } + + $ordering = $this->getConfig('data.ordering', []); + + // We need to do this in two steps as orderBy() calls loadIndex() again and we do not want infinite loop. + $this->indexes['storage_key'] = $index = $this->createIndex($keys, 'storage_key'); + if ($ordering) { + /** @var FlexCollectionInterface $collection */ + $collection = $this->indexes['storage_key']->orderBy($ordering); + $this->indexes['storage_key'] = $index = $collection->getIndex(); + } + + $debugger->stopTimer('flex-keys-' . $this->type . $j); + } + + if ($keyField !== 'storage_key') { + $this->indexes[$keyField] = $index = $index->withKeyField($keyField ?: null); + } + + return $index; + } + + /** + * @param string $action + * @return string + */ + protected function getAuthorizeAction(string $action): string + { + // Handle special action save, which can mean either update or create. + if ($action === 'save') { + $action = 'create'; + } + + return $action; + } + /** + * @return UserInterface|null + */ + protected function getActiveUser(): ?UserInterface + { + /** @var UserInterface|null $user */ + $user = Grav::instance()['user'] ?? null; + + return $user; + } + + /** + * @return string + */ + protected function getAuthorizeScope(): string + { + return isset(Grav::instance()['admin']) ? 'admin' : 'site'; + } + + // DEPRECATED METHODS + + /** + * @return string + * @deprecated 1.6 Use ->getFlexType() method instead. + */ + public function getType(): string + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use ->getFlexType() method instead', E_USER_DEPRECATED); + + return $this->type; + } + + /** + * @param array $data + * @param string|null $key + * @return FlexObjectInterface + * @deprecated 1.7 Use $object->update()->save() instead. + */ + public function update(array $data, string $key = null): FlexObjectInterface + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() should not be used anymore: use $object->update()->save() instead.', E_USER_DEPRECATED); + + $object = null !== $key ? $this->getIndex()->get($key): null; + + $storage = $this->getStorage(); + + if (null === $object) { + $object = $this->createObject($data, $key ?? '', true); + $key = $object->getStorageKey(); + + if ($key) { + $storage->replaceRows([$key => $object->prepareStorage()]); + } else { + $storage->createRows([$object->prepareStorage()]); + } + } else { + $oldKey = $object->getStorageKey(); + $object->update($data); + $newKey = $object->getStorageKey(); + + if ($oldKey !== $newKey) { + if (method_exists($object, 'triggerEvent')) { + $object->triggerEvent('move'); + } + $storage->renameRow($oldKey, $newKey); + // TODO: media support. + } + + $object->save(); + } + + try { + $this->clearCache(); + } catch (InvalidArgumentException $e) { + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $debugger->addException($e); + + // Caching failed, but we can ignore that for now. + } + + return $object; + } + + /** + * @param string $key + * @return FlexObjectInterface|null + * @deprecated 1.7 Use $object->delete() instead. + */ + public function remove(string $key): ?FlexObjectInterface + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() should not be used anymore: use $object->delete() instead.', E_USER_DEPRECATED); + + $object = $this->getIndex()->get($key); + if (!$object) { + return null; + } + + $object->delete(); + + return $object; + } +} diff --git a/system/src/Grav/Framework/Flex/FlexDirectoryForm.php b/system/src/Grav/Framework/Flex/FlexDirectoryForm.php new file mode 100644 index 0000000..459fb49 --- /dev/null +++ b/system/src/Grav/Framework/Flex/FlexDirectoryForm.php @@ -0,0 +1,509 @@ +getDirectoryForm($name, $options); + } + + /** + * FlexForm constructor. + * @param string $name + * @param FlexDirectory $directory + * @param array|null $options + */ + public function __construct(string $name, FlexDirectory $directory, array $options = null) + { + $this->name = $name; + $this->setDirectory($directory); + $this->setName($directory->getFlexType(), $name); + $this->setId($this->getName()); + + $uniqueId = $options['unique_id'] ?? null; + if (!$uniqueId) { + $uniqueId = md5($directory->getFlexType() . '-directory-' . $this->name); + } + $this->setUniqueId($uniqueId); + + $this->setFlashLookupFolder($directory->getDirectoryBlueprint()->get('form/flash_folder') ?? 'tmp://forms/[SESSIONID]'); + $this->form = $options['form'] ?? null; + + if (Utils::isPositive($this->form['disabled'] ?? false)) { + $this->disable(); + } + + $this->initialize(); + } + + /** + * @return $this + */ + public function initialize() + { + $this->messages = []; + $this->submitted = false; + $this->data = new Data($this->directory->loadDirectoryConfig($this->name), $this->getBlueprint()); + $this->files = []; + $this->unsetFlash(); + + /** @var FlexFormFlash $flash */ + $flash = $this->getFlash(); + if ($flash->exists()) { + $data = $flash->getData(); + $includeOriginal = (bool)($this->getBlueprint()->form()['images']['original'] ?? null); + + $directory = $flash->getDirectory(); + if (null === $directory) { + throw new RuntimeException('Flash has no directory'); + } + $this->directory = $directory; + $this->data = $data ? new Data($data, $this->getBlueprint()) : null; + $this->files = $flash->getFilesByFields($includeOriginal); + } + + return $this; + } + + /** + * @param string $uniqueId + * @return void + */ + public function setUniqueId(string $uniqueId): void + { + if ($uniqueId !== '') { + $this->uniqueid = $uniqueId; + } + } + + /** + * @param string $name + * @param mixed $default + * @param string|null $separator + * @return mixed + */ + public function get($name, $default = null, $separator = null) + { + switch (strtolower($name)) { + case 'id': + case 'uniqueid': + case 'name': + case 'noncename': + case 'nonceaction': + case 'action': + case 'data': + case 'files': + case 'errors'; + case 'fields': + case 'blueprint': + case 'page': + $method = 'get' . $name; + return $this->{$method}(); + } + + return $this->traitGet($name, $default, $separator); + } + + /** + * @param string $name + * @param mixed $value + * @param string|null $separator + * @return $this + */ + public function set($name, $value, $separator = null) + { + switch (strtolower($name)) { + case 'id': + case 'uniqueid': + $method = 'set' . $name; + return $this->{$method}(); + } + + return $this->traitSet($name, $value, $separator); + } + + /** + * @return string + */ + public function getName(): string + { + return $this->flexName; + } + + protected function setName(string $type, string $name): void + { + // Make sure that both type and name do not have dash (convert dashes to underscores). + $type = str_replace('-', '_', $type); + $name = str_replace('-', '_', $name); + $this->flexName = $name ? "flex_conf-{$type}-{$name}" : "flex_conf-{$type}"; + } + + /** + * @return Data|object + */ + public function getData() + { + if (null === $this->data) { + $this->data = new Data([], $this->getBlueprint()); + } + + return $this->data; + } + + /** + * Get a value from the form. + * + * Note: Used in form fields. + * + * @param string $name + * @return mixed + */ + public function getValue(string $name) + { + // Attempt to get value from the form data. + $value = $this->data ? $this->data[$name] : null; + + // Return the form data or fall back to the object property. + return $value ?? null; + } + + /** + * @param string $name + * @return array|mixed|null + */ + public function getDefaultValue(string $name) + { + return $this->getBlueprint()->getDefaultValue($name); + } + + /** + * @return array + */ + public function getDefaultValues(): array + { + return $this->getBlueprint()->getDefaults(); + } + /** + * @return string + */ + public function getFlexType(): string + { + return $this->directory->getFlexType(); + } + + /** + * Get form flash object. + * + * @return FormFlashInterface|FlexFormFlash + */ + public function getFlash() + { + if (null === $this->flash) { + $grav = Grav::instance(); + $config = [ + 'session_id' => $this->getSessionId(), + 'unique_id' => $this->getUniqueId(), + 'form_name' => $this->getName(), + 'folder' => $this->getFlashFolder(), + 'id' => $this->getFlashId(), + 'directory' => $this->getDirectory() + ]; + + $this->flash = new FlexFormFlash($config); + $this->flash + ->setUrl($grav['uri']->url) + ->setUser($grav['user'] ?? null); + } + + return $this->flash; + } + + /** + * @return FlexDirectory + */ + public function getDirectory(): FlexDirectory + { + return $this->directory; + } + + /** + * @return Blueprint + */ + public function getBlueprint(): Blueprint + { + if (null === $this->blueprint) { + try { + $blueprint = $this->getDirectory()->getDirectoryBlueprint(); + if ($this->form) { + // We have field overrides available. + $blueprint->extend(['form' => $this->form], true); + $blueprint->init(); + } + } catch (RuntimeException $e) { + if (!isset($this->form['fields'])) { + throw $e; + } + + // Blueprint is not defined, but we have custom form fields available. + $blueprint = new Blueprint(null, ['form' => $this->form]); + $blueprint->load(); + $blueprint->setScope('directory'); + $blueprint->init(); + } + + $this->blueprint = $blueprint; + } + + return $this->blueprint; + } + + /** + * @return Route|null + */ + public function getFileUploadAjaxRoute(): ?Route + { + return null; + } + + /** + * @param string|null $field + * @param string|null $filename + * @return Route|null + */ + public function getFileDeleteAjaxRoute($field = null, $filename = null): ?Route + { + return null; + } + + /** + * @param array $params + * @param string|null $extension + * @return string + */ + public function getMediaTaskRoute(array $params = [], string $extension = null): string + { + return ''; + } + + /** + * @param string $name + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function __get($name) + { + $method = "get{$name}"; + if (method_exists($this, $method)) { + return $this->{$method}(); + } + + $form = $this->getBlueprint()->form(); + + return $form[$name] ?? null; + } + + /** + * @param string $name + * @param mixed $value + * @return void + */ + #[\ReturnTypeWillChange] + public function __set($name, $value) + { + $method = "set{$name}"; + if (method_exists($this, $method)) { + $this->{$method}($value); + } + } + + /** + * @param string $name + * @return bool + */ + #[\ReturnTypeWillChange] + public function __isset($name) + { + $method = "get{$name}"; + if (method_exists($this, $method)) { + return true; + } + + $form = $this->getBlueprint()->form(); + + return isset($form[$name]); + } + + /** + * @param string $name + * @return void + */ + #[\ReturnTypeWillChange] + public function __unset($name) + { + } + + /** + * @return array|bool + */ + protected function getUnserializeAllowedClasses() + { + return [FlexObject::class]; + } + + /** + * Note: this method clones the object. + * + * @param FlexDirectory $directory + * @return $this + */ + protected function setDirectory(FlexDirectory $directory): self + { + $this->directory = $directory; + + return $this; + } + + /** + * @param string $layout + * @return Template|TemplateWrapper + * @throws LoaderError + * @throws SyntaxError + */ + protected function getTemplate($layout) + { + $grav = Grav::instance(); + + /** @var Twig $twig */ + $twig = $grav['twig']; + + return $twig->twig()->resolveTemplate( + [ + "flex-objects/layouts/{$this->getFlexType()}/form/{$layout}.html.twig", + "flex-objects/layouts/_default/form/{$layout}.html.twig", + "forms/{$layout}/form.html.twig", + 'forms/default/form.html.twig' + ] + ); + } + + /** + * @param array $data + * @param array $files + * @return void + * @throws Exception + */ + protected function doSubmit(array $data, array $files) + { + $this->directory->saveDirectoryConfig($this->name, $data); + + $this->reset(); + } + + /** + * @return array + */ + protected function doSerialize(): array + { + return $this->doTraitSerialize() + [ + 'form' => $this->form, + 'directory' => $this->directory, + 'flexName' => $this->flexName + ]; + } + + /** + * @param array $data + * @return void + */ + protected function doUnserialize(array $data): void + { + $this->doTraitUnserialize($data); + + $this->form = $data['form']; + $this->directory = $data['directory']; + $this->flexName = $data['flexName']; + } + + /** + * Filter validated data. + * + * @param ArrayAccess|Data|null $data + * @phpstan-param ArrayAccess|Data|null $data + */ + protected function filterData($data = null): void + { + if ($data instanceof Data) { + $data->filter(false, true); + } + } +} diff --git a/system/src/Grav/Framework/Flex/FlexForm.php b/system/src/Grav/Framework/Flex/FlexForm.php new file mode 100644 index 0000000..f3a0d1f --- /dev/null +++ b/system/src/Grav/Framework/Flex/FlexForm.php @@ -0,0 +1,610 @@ +getObject($key) ?? $directory->createObject([], $key); + } else { + throw new RuntimeException(__METHOD__ . "(): You need to pass option 'directory' or 'object'", 400); + } + + $name = $options['name'] ?? ''; + + // There is no reason to pass object and directory. + unset($options['object'], $options['directory']); + + return $object->getForm($name, $options); + } + + /** + * FlexForm constructor. + * @param string $name + * @param FlexObjectInterface $object + * @param array|null $options + */ + public function __construct(string $name, FlexObjectInterface $object, array $options = null) + { + $this->name = $name; + $this->setObject($object); + + if (isset($options['form']['name'])) { + // Use custom form name. + $this->flexName = $options['form']['name']; + } else { + // Use standard form name. + $this->setName($object->getFlexType(), $name); + } + $this->setId($this->getName()); + + $uniqueId = $options['unique_id'] ?? null; + if (!$uniqueId) { + if ($object->exists()) { + $uniqueId = $object->getStorageKey(); + } elseif ($object->hasKey()) { + $uniqueId = "{$object->getKey()}:new"; + } else { + $uniqueId = "{$object->getFlexType()}:new"; + } + $uniqueId = md5($uniqueId); + } + $this->setUniqueId($uniqueId); + + $directory = $object->getFlexDirectory(); + $this->setFlashLookupFolder($options['flash_folder'] ?? $directory->getBlueprint()->get('form/flash_folder') ?? 'tmp://forms/[SESSIONID]'); + $this->form = $options['form'] ?? null; + + if (Utils::isPositive($this->items['disabled'] ?? $this->form['disabled'] ?? false)) { + $this->disable(); + } + + if (!empty($options['reset'])) { + $this->getFlash()->delete(); + } + + $this->initialize(); + } + + /** + * @return $this + */ + public function initialize() + { + $this->messages = []; + $this->submitted = false; + $this->data = null; + $this->files = []; + $this->unsetFlash(); + + /** @var FlexFormFlash $flash */ + $flash = $this->getFlash(); + if ($flash->exists()) { + $data = $flash->getData(); + if (null !== $data) { + $data = new Data($data, $this->getBlueprint()); + $data->setKeepEmptyValues(true); + $data->setMissingValuesAsNull(true); + } + + $object = $flash->getObject(); + if (null === $object) { + throw new RuntimeException('Flash has no object'); + } + + $this->object = $object; + $this->data = $data; + + $includeOriginal = (bool)($this->getBlueprint()->form()['images']['original'] ?? null); + $this->files = $flash->getFilesByFields($includeOriginal); + } + + return $this; + } + + /** + * @param string $uniqueId + * @return void + */ + public function setUniqueId(string $uniqueId): void + { + if ($uniqueId !== '') { + $this->uniqueid = $uniqueId; + } + } + + /** + * @param string $name + * @param mixed $default + * @param string|null $separator + * @return mixed + */ + public function get($name, $default = null, $separator = null) + { + switch (strtolower($name)) { + case 'id': + case 'uniqueid': + case 'name': + case 'noncename': + case 'nonceaction': + case 'action': + case 'data': + case 'files': + case 'errors'; + case 'fields': + case 'blueprint': + case 'page': + $method = 'get' . $name; + return $this->{$method}(); + } + + return $this->traitGet($name, $default, $separator); + } + + /** + * @param string $name + * @param mixed $value + * @param string|null $separator + * @return FlexForm + */ + public function set($name, $value, $separator = null) + { + switch (strtolower($name)) { + case 'id': + case 'uniqueid': + $method = 'set' . $name; + return $this->{$method}(); + } + + return $this->traitSet($name, $value, $separator); + } + + /** + * @return string + */ + public function getName(): string + { + return $this->flexName; + } + + /** + * @param callable|null $submitMethod + */ + public function setSubmitMethod(?callable $submitMethod): void + { + $this->submitMethod = $submitMethod; + } + + /** + * @param string $type + * @param string $name + */ + protected function setName(string $type, string $name): void + { + // Make sure that both type and name do not have dash (convert dashes to underscores). + $type = str_replace('-', '_', $type); + $name = str_replace('-', '_', $name); + $this->flexName = $name ? "flex-{$type}-{$name}" : "flex-{$type}"; + } + + /** + * @return Data|FlexObjectInterface|object + */ + public function getData() + { + return $this->data ?? $this->getObject(); + } + + /** + * Get a value from the form. + * + * Note: Used in form fields. + * + * @param string $name + * @return mixed + */ + public function getValue(string $name) + { + // Attempt to get value from the form data. + $value = $this->data ? $this->data[$name] : null; + + // Return the form data or fall back to the object property. + return $value ?? $this->getObject()->getFormValue($name); + } + + /** + * @param string $name + * @return array|mixed|null + */ + public function getDefaultValue(string $name) + { + return $this->object->getDefaultValue($name); + } + + /** + * @return array + */ + public function getDefaultValues(): array + { + return $this->object->getDefaultValues(); + } + /** + * @return string + */ + public function getFlexType(): string + { + return $this->object->getFlexType(); + } + + /** + * Get form flash object. + * + * @return FormFlashInterface|FlexFormFlash + */ + public function getFlash() + { + if (null === $this->flash) { + $grav = Grav::instance(); + $config = [ + 'session_id' => $this->getSessionId(), + 'unique_id' => $this->getUniqueId(), + 'form_name' => $this->getName(), + 'folder' => $this->getFlashFolder(), + 'id' => $this->getFlashId(), + 'object' => $this->getObject() + ]; + + $this->flash = new FlexFormFlash($config); + $this->flash + ->setUrl($grav['uri']->url) + ->setUser($grav['user'] ?? null); + } + + return $this->flash; + } + + /** + * @return FlexObjectInterface + */ + public function getObject(): FlexObjectInterface + { + return $this->object; + } + + /** + * @return FlexObjectInterface + */ + public function updateObject(): FlexObjectInterface + { + $data = $this->data instanceof Data ? $this->data->toArray() : []; + $files = $this->files; + + return $this->getObject()->update($data, $files); + } + + /** + * @return Blueprint + */ + public function getBlueprint(): Blueprint + { + if (null === $this->blueprint) { + try { + $blueprint = $this->getObject()->getBlueprint($this->name); + if ($this->form) { + // We have field overrides available. + $blueprint->extend(['form' => $this->form], true); + $blueprint->init(); + } + } catch (RuntimeException $e) { + if (!isset($this->form['fields'])) { + throw $e; + } + + // Blueprint is not defined, but we have custom form fields available. + $blueprint = new Blueprint(null, ['form' => $this->form]); + $blueprint->load(); + $blueprint->setScope('object'); + $blueprint->init(); + } + + $this->blueprint = $blueprint; + } + + return $this->blueprint; + } + + /** + * @return Route|null + */ + public function getFileUploadAjaxRoute(): ?Route + { + $object = $this->getObject(); + if (!method_exists($object, 'route')) { + /** @var Route $route */ + $route = Grav::instance()['route']; + + return $route->withExtension('json')->withGravParam('task', 'media.upload'); + } + + return $object->route('/edit.json/task:media.upload'); + } + + /** + * @param string|null $field + * @param string|null $filename + * @return Route|null + */ + public function getFileDeleteAjaxRoute($field = null, $filename = null): ?Route + { + $object = $this->getObject(); + if (!method_exists($object, 'route')) { + /** @var Route $route */ + $route = Grav::instance()['route']; + + return $route->withExtension('json')->withGravParam('task', 'media.delete'); + } + + return $object->route('/edit.json/task:media.delete'); + } + + /** + * @param array $params + * @param string|null $extension + * @return string + */ + public function getMediaTaskRoute(array $params = [], string $extension = null): string + { + $grav = Grav::instance(); + /** @var Flex $flex */ + $flex = $grav['flex_objects']; + + if (method_exists($flex, 'adminRoute')) { + return $flex->adminRoute($this->getObject(), $params, $extension ?? 'json'); + } + + return ''; + } + + /** + * @param string $name + * @return mixed|null + */ + #[\ReturnTypeWillChange] + public function __get($name) + { + $method = "get{$name}"; + if (method_exists($this, $method)) { + return $this->{$method}(); + } + + $form = $this->getBlueprint()->form(); + + return $form[$name] ?? null; + } + + /** + * @param string $name + * @param mixed $value + * @return void + */ + #[\ReturnTypeWillChange] + public function __set($name, $value) + { + $method = "set{$name}"; + if (method_exists($this, $method)) { + $this->{$method}($value); + } + } + + /** + * @param string $name + * @return bool + */ + #[\ReturnTypeWillChange] + public function __isset($name) + { + $method = "get{$name}"; + if (method_exists($this, $method)) { + return true; + } + + $form = $this->getBlueprint()->form(); + + return isset($form[$name]); + } + + /** + * @param string $name + * @return void + */ + #[\ReturnTypeWillChange] + public function __unset($name) + { + } + + /** + * @return array|bool + */ + protected function getUnserializeAllowedClasses() + { + return [FlexObject::class]; + } + + /** + * Note: this method clones the object. + * + * @param FlexObjectInterface $object + * @return $this + */ + protected function setObject(FlexObjectInterface $object): self + { + $this->object = clone $object; + + return $this; + } + + /** + * @param string $layout + * @return Template|TemplateWrapper + * @throws LoaderError + * @throws SyntaxError + */ + protected function getTemplate($layout) + { + $grav = Grav::instance(); + + /** @var Twig $twig */ + $twig = $grav['twig']; + + return $twig->twig()->resolveTemplate( + [ + "flex-objects/layouts/{$this->getFlexType()}/form/{$layout}.html.twig", + "flex-objects/layouts/_default/form/{$layout}.html.twig", + "forms/{$layout}/form.html.twig", + 'forms/default/form.html.twig' + ] + ); + } + + /** + * @param array $data + * @param array $files + * @return void + * @throws Exception + */ + protected function doSubmit(array $data, array $files) + { + /** @var FlexObject $object */ + $object = clone $this->getObject(); + + $method = $this->submitMethod; + if ($method) { + $method($data, $files, $object); + } else { + $object->update($data, $files); + $object->save(); + } + + $this->setObject($object); + $this->reset(); + } + + /** + * @return array + */ + protected function doSerialize(): array + { + return $this->doTraitSerialize() + [ + 'items' => $this->items, + 'form' => $this->form, + 'object' => $this->object, + 'flexName' => $this->flexName, + 'submitMethod' => $this->submitMethod, + ]; + } + + /** + * @param array $data + * @return void + */ + protected function doUnserialize(array $data): void + { + $this->doTraitUnserialize($data); + + $this->items = $data['items'] ?? null; + $this->form = $data['form'] ?? null; + $this->object = $data['object'] ?? null; + $this->flexName = $data['flexName'] ?? null; + $this->submitMethod = $data['submitMethod'] ?? null; + } + + /** + * Filter validated data. + * + * @param ArrayAccess|Data|null $data + * @return void + * @phpstan-param ArrayAccess|Data|null $data + */ + protected function filterData($data = null): void + { + if ($data instanceof Data) { + $data->filter(true, true); + } + } +} diff --git a/system/src/Grav/Framework/Flex/FlexFormFlash.php b/system/src/Grav/Framework/Flex/FlexFormFlash.php new file mode 100644 index 0000000..084c346 --- /dev/null +++ b/system/src/Grav/Framework/Flex/FlexFormFlash.php @@ -0,0 +1,130 @@ +object = $object; + $this->directory = $object->getFlexDirectory(); + } + + /** + * @return FlexObjectInterface|null + */ + public function getObject(): ?FlexObjectInterface + { + return $this->object; + } + + /** + * @param FlexDirectory $directory + */ + public function setDirectory(FlexDirectory $directory): void + { + $this->directory = $directory; + } + + /** + * @return FlexDirectory|null + */ + public function getDirectory(): ?FlexDirectory + { + return $this->directory; + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + $serialized = parent::jsonSerialize(); + + $object = $this->getObject(); + if ($object instanceof FlexObjectInterface) { + $serialized['object'] = [ + 'type' => $object->getFlexType(), + 'key' => $object->getKey() ?: null, + 'storage_key' => $object->getStorageKey(), + 'timestamp' => $object->getTimestamp(), + 'serialized' => $object->prepareStorage() + ]; + } else { + $directory = $this->getDirectory(); + if ($directory instanceof FlexDirectory) { + $serialized['directory'] = [ + 'type' => $directory->getFlexType() + ]; + } + } + + return $serialized; + } + + /** + * @param array|null $data + * @param array $config + * @return void + */ + protected function init(?array $data, array $config): void + { + parent::init($data, $config); + + $data = $data ?? []; + /** @var FlexObjectInterface|null $object */ + $object = $config['object'] ?? null; + $create = true; + if ($object) { + $directory = $object->getFlexDirectory(); + $create = !$object->exists(); + } elseif (null === ($directory = $config['directory'] ?? null)) { + $flex = $config['flex'] ?? static::$flex; + $type = $data['object']['type'] ?? $data['directory']['type'] ?? null; + $directory = $flex && $type ? $flex->getDirectory($type) : null; + } + + if ($directory && $create && isset($data['object']['serialized'])) { + // TODO: update instead of create new. + $object = $directory->createObject($data['object']['serialized'], $data['object']['key'] ?? ''); + } + + if ($object) { + $this->setObject($object); + } elseif ($directory) { + $this->setDirectory($directory); + } + } +} diff --git a/system/src/Grav/Framework/Flex/FlexIdentifier.php b/system/src/Grav/Framework/Flex/FlexIdentifier.php new file mode 100644 index 0000000..ec47ed8 --- /dev/null +++ b/system/src/Grav/Framework/Flex/FlexIdentifier.php @@ -0,0 +1,75 @@ + + */ +class FlexIdentifier extends Identifier +{ + /** @var string */ + private $keyField; + /** @var FlexObjectInterface|null */ + private $object = null; + + /** + * @param FlexObjectInterface $object + * @return FlexIdentifier + */ + public static function createFromObject(FlexObjectInterface $object): FlexIdentifier + { + $instance = new static($object->getKey(), $object->getFlexType(), 'key'); + $instance->setObject($object); + + return $instance; + } + + /** + * IdentifierInterface constructor. + * @param string $id + * @param string $type + * @param string $keyField + */ + public function __construct(string $id, string $type, string $keyField = 'key') + { + parent::__construct($id, $type); + + $this->keyField = $keyField; + } + + /** + * @return T + */ + public function getObject(): ?FlexObjectInterface + { + if (!isset($this->object)) { + /** @var Flex $flex */ + $flex = Grav::instance()['flex']; + + $this->object = $flex->getObject($this->getId(), $this->getType(), $this->keyField); + } + + return $this->object; + } + + /** + * @param T $object + */ + public function setObject(FlexObjectInterface $object): void + { + $type = $this->getType(); + if ($type !== $object->getFlexType()) { + throw new RuntimeException(sprintf('Object has to be type %s, %s given', $type, $object->getFlexType())); + } + + $this->object = $object; + } +} diff --git a/system/src/Grav/Framework/Flex/FlexIndex.php b/system/src/Grav/Framework/Flex/FlexIndex.php new file mode 100644 index 0000000..39fec18 --- /dev/null +++ b/system/src/Grav/Framework/Flex/FlexIndex.php @@ -0,0 +1,930 @@ + + * @implements FlexIndexInterface + * @mixin C + */ +class FlexIndex extends ObjectIndex implements FlexIndexInterface +{ + const VERSION = 1; + + /** @var FlexDirectory|null */ + private $_flexDirectory; + /** @var string */ + private $_keyField = 'storage_key'; + /** @var array */ + private $_indexKeys; + + /** + * @param FlexDirectory $directory + * @return static + * @phpstan-return static + */ + public static function createFromStorage(FlexDirectory $directory) + { + return static::createFromArray(static::loadEntriesFromStorage($directory->getStorage()), $directory); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::createFromArray() + */ + public static function createFromArray(array $entries, FlexDirectory $directory, string $keyField = null) + { + $instance = new static($entries, $directory); + $instance->setKeyField($keyField); + + return $instance; + } + + /** + * @param FlexStorageInterface $storage + * @return array + */ + public static function loadEntriesFromStorage(FlexStorageInterface $storage): array + { + return $storage->getExistingKeys(); + } + + /** + * You can define indexes for fast lookup. + * + * Primary key: $meta['key'] + * Secondary keys: $meta['my_field'] + * + * @param array $meta + * @param array $data + * @param FlexStorageInterface $storage + * @return void + */ + public static function updateObjectMeta(array &$meta, array $data, FlexStorageInterface $storage) + { + // For backwards compatibility, no need to call this method when you override this method. + static::updateIndexData($meta, $data); + } + + /** + * Initializes a new FlexIndex. + * + * @param array $entries + * @param FlexDirectory|null $directory + */ + public function __construct(array $entries = [], FlexDirectory $directory = null) + { + // @phpstan-ignore-next-line + if (get_class($this) === __CLASS__) { + user_error('Using ' . __CLASS__ . ' directly is deprecated since Grav 1.7, use \Grav\Common\Flex\Types\Generic\GenericIndex or your own class instead', E_USER_DEPRECATED); + } + + parent::__construct($entries); + + $this->_flexDirectory = $directory; + $this->setKeyField(null); + } + + /** + * @return string + */ + public function getKey() + { + return $this->_key ?: $this->getFlexType() . '@@' . spl_object_hash($this); + } + + /** + * {@inheritdoc} + * @see FlexCommonInterface::hasFlexFeature() + */ + public function hasFlexFeature(string $name): bool + { + return in_array($name, $this->getFlexFeatures(), true); + } + + /** + * {@inheritdoc} + * @see FlexCommonInterface::hasFlexFeature() + */ + public function getFlexFeatures(): array + { + /** @var array $implements */ + $implements = class_implements($this->getFlexDirectory()->getCollectionClass()); + + $list = []; + foreach ($implements as $interface) { + if ($pos = strrpos($interface, '\\')) { + $interface = substr($interface, $pos+1); + } + + $list[] = Inflector::hyphenize(str_replace('Interface', '', $interface)); + } + + return $list; + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::search() + */ + public function search(string $search, $properties = null, array $options = null) + { + $directory = $this->getFlexDirectory(); + $properties = $directory->getSearchProperties($properties); + $options = $directory->getSearchOptions($options); + + return $this->__call('search', [$search, $properties, $options]); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::sort() + */ + public function sort(array $orderings) + { + return $this->orderBy($orderings); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::filterBy() + */ + public function filterBy(array $filters) + { + return $this->__call('filterBy', [$filters]); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getFlexType() + */ + public function getFlexType(): string + { + return $this->getFlexDirectory()->getFlexType(); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getFlexDirectory() + */ + public function getFlexDirectory(): FlexDirectory + { + if (null === $this->_flexDirectory) { + throw new RuntimeException('Flex Directory not defined, object is not fully defined'); + } + + return $this->_flexDirectory; + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getTimestamp() + */ + public function getTimestamp(): int + { + $timestamps = $this->getTimestamps(); + + return $timestamps ? max($timestamps) : time(); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getCacheKey() + */ + public function getCacheKey(): string + { + return $this->getTypePrefix() . $this->getFlexType() . '.' . sha1(json_encode($this->getKeys()) . $this->_keyField); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getCacheChecksum() + */ + public function getCacheChecksum(): string + { + $list = []; + foreach ($this->getEntries() as $key => $value) { + $list[$key] = $value['checksum'] ?? $value['storage_timestamp']; + } + + return sha1((string)json_encode($list)); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getTimestamps() + */ + public function getTimestamps(): array + { + return $this->getIndexMap('storage_timestamp'); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getStorageKeys() + */ + public function getStorageKeys(): array + { + return $this->getIndexMap('storage_key'); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getFlexKeys() + */ + public function getFlexKeys(): array + { + // Get storage keys for the objects. + $keys = []; + $type = $this->getFlexDirectory()->getFlexType() . '.obj:'; + + foreach ($this->getEntries() as $key => $value) { + $keys[$key] = $value['flex_key'] ?? $type . $value['storage_key']; + } + + return $keys; + } + + /** + * {@inheritdoc} + * @see FlexIndexInterface::withKeyField() + */ + public function withKeyField(string $keyField = null) + { + $keyField = $keyField ?: 'key'; + if ($keyField === $this->getKeyField()) { + return $this; + } + + $type = $keyField === 'flex_key' ? $this->getFlexDirectory()->getFlexType() . '.obj:' : ''; + $entries = []; + foreach ($this->getEntries() as $key => $value) { + if (!isset($value['key'])) { + $value['key'] = $key; + } + + if (isset($value[$keyField])) { + $entries[$value[$keyField]] = $value; + } elseif ($keyField === 'flex_key') { + $entries[$type . $value['storage_key']] = $value; + } + } + + return $this->createFrom($entries, $keyField); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::getIndex() + */ + public function getIndex() + { + return $this; + } + + /** + * @return FlexCollectionInterface + * @phpstan-return C + */ + public function getCollection() + { + return $this->loadCollection(); + } + + /** + * {@inheritdoc} + * @see FlexCollectionInterface::render() + */ + public function render(string $layout = null, array $context = []) + { + return $this->__call('render', [$layout, $context]); + } + + /** + * {@inheritdoc} + * @see FlexIndexInterface::getFlexKeys() + */ + public function getIndexMap(string $indexKey = null) + { + if (null === $indexKey) { + return $this->getEntries(); + } + + // Get storage keys for the objects. + $index = []; + foreach ($this->getEntries() as $key => $value) { + $index[$key] = $value[$indexKey] ?? null; + } + + return $index; + } + + /** + * @param string $key + * @return array + */ + public function getMetaData($key): array + { + return $this->getEntries()[$key] ?? []; + } + + /** + * @return string + */ + public function getKeyField(): string + { + return $this->_keyField; + } + + /** + * @param string|null $namespace + * @return CacheInterface + */ + public function getCache(string $namespace = null) + { + return $this->getFlexDirectory()->getCache($namespace); + } + + /** + * @param array $orderings + * @return static + * @phpstan-return static + */ + public function orderBy(array $orderings) + { + if (!$orderings || !$this->count()) { + return $this; + } + + // Handle primary key alias. + $keyField = $this->getFlexDirectory()->getStorage()->getKeyField(); + if ($keyField !== 'key' && $keyField !== 'storage_key' && isset($orderings[$keyField])) { + $orderings['key'] = $orderings[$keyField]; + unset($orderings[$keyField]); + } + + // Check if ordering needs to load the objects. + if (array_diff_key($orderings, $this->getIndexKeys())) { + return $this->__call('orderBy', [$orderings]); + } + + // Ordering can be done by using index only. + $previous = null; + foreach (array_reverse($orderings) as $field => $ordering) { + $field = (string)$field; + if ($this->getKeyField() === $field) { + $keys = $this->getKeys(); + $search = array_combine($keys, $keys) ?: []; + } elseif ($field === 'flex_key') { + $search = $this->getFlexKeys(); + } else { + $search = $this->getIndexMap($field); + } + + // Update current search to match the previous ordering. + if (null !== $previous) { + $search = array_replace($previous, $search); + } + + // Order by current field. + if (strtoupper($ordering) === 'DESC') { + arsort($search, SORT_NATURAL | SORT_FLAG_CASE); + } else { + asort($search, SORT_NATURAL | SORT_FLAG_CASE); + } + + $previous = $search; + } + + return $this->createFrom(array_replace($previous ?? [], $this->getEntries())); + } + + /** + * {@inheritDoc} + */ + public function call($method, array $arguments = []) + { + return $this->__call('call', [$method, $arguments]); + } + + /** + * @param string $name + * @param array $arguments + * @return mixed + */ + #[\ReturnTypeWillChange] + public function __call($name, $arguments) + { + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + + /** @phpstan-var class-string $className */ + $className = $this->getFlexDirectory()->getCollectionClass(); + $cachedMethods = $className::getCachedMethods(); + + $flexType = $this->getFlexType(); + + if (!empty($cachedMethods[$name])) { + $type = $cachedMethods[$name]; + if ($type === 'session') { + /** @var Session $session */ + $session = Grav::instance()['session']; + $cacheKey = $session->getId() . ($session->user->username ?? ''); + } else { + $cacheKey = ''; + } + $key = "{$flexType}.idx." . sha1($name . '.' . $cacheKey . json_encode($arguments) . $this->getCacheKey()); + $checksum = $this->getCacheChecksum(); + + $cache = $this->getCache('object'); + + try { + $cached = $cache->get($key); + $test = $cached[0] ?? null; + $result = $test === $checksum ? ($cached[1] ?? null) : null; + + // Make sure the keys aren't changed if the returned type is the same index type. + if ($result instanceof self && $flexType === $result->getFlexType()) { + $result = $result->withKeyField($this->getKeyField()); + } + } catch (InvalidArgumentException $e) { + $debugger->addException($e); + } + + if (!isset($result)) { + $collection = $this->loadCollection(); + $result = $collection->{$name}(...$arguments); + $debugger->addMessage("Cache miss: '{$flexType}::{$name}()'", 'debug'); + + try { + // If flex collection is returned, convert it back to flex index. + if ($result instanceof FlexCollection) { + $cached = $result->getFlexDirectory()->getIndex($result->getKeys(), $this->getKeyField()); + } else { + $cached = $result; + } + + $cache->set($key, [$checksum, $cached]); + } catch (InvalidArgumentException $e) { + $debugger->addException($e); + + // TODO: log error. + } + } + } else { + $collection = $this->loadCollection(); + if (\is_callable([$collection, $name])) { + $result = $collection->{$name}(...$arguments); + if (!isset($cachedMethods[$name])) { + $debugger->addMessage("Call '{$flexType}:{$name}()' isn't cached", 'debug'); + } + } else { + $result = null; + } + } + + return $result; + } + + /** + * @return array + */ + public function __serialize(): array + { + return ['type' => $this->getFlexType(), 'entries' => $this->getEntries()]; + } + + /** + * @param array $data + * @return void + */ + public function __unserialize(array $data): void + { + $this->_flexDirectory = Grav::instance()['flex']->getDirectory($data['type']); + $this->setEntries($data['entries']); + } + + /** + * @return array + */ + #[\ReturnTypeWillChange] + public function __debugInfo() + { + return [ + 'type:private' => $this->getFlexType(), + 'key:private' => $this->getKey(), + 'entries_key:private' => $this->getKeyField(), + 'entries:private' => $this->getEntries() + ]; + } + + /** + * @param array $entries + * @param string|null $keyField + * @return static + * @phpstan-return static + */ + protected function createFrom(array $entries, string $keyField = null) + { + /** @phpstan-var static $index */ + $index = new static($entries, $this->getFlexDirectory()); + $index->setKeyField($keyField ?? $this->_keyField); + + return $index; + } + + /** + * @param string|null $keyField + * @return void + */ + protected function setKeyField(string $keyField = null) + { + $this->_keyField = $keyField ?? 'storage_key'; + } + + /** + * @return array + */ + protected function getIndexKeys() + { + if (null === $this->_indexKeys) { + $entries = $this->getEntries(); + $first = reset($entries); + if ($first) { + $keys = array_keys($first); + $keys = array_combine($keys, $keys) ?: []; + } else { + $keys = []; + } + + $this->setIndexKeys($keys); + } + + return $this->_indexKeys; + } + + /** + * @param array $indexKeys + * @return void + */ + protected function setIndexKeys(array $indexKeys) + { + // Add defaults. + $indexKeys += [ + 'key' => 'key', + 'storage_key' => 'storage_key', + 'storage_timestamp' => 'storage_timestamp', + 'flex_key' => 'flex_key' + ]; + + + $this->_indexKeys = $indexKeys; + } + + /** + * @return string + */ + protected function getTypePrefix() + { + return 'i.'; + } + + /** + * @param string $key + * @param mixed $value + * @return ObjectInterface|null + * @phpstan-return T|null + */ + protected function loadElement($key, $value): ?ObjectInterface + { + /** @phpstan-var T[] $objects */ + $objects = $this->getFlexDirectory()->loadObjects([$key => $value]); + + return $objects ? reset($objects): null; + } + + /** + * @param array|null $entries + * @return ObjectInterface[] + * @phpstan-return T[] + */ + protected function loadElements(array $entries = null): array + { + /** @phpstan-var T[] $objects */ + $objects = $this->getFlexDirectory()->loadObjects($entries ?? $this->getEntries()); + + return $objects; + } + + /** + * @param array|null $entries + * @return CollectionInterface + * @phpstan-return C + */ + protected function loadCollection(array $entries = null): CollectionInterface + { + /** @var C $collection */ + $collection = $this->getFlexDirectory()->loadCollection($entries ?? $this->getEntries(), $this->_keyField); + + return $collection; + } + + /** + * @param mixed $value + * @return bool + */ + protected function isAllowedElement($value): bool + { + return $value instanceof FlexObject; + } + + /** + * @param FlexObjectInterface $object + * @return mixed + */ + protected function getElementMeta($object) + { + return $object->getMetaData(); + } + + /** + * @param FlexObjectInterface $element + * @return string + */ + protected function getCurrentKey($element) + { + $keyField = $this->getKeyField(); + if ($keyField === 'storage_key') { + return $element->getStorageKey(); + } + if ($keyField === 'flex_key') { + return $element->getFlexKey(); + } + if ($keyField === 'key') { + return $element->getKey(); + } + + return $element->getKey(); + } + + /** + * @param FlexStorageInterface $storage + * @param array $index Saved index + * @param array $entries Updated index + * @param array $options + * @return array Compiled list of entries + */ + protected static function updateIndexFile(FlexStorageInterface $storage, array $index, array $entries, array $options = []): array + { + $indexFile = static::getIndexFile($storage); + if (null === $indexFile) { + return $entries; + } + + // Calculate removed objects. + $removed = array_diff_key($index, $entries); + + // First get rid of all removed objects. + if ($removed) { + $index = array_diff_key($index, $removed); + } + + if ($entries && empty($options['force_update'])) { + // Calculate difference between saved index and current data. + foreach ($index as $key => $entry) { + $storage_key = $entry['storage_key'] ?? null; + if (isset($entries[$storage_key]) && $entries[$storage_key]['storage_timestamp'] === $entry['storage_timestamp']) { + // Entry is up to date, no update needed. + unset($entries[$storage_key]); + } + } + + if (empty($entries) && empty($removed)) { + // No objects were added, updated or removed. + return $index; + } + } elseif (!$removed) { + // There are no objects and nothing was removed. + return []; + } + + // Index should be updated, lock the index file for saving. + $indexFile->lock(); + + // Read all the data rows into an array using chunks of 100. + $keys = array_fill_keys(array_keys($entries), null); + $chunks = array_chunk($keys, 100, true); + $updated = $added = []; + foreach ($chunks as $keys) { + $rows = $storage->readRows($keys); + + $keyField = $storage->getKeyField(); + + // Go through all the updated objects and refresh their index data. + foreach ($rows as $key => $row) { + if (null !== $row || !empty($options['include_missing'])) { + $entry = $entries[$key] + ['key' => $key]; + if ($keyField !== 'storage_key' && isset($row[$keyField])) { + $entry['key'] = $row[$keyField]; + } + static::updateObjectMeta($entry, $row ?? [], $storage); + if (isset($row['__ERROR'])) { + $entry['__ERROR'] = true; + static::onException(new RuntimeException(sprintf('Object failed to load: %s (%s)', $key, + $row['__ERROR']))); + } + if (isset($index[$key])) { + // Update object in the index. + $updated[$key] = $entry; + } else { + // Add object into the index. + $added[$key] = $entry; + } + + // Either way, update the entry. + $index[$key] = $entry; + } elseif (isset($index[$key])) { + // Remove object from the index. + $removed[$key] = $index[$key]; + unset($index[$key]); + } + } + unset($rows); + } + + // Sort the index before saving it. + ksort($index, SORT_NATURAL | SORT_FLAG_CASE); + + static::onChanges($index, $added, $updated, $removed); + + $indexFile->save(['version' => static::VERSION, 'timestamp' => time(), 'count' => count($index), 'index' => $index]); + $indexFile->unlock(); + + return $index; + } + + /** + * @param array $entry + * @param array $data + * @return void + * @deprecated 1.7 Use static ::updateObjectMeta() method instead. + */ + protected static function updateIndexData(array &$entry, array $data) + { + } + + /** + * @param FlexStorageInterface $storage + * @return array + */ + protected static function loadIndex(FlexStorageInterface $storage) + { + $indexFile = static::getIndexFile($storage); + + if ($indexFile) { + $data = []; + try { + $data = (array)$indexFile->content(); + $version = $data['version'] ?? null; + if ($version !== static::VERSION) { + $data = []; + } + } catch (Exception $e) { + $e = new RuntimeException(sprintf('Index failed to load: %s', $e->getMessage()), $e->getCode(), $e); + + static::onException($e); + } + + if ($data) { + return $data; + } + } + + return ['version' => static::VERSION, 'timestamp' => 0, 'count' => 0, 'index' => []]; + } + + /** + * @param FlexStorageInterface $storage + * @return array + */ + protected static function loadEntriesFromIndex(FlexStorageInterface $storage) + { + $data = static::loadIndex($storage); + + return $data['index'] ?? []; + } + + /** + * @param FlexStorageInterface $storage + * @return CompiledYamlFile|CompiledJsonFile|null + */ + protected static function getIndexFile(FlexStorageInterface $storage) + { + if (!method_exists($storage, 'isIndexed') || !$storage->isIndexed()) { + return null; + } + + $path = $storage->getStoragePath(); + if (!$path) { + return null; + } + + // Load saved index file. + $grav = Grav::instance(); + $locator = $grav['locator']; + $filename = $locator->findResource("{$path}/index.yaml", true, true); + + return CompiledYamlFile::instance($filename); + } + + /** + * @param Exception $e + * @return void + */ + protected static function onException(Exception $e) + { + $grav = Grav::instance(); + + /** @var Logger $logger */ + $logger = $grav['log']; + $logger->addAlert($e->getMessage()); + + /** @var Debugger $debugger */ + $debugger = $grav['debugger']; + $debugger->addException($e); + $debugger->addMessage($e, 'error'); + } + + /** + * @param array $entries + * @param array $added + * @param array $updated + * @param array $removed + * @return void + */ + protected static function onChanges(array $entries, array $added, array $updated, array $removed) + { + $addedCount = count($added); + $updatedCount = count($updated); + $removedCount = count($removed); + + if ($addedCount + $updatedCount + $removedCount) { + $message = sprintf('Index updated, %d objects (%d added, %d updated, %d removed).', count($entries), $addedCount, $updatedCount, $removedCount); + + $grav = Grav::instance(); + + /** @var Debugger $debugger */ + $debugger = $grav['debugger']; + $debugger->addMessage($message, 'debug'); + } + } + + // DEPRECATED METHODS + + /** + * @param bool $prefix + * @return string + * @deprecated 1.6 Use `->getFlexType()` instead. + */ + public function getType($prefix = false) + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use ->getFlexType() method instead', E_USER_DEPRECATED); + + $type = $prefix ? $this->getTypePrefix() : ''; + + return $type . $this->getFlexType(); + } +} diff --git a/system/src/Grav/Framework/Flex/FlexObject.php b/system/src/Grav/Framework/Flex/FlexObject.php new file mode 100644 index 0000000..14f28f9 --- /dev/null +++ b/system/src/Grav/Framework/Flex/FlexObject.php @@ -0,0 +1,1288 @@ + true, + 'getType' => true, + 'getFlexType' => true, + 'getFlexDirectory' => true, + 'hasFlexFeature' => true, + 'getFlexFeatures' => true, + 'getCacheKey' => true, + 'getCacheChecksum' => false, + 'getTimestamp' => true, + 'value' => true, + 'exists' => true, + 'hasProperty' => true, + 'getProperty' => true, + + // FlexAclTrait + 'isAuthorized' => 'session', + ]; + } + + /** + * @param array $elements + * @param array $storage + * @param FlexDirectory $directory + * @param bool $validate + * @return static + */ + public static function createFromStorage(array $elements, array $storage, FlexDirectory $directory, bool $validate = false) + { + $instance = new static($elements, $storage['key'], $directory, $validate); + $instance->setMetaData($storage); + + return $instance; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::__construct() + */ + public function __construct(array $elements, $key, FlexDirectory $directory, bool $validate = false) + { + if (get_class($this) === __CLASS__) { + user_error('Using ' . __CLASS__ . ' directly is deprecated since Grav 1.7, use \Grav\Common\Flex\Types\Generic\GenericObject or your own class instead', E_USER_DEPRECATED); + } + + $this->_flexDirectory = $directory; + + if (isset($elements['__META'])) { + $this->setMetaData($elements['__META']); + unset($elements['__META']); + } + + if ($validate) { + $blueprint = $this->getFlexDirectory()->getBlueprint(); + + $blueprint->validate($elements, ['xss_check' => false]); + + $elements = $blueprint->filter($elements, true, true); + } + + $this->filterElements($elements); + + $this->objectConstruct($elements, $key); + } + + /** + * {@inheritdoc} + * @see FlexCommonInterface::hasFlexFeature() + */ + public function hasFlexFeature(string $name): bool + { + return in_array($name, $this->getFlexFeatures(), true); + } + + /** + * {@inheritdoc} + * @see FlexCommonInterface::hasFlexFeature() + */ + public function getFlexFeatures(): array + { + /** @var array $implements */ + $implements = class_implements($this); + + $list = []; + foreach ($implements as $interface) { + if ($pos = strrpos($interface, '\\')) { + $interface = substr($interface, $pos+1); + } + + $list[] = Inflector::hyphenize(str_replace('Interface', '', $interface)); + } + + return $list; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::getFlexType() + */ + public function getFlexType(): string + { + return $this->_flexDirectory->getFlexType(); + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::getFlexDirectory() + */ + public function getFlexDirectory(): FlexDirectory + { + return $this->_flexDirectory; + } + + /** + * Refresh object from the storage. + * + * @param bool $keepMissing + * @return bool True if the object was refreshed + */ + public function refresh(bool $keepMissing = false): bool + { + $key = $this->getStorageKey(); + if ('' === $key) { + return false; + } + + $storage = $this->getFlexDirectory()->getStorage(); + $meta = $storage->getMetaData([$key])[$key] ?? null; + + $newChecksum = $meta['checksum'] ?? $meta['storage_timestamp'] ?? null; + $curChecksum = $this->_meta['checksum'] ?? $this->_meta['storage_timestamp'] ?? null; + + // Check if object is up to date with the storage. + if (null === $newChecksum || $newChecksum === $curChecksum) { + return false; + } + + // Get current elements (if requested). + $current = $keepMissing ? $this->getElements() : []; + // Get elements from the filesystem. + $elements = $storage->readRows([$key => null])[$key] ?? null; + if (null !== $elements) { + $meta = $elements['__META'] ?? $meta; + unset($elements['__META']); + $this->filterElements($elements); + $newKey = $meta['key'] ?? $this->getKey(); + if ($meta) { + $this->setMetaData($meta); + } + $this->objectConstruct($elements, $newKey); + + if ($current) { + // Inject back elements which are missing in the filesystem. + $data = $this->getBlueprint()->flattenData($current); + foreach ($data as $property => $value) { + if (strpos($property, '.') === false) { + $this->defProperty($property, $value); + } else { + $this->defNestedProperty($property, $value); + } + } + } + + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $debugger->addMessage("Refreshed {$this->getFlexType()} object {$this->getKey()}", 'debug'); + } + + return true; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::getTimestamp() + */ + public function getTimestamp(): int + { + return $this->_meta['storage_timestamp'] ?? 0; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::getCacheKey() + */ + public function getCacheKey(): string + { + return $this->hasKey() ? $this->getTypePrefix() . $this->getFlexType() . '.' . $this->getKey() : ''; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::getCacheChecksum() + */ + public function getCacheChecksum(): string + { + return (string)($this->_meta['checksum'] ?? $this->getTimestamp()); + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::search() + */ + public function search(string $search, $properties = null, array $options = null): float + { + $directory = $this->getFlexDirectory(); + $properties = $directory->getSearchProperties($properties); + $options = $directory->getSearchOptions($options); + + $weight = 0; + foreach ($properties as $property) { + if (strpos($property, '.')) { + $weight += $this->searchNestedProperty($property, $search, $options); + } else { + $weight += $this->searchProperty($property, $search, $options); + } + } + + return $weight > 0 ? min($weight, 1) : 0; + } + + /** + * {@inheritdoc} + * @see ObjectInterface::getFlexKey() + */ + public function getKey() + { + return (string)$this->_key; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::getFlexKey() + */ + public function getFlexKey(): string + { + $key = $this->_meta['flex_key'] ?? null; + + if (!$key && $key = $this->getStorageKey()) { + $key = $this->_flexDirectory->getFlexType() . '.obj:' . $key; + } + + return (string)$key; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::getStorageKey() + */ + public function getStorageKey(): string + { + return (string)($this->storage_key ?? $this->_meta['storage_key'] ?? null); + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::getMetaData() + */ + public function getMetaData(): array + { + return $this->_meta ?? []; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::exists() + */ + public function exists(): bool + { + $key = $this->getStorageKey(); + + return $key && $this->getFlexDirectory()->getStorage()->hasKey($key); + } + + /** + * @param string $property + * @param string $search + * @param array|null $options + * @return float + */ + public function searchProperty(string $property, string $search, array $options = null): float + { + $options = $options ?? (array)$this->getFlexDirectory()->getConfig('data.search.options'); + $value = $this->getProperty($property); + + return $this->searchValue($property, $value, $search, $options); + } + + /** + * @param string $property + * @param string $search + * @param array|null $options + * @return float + */ + public function searchNestedProperty(string $property, string $search, array $options = null): float + { + $options = $options ?? (array)$this->getFlexDirectory()->getConfig('data.search.options'); + if ($property === 'key') { + $value = $this->getKey(); + } else { + $value = $this->getNestedProperty($property); + } + + return $this->searchValue($property, $value, $search, $options); + } + + /** + * @param string $name + * @param mixed $value + * @param string $search + * @param array|null $options + * @return float + */ + protected function searchValue(string $name, $value, string $search, array $options = null): float + { + $options = $options ?? []; + + // Ignore empty search strings. + $search = trim($search); + if ($search === '') { + return 0; + } + + // Search only non-empty string values. + if (!is_string($value) || $value === '') { + return 0; + } + + $caseSensitive = $options['case_sensitive'] ?? false; + + $tested = false; + if (($tested |= !empty($options['same_as']))) { + if ($caseSensitive) { + if ($value === $search) { + return (float)$options['same_as']; + } + } elseif (mb_strtolower($value) === mb_strtolower($search)) { + return (float)$options['same_as']; + } + } + if (($tested |= !empty($options['starts_with'])) && Utils::startsWith($value, $search, $caseSensitive)) { + return (float)$options['starts_with']; + } + if (($tested |= !empty($options['ends_with'])) && Utils::endsWith($value, $search, $caseSensitive)) { + return (float)$options['ends_with']; + } + if ((!$tested || !empty($options['contains'])) && Utils::contains($value, $search, $caseSensitive)) { + return (float)($options['contains'] ?? 1); + } + + return 0; + } + + /** + * Get original data before update + * + * @return array + */ + public function getOriginalData(): array + { + return $this->_original ?? []; + } + + /** + * Get diff array from the object. + * + * @return array + */ + public function getDiff(): array + { + $blueprint = $this->getBlueprint(); + + $flattenOriginal = $blueprint->flattenData($this->getOriginalData()); + $flattenElements = $blueprint->flattenData($this->getElements()); + $removedElements = array_diff_key($flattenOriginal, $flattenElements); + $diff = []; + + // Include all added or changed keys. + foreach ($flattenElements as $key => $value) { + $orig = $flattenOriginal[$key] ?? null; + if ($orig !== $value) { + $diff[$key] = ['old' => $orig, 'new' => $value]; + } + } + + // Include all removed keys. + foreach ($removedElements as $key => $value) { + $diff[$key] = ['old' => $value, 'new' => null]; + } + + return $diff; + } + + /** + * Get any changes from the object. + * + * @return array + */ + public function getChanges(): array + { + $diff = $this->getDiff(); + + $data = new Data(); + foreach ($diff as $key => $change) { + $data->set($key, $change['new']); + } + + return $data->toArray(); + } + + /** + * @return string + */ + protected function getTypePrefix(): string + { + return 'o.'; + } + + /** + * Alias of getBlueprint() + * + * @return Blueprint + * @deprecated 1.6 Admin compatibility + */ + public function blueprints() + { + return $this->getBlueprint(); + } + + /** + * @param string|null $namespace + * @return CacheInterface + */ + public function getCache(string $namespace = null) + { + return $this->_flexDirectory->getCache($namespace); + } + + /** + * @param string|null $key + * @return $this + */ + public function setStorageKey($key = null) + { + $this->storage_key = $key ?? ''; + + return $this; + } + + /** + * @param int $timestamp + * @return $this + */ + public function setTimestamp($timestamp = null) + { + $this->storage_timestamp = $timestamp ?? time(); + + return $this; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::render() + */ + public function render(string $layout = null, array $context = []) + { + if (!$layout) { + $config = $this->getTemplateConfig(); + $layout = $config['object']['defaults']['layout'] ?? 'default'; + } + + $type = $this->getFlexType(); + + $grav = Grav::instance(); + + /** @var Debugger $debugger */ + $debugger = $grav['debugger']; + $debugger->startTimer('flex-object-' . ($debugKey = uniqid($type, false)), 'Render Object ' . $type . ' (' . $layout . ')'); + + $key = $this->getCacheKey(); + + // Disable caching if context isn't all scalars. + if ($key) { + foreach ($context as $value) { + if (!is_scalar($value)) { + $key = ''; + break; + } + } + } + + if ($key) { + // Create a new key which includes layout and context. + $key = md5($key . '.' . $layout . json_encode($context)); + $cache = $this->getCache('render'); + } else { + $cache = null; + } + + try { + $data = $cache ? $cache->get($key) : null; + + $block = $data ? HtmlBlock::fromArray($data) : null; + } catch (InvalidArgumentException $e) { + $debugger->addException($e); + + $block = null; + } catch (\InvalidArgumentException $e) { + $debugger->addException($e); + + $block = null; + } + + $checksum = $this->getCacheChecksum(); + if ($block && $checksum !== $block->getChecksum()) { + $block = null; + } + + if (!$block) { + $block = HtmlBlock::create($key ?: null); + $block->setChecksum($checksum); + if (!$cache) { + $block->disableCache(); + } + + $event = new Event([ + 'type' => 'flex', + 'directory' => $this->getFlexDirectory(), + 'object' => $this, + 'layout' => &$layout, + 'context' => &$context + ]); + $this->triggerEvent('onRender', $event); + + $output = $this->getTemplate($layout)->render( + [ + 'grav' => $grav, + 'config' => $grav['config'], + 'block' => $block, + 'directory' => $this->getFlexDirectory(), + 'object' => $this, + 'layout' => $layout + ] + $context + ); + + if ($debugger->enabled() && + !($grav['uri']->getContentType() === 'application/json' || $grav['uri']->extension() === 'json')) { + $name = $this->getKey() . ' (' . $type . ')'; + $output = "\n\n{$output}\n\n"; + } + + $block->setContent($output); + + try { + $cache && $block->isCached() && $cache->set($key, $block->toArray()); + } catch (InvalidArgumentException $e) { + $debugger->addException($e); + } + } + + $debugger->stopTimer('flex-object-' . $debugKey); + + return $block; + } + + /** + * @return array + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return $this->getElements(); + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::prepareStorage() + */ + public function prepareStorage(): array + { + return ['__META' => $this->getMetaData()] + $this->getElements(); + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::update() + */ + public function update(array $data, array $files = []) + { + if ($data) { + // Get currently stored data. + $elements = $this->getElements(); + + // Store original version of the object. + if ($this->_original === null) { + $this->_original = $elements; + } + + $blueprint = $this->getBlueprint(); + + // Process updated data through the object filters. + $this->filterElements($data); + + // Merge existing object to the test data to be validated. + $test = $blueprint->mergeData($elements, $data); + + // Validate and filter elements and throw an error if any issues were found. + $blueprint->validate($test + ['storage_key' => $this->getStorageKey(), 'timestamp' => $this->getTimestamp()], ['xss_check' => false]); + $data = $blueprint->filter($data, true, true); + + // Finally update the object. + $flattenData = $blueprint->flattenData($data); + foreach ($flattenData as $key => $value) { + if ($value === null) { + $this->unsetNestedProperty($key); + } else { + $this->setNestedProperty($key, $value); + } + } + } + + if ($files && method_exists($this, 'setUpdatedMedia')) { + $this->setUpdatedMedia($files); + } + + return $this; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::create() + */ + public function create(string $key = null) + { + if ($key) { + $this->setStorageKey($key); + } + + if ($this->exists()) { + throw new RuntimeException('Cannot create new object (Already exists)'); + } + + return $this->save(); + } + + /** + * @param string|null $key + * @return FlexObject|FlexObjectInterface + */ + public function createCopy(string $key = null) + { + $this->markAsCopy(); + + return $this->create($key); + } + + /** + * @param UserInterface|null $user + */ + public function check(UserInterface $user = null): void + { + // If user has been provided, check if the user has permissions to save this object. + if ($user && !$this->isAuthorized('save', null, $user)) { + throw new \RuntimeException('Forbidden', 403); + } + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::save() + */ + public function save() + { + $this->triggerEvent('onBeforeSave'); + + $storage = $this->getFlexDirectory()->getStorage(); + + $storageKey = $this->getStorageKey() ?: '@@' . spl_object_hash($this); + + $result = $storage->replaceRows([$storageKey => $this->prepareStorage()]); + + if (method_exists($this, 'clearMediaCache')) { + $this->clearMediaCache(); + } + + $value = reset($result); + $meta = $value['__META'] ?? null; + if ($meta) { + /** @phpstan-var class-string $indexClass */ + $indexClass = $this->getFlexDirectory()->getIndexClass(); + $indexClass::updateObjectMeta($meta, $value, $storage); + $this->_meta = $meta; + } + + if ($value) { + $storageKey = $meta['storage_key'] ?? (string)key($result); + if ($storageKey !== '') { + $this->setStorageKey($storageKey); + } + + $newKey = $meta['key'] ?? ($this->hasKey() ? $this->getKey() : null); + $this->setKey($newKey ?? $storageKey); + } + + // FIXME: For some reason locator caching isn't cleared for the file, investigate! + $locator = Grav::instance()['locator']; + $locator->clearCache(); + + if (method_exists($this, 'saveUpdatedMedia')) { + $this->saveUpdatedMedia(); + } + + try { + $this->getFlexDirectory()->reloadIndex(); + if (method_exists($this, 'clearMediaCache')) { + $this->clearMediaCache(); + } + } catch (Exception $e) { + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $debugger->addException($e); + + // Caching failed, but we can ignore that for now. + } + + $this->triggerEvent('onAfterSave'); + + return $this; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::delete() + */ + public function delete() + { + if (!$this->exists()) { + return $this; + } + + $this->triggerEvent('onBeforeDelete'); + + $this->getFlexDirectory()->getStorage()->deleteRows([$this->getStorageKey() => $this->prepareStorage()]); + + try { + $this->getFlexDirectory()->reloadIndex(); + if (method_exists($this, 'clearMediaCache')) { + $this->clearMediaCache(); + } + } catch (Exception $e) { + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $debugger->addException($e); + + // Caching failed, but we can ignore that for now. + } + + $this->triggerEvent('onAfterDelete'); + + return $this; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::getBlueprint() + */ + public function getBlueprint(string $name = '') + { + if (!isset($this->_blueprint[$name])) { + $blueprint = $this->doGetBlueprint($name); + $blueprint->setScope('object'); + $blueprint->setObject($this); + + $this->_blueprint[$name] = $blueprint->init(); + } + + return $this->_blueprint[$name]; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::getForm() + */ + public function getForm(string $name = '', array $options = null) + { + $hash = $name . '-' . md5(json_encode($options, JSON_THROW_ON_ERROR)); + if (!isset($this->_forms[$hash])) { + $this->_forms[$hash] = $this->createFormObject($name, $options); + } + + return $this->_forms[$hash]; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::getDefaultValue() + */ + public function getDefaultValue(string $name, string $separator = null) + { + $separator = $separator ?: '.'; + $path = explode($separator, $name); + $offset = array_shift($path); + + $current = $this->getDefaultValues(); + + if (!isset($current[$offset])) { + return null; + } + + $current = $current[$offset]; + + while ($path) { + $offset = array_shift($path); + + if ((is_array($current) || $current instanceof ArrayAccess) && isset($current[$offset])) { + $current = $current[$offset]; + } elseif (is_object($current) && isset($current->{$offset})) { + $current = $current->{$offset}; + } else { + return null; + } + }; + + return $current; + } + + /** + * @return array + */ + public function getDefaultValues(): array + { + return $this->getBlueprint()->getDefaults(); + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::getFormValue() + */ + public function getFormValue(string $name, $default = null, string $separator = null) + { + if ($name === 'storage_key') { + return $this->getStorageKey(); + } + if ($name === 'storage_timestamp') { + return $this->getTimestamp(); + } + + return $this->getNestedProperty($name, $default, $separator); + } + + /** + * @param FlexDirectory $directory + */ + public function setFlexDirectory(FlexDirectory $directory): void + { + $this->_flexDirectory = $directory; + } + + /** + * Returns a string representation of this object. + * + * @return string + */ + #[\ReturnTypeWillChange] + public function __toString() + { + return $this->getFlexKey(); + } + + /** + * @return array + */ + #[\ReturnTypeWillChange] + public function __debugInfo() + { + return [ + 'type:private' => $this->getFlexType(), + 'storage_key:protected' => $this->getStorageKey(), + 'storage_timestamp:protected' => $this->getTimestamp(), + 'key:private' => $this->getKey(), + 'elements:private' => $this->getElements(), + 'storage:private' => $this->getMetaData() + ]; + } + + /** + * Clone object. + */ + #[\ReturnTypeWillChange] + public function __clone() + { + // Allows future compatibility as parent::__clone() works. + } + + protected function markAsCopy(): void + { + $meta = $this->getMetaData(); + $meta['copy'] = true; + $this->_meta = $meta; + } + + /** + * @param string $name + * @return Blueprint + */ + protected function doGetBlueprint(string $name = ''): Blueprint + { + return $this->_flexDirectory->getBlueprint($name ? '.' . $name : $name); + } + + /** + * @param array $meta + */ + protected function setMetaData(array $meta): void + { + $this->_meta = $meta; + } + + /** + * @return array + */ + protected function doSerialize(): array + { + return [ + 'type' => $this->getFlexType(), + 'key' => $this->getKey(), + 'elements' => $this->getElements(), + 'storage' => $this->getMetaData() + ]; + } + + /** + * @param array $serialized + * @param FlexDirectory|null $directory + * @return void + */ + protected function doUnserialize(array $serialized, FlexDirectory $directory = null): void + { + $type = $serialized['type'] ?? 'unknown'; + + if (!isset($serialized['key'], $serialized['type'], $serialized['elements'])) { + throw new \InvalidArgumentException("Cannot unserialize '{$type}': Bad data"); + } + + if (null === $directory) { + $directory = $this->getFlexContainer()->getDirectory($type); + if (!$directory) { + throw new \InvalidArgumentException("Cannot unserialize Flex type '{$type}': Directory not found"); + } + } + + $this->setFlexDirectory($directory); + $this->setMetaData($serialized['storage']); + $this->setKey($serialized['key']); + $this->setElements($serialized['elements']); + } + + /** + * @return array + */ + protected function getTemplateConfig() + { + $config = $this->getFlexDirectory()->getConfig('site.templates', []); + $defaults = array_replace($config['defaults'] ?? [], $config['object']['defaults'] ?? []); + $config['object']['defaults'] = $defaults; + + return $config; + } + + /** + * @param string $layout + * @return array + */ + protected function getTemplatePaths(string $layout): array + { + $config = $this->getTemplateConfig(); + $type = $this->getFlexType(); + $defaults = $config['object']['defaults'] ?? []; + + $ext = $defaults['ext'] ?? '.html.twig'; + $types = array_unique(array_merge([$type], (array)($defaults['type'] ?? null))); + $paths = $config['object']['paths'] ?? [ + 'flex/{TYPE}/object/{LAYOUT}{EXT}', + 'flex-objects/layouts/{TYPE}/object/{LAYOUT}{EXT}' + ]; + $table = ['TYPE' => '%1$s', 'LAYOUT' => '%2$s', 'EXT' => '%3$s']; + + $lookups = []; + foreach ($paths as $path) { + $path = Utils::simpleTemplate($path, $table); + foreach ($types as $type) { + $lookups[] = sprintf($path, $type, $layout, $ext); + } + } + + return array_unique($lookups); + } + + /** + * Filter data coming to constructor or $this->update() request. + * + * NOTE: The incoming data can be an arbitrary array so do not assume anything from its content. + * + * @param array $elements + */ + protected function filterElements(array &$elements): void + { + if (isset($elements['storage_key'])) { + $elements['storage_key'] = trim($elements['storage_key']); + } + if (isset($elements['storage_timestamp'])) { + $elements['storage_timestamp'] = (int)$elements['storage_timestamp']; + } + + unset($elements['_post_entries_save']); + } + + /** + * This methods allows you to override form objects in child classes. + * + * @param string $name Form name + * @param array|null $options Form optiosn + * @return FlexFormInterface + */ + protected function createFormObject(string $name, array $options = null) + { + return new FlexForm($name, $this, $options); + } + + /** + * @param string $action + * @return string + */ + protected function getAuthorizeAction(string $action): string + { + // Handle special action save, which can mean either update or create. + if ($action === 'save') { + $action = $this->exists() ? 'update' : 'create'; + } + + return $action; + } + + /** + * Method to reset blueprints if the type changes. + * + * @return void + * @since 1.7.18 + */ + protected function resetBlueprints(): void + { + $this->_blueprint = []; + } + + // DEPRECATED METHODS + + /** + * @param bool $prefix + * @return string + * @deprecated 1.6 Use `->getFlexType()` instead. + */ + public function getType($prefix = false) + { + user_error(__METHOD__ . '() is deprecated since Grav 1.6, use ->getFlexType() method instead', E_USER_DEPRECATED); + + $type = $prefix ? $this->getTypePrefix() : ''; + + return $type . $this->getFlexType(); + } + + /** + * @param string $name + * @param mixed|null $default + * @param string|null $separator + * @return mixed + * + * @deprecated 1.6 Use ->getFormValue() method instead. + */ + public function value($name, $default = null, $separator = null) + { + user_error(__METHOD__ . '() is deprecated since Grav 1.6, use ->getFormValue() method instead', E_USER_DEPRECATED); + + return $this->getFormValue($name, $default, $separator); + } + + /** + * @param string $name + * @param object|null $event + * @return $this + * @deprecated 1.7 Moved to \Grav\Common\Flex\Traits\FlexObjectTrait + */ + public function triggerEvent(string $name, $event = null) + { + user_error(__METHOD__ . '() is deprecated since Grav 1.7, moved to \Grav\Common\Flex\Traits\FlexObjectTrait', E_USER_DEPRECATED); + + if (null === $event) { + $event = new Event([ + 'type' => 'flex', + 'directory' => $this->getFlexDirectory(), + 'object' => $this + ]); + } + if (strpos($name, 'onFlexObject') !== 0 && strpos($name, 'on') === 0) { + $name = 'onFlexObject' . substr($name, 2); + } + + $grav = Grav::instance(); + if ($event instanceof Event) { + $grav->fireEvent($name, $event); + } else { + $grav->dispatchEvent($event); + } + + return $this; + } + + /** + * @param array $storage + * @deprecated 1.7 Use `->setMetaData()` instead. + */ + protected function setStorage(array $storage): void + { + user_error(__METHOD__ . '() is deprecated since Grav 1.7, use ->setMetaData() method instead', E_USER_DEPRECATED); + + $this->setMetaData($storage); + } + + /** + * @return array + * @deprecated 1.7 Use `->getMetaData()` instead. + */ + protected function getStorage(): array + { + user_error(__METHOD__ . '() is deprecated since Grav 1.7, use ->getMetaData() method instead', E_USER_DEPRECATED); + + return $this->getMetaData(); + } + + /** + * @param string $layout + * @return Template|TemplateWrapper + * @throws LoaderError + * @throws SyntaxError + * @deprecated 1.7 Moved to \Grav\Common\Flex\Traits\GravTrait + */ + protected function getTemplate($layout) + { + user_error(__METHOD__ . '() is deprecated since Grav 1.7, moved to \Grav\Common\Flex\Traits\GravTrait', E_USER_DEPRECATED); + + $grav = Grav::instance(); + + /** @var Twig $twig */ + $twig = $grav['twig']; + + try { + return $twig->twig()->resolveTemplate($this->getTemplatePaths($layout)); + } catch (LoaderError $e) { + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $debugger->addException($e); + + return $twig->twig()->resolveTemplate(['flex/404.html.twig']); + } + } + + /** + * @return Flex + * @deprecated 1.7 Moved to \Grav\Common\Flex\Traits\GravTrait + */ + protected function getFlexContainer(): Flex + { + user_error(__METHOD__ . '() is deprecated since Grav 1.7, moved to \Grav\Common\Flex\Traits\GravTrait', E_USER_DEPRECATED); + + /** @var Flex $flex */ + $flex = Grav::instance()['flex']; + + return $flex; + } + + /** + * @return UserInterface|null + * @deprecated 1.7 Moved to \Grav\Common\Flex\Traits\GravTrait + */ + protected function getActiveUser(): ?UserInterface + { + user_error(__METHOD__ . '() is deprecated since Grav 1.7, moved to \Grav\Common\Flex\Traits\GravTrait', E_USER_DEPRECATED); + + /** @var UserInterface|null $user */ + $user = Grav::instance()['user'] ?? null; + + return $user; + } + + /** + * @return string + * @deprecated 1.7 Moved to \Grav\Common\Flex\Traits\GravTrait + */ + protected function getAuthorizeScope(): string + { + user_error(__METHOD__ . '() is deprecated since Grav 1.7, moved to \Grav\Common\Flex\Traits\GravTrait', E_USER_DEPRECATED); + + return isset(Grav::instance()['admin']) ? 'admin' : 'site'; + } +} diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexAuthorizeInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexAuthorizeInterface.php new file mode 100644 index 0000000..9561f59 --- /dev/null +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexAuthorizeInterface.php @@ -0,0 +1,33 @@ + + */ +interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionInterface, NestedObjectInterface +{ + /** + * Creates a Flex Collection from an array. + * + * @used-by FlexDirectory::createCollection() Official method to create a Flex Collection. + * + * @param FlexObjectInterface[] $entries Associated array of Flex Objects to be included in the collection. + * @param FlexDirectory $directory Flex Directory where all the objects belong into. + * @param string|null $keyField Key field used to index the collection. + * @return static Returns a new Flex Collection. + */ + public static function createFromArray(array $entries, FlexDirectory $directory, string $keyField = null); + + /** + * Creates a new Flex Collection. + * + * @used-by FlexDirectory::createCollection() Official method to create Flex Collection. + * + * @param FlexObjectInterface[] $entries Associated array of Flex Objects to be included in the collection. + * @param FlexDirectory|null $directory Flex Directory where all the objects belong into. + * @throws InvalidArgumentException + */ + public function __construct(array $entries = [], FlexDirectory $directory = null); + + /** + * Search a string from the collection. + * + * @param string $search Search string. + * @param string|string[]|null $properties Properties to search for, defaults to configured properties. + * @param array|null $options Search options, defaults to configured options. + * @return FlexCollectionInterface Returns a Flex Collection with only matching objects. + * @phpstan-return static + * @api + */ + public function search(string $search, $properties = null, array $options = null); + + /** + * Sort the collection. + * + * @param array $orderings Pair of [property => 'ASC'|'DESC', ...]. + * + * @return FlexCollectionInterface Returns a sorted version from the collection. + * @phpstan-return static + */ + public function sort(array $orderings); + + /** + * Filter collection by filter array with keys and values. + * + * @param array $filters + * @return FlexCollectionInterface + * @phpstan-return static + */ + public function filterBy(array $filters); + + /** + * Get timestamps from all the objects in the collection. + * + * This method can be used for example in caching. + * + * @return int[] Returns [key => timestamp, ...] pairs. + */ + public function getTimestamps(): array; + + /** + * Get storage keys from all the objects in the collection. + * + * @see FlexDirectory::getObject() If you want to get Flex Object from the Flex Directory. + * + * @return string[] Returns [key => storage_key, ...] pairs. + */ + public function getStorageKeys(): array; + + /** + * Get Flex keys from all the objects in the collection. + * + * @see Flex::getObjects() If you want to get list of Flex Objects from any Flex Directory. + * + * @return string[] Returns[key => flex_key, ...] pairs. + */ + public function getFlexKeys(): array; + + /** + * Return new collection with a different key. + * + * @param string|null $keyField Switch key field of the collection. + * @return FlexCollectionInterface Returns a new Flex Collection with new key field. + * @phpstan-return static + * @api + */ + public function withKeyField(string $keyField = null); + + /** + * Get Flex Index from the Flex Collection. + * + * @return FlexIndexInterface Returns a Flex Index from the current collection. + * @phpstan-return FlexIndexInterface + */ + public function getIndex(); + + /** + * Load all the objects into memory, + * + * @return FlexCollectionInterface + * @phpstan-return static + */ + public function getCollection(); + + /** + * Get metadata associated to the object + * + * @param string $key Key. + * @return array + */ + public function getMetaData($key): array; +} diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexCommonInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexCommonInterface.php new file mode 100644 index 0000000..03d5f4d --- /dev/null +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexCommonInterface.php @@ -0,0 +1,79 @@ +getBlueprint() or $object->getForm()->getBlueprint() instead. + * + * @param string $type + * @param string $context + * @return Blueprint + */ + public function getBlueprint(string $type = '', string $context = ''); + + /** + * @param string $view + * @return string + */ + public function getBlueprintFile(string $view = ''): string; + + /** + * Get collection. In the site this will be filtered by the default filters (published etc). + * + * Use $directory->getIndex() if you want unfiltered collection. + * + * @param array|null $keys Array of keys. + * @param string|null $keyField Field to be used as the key. + * @return FlexCollectionInterface + * @phpstan-return FlexCollectionInterface + */ + public function getCollection(array $keys = null, string $keyField = null): FlexCollectionInterface; + + /** + * Get the full collection of all stored objects. + * + * Use $directory->getCollection() if you want a filtered collection. + * + * @param array|null $keys Array of keys. + * @param string|null $keyField Field to be used as the key. + * @return FlexIndexInterface + * @phpstan-return FlexIndexInterface + */ + public function getIndex(array $keys = null, string $keyField = null): FlexIndexInterface; + + /** + * Returns an object if it exists. If no arguments are passed (or both of them are null), method creates a new empty object. + * + * Note: It is not safe to use the object without checking if the user can access it. + * + * @param string|null $key + * @param string|null $keyField Field to be used as the key. + * @return FlexObjectInterface|null + */ + public function getObject($key = null, string $keyField = null): ?FlexObjectInterface; + + /** + * @param string|null $namespace + * @return CacheInterface + */ + public function getCache(string $namespace = null); + + /** + * @return $this + */ + public function clearCache(); + + /** + * @param string|null $key + * @return string|null + */ + public function getStorageFolder(string $key = null): ?string; + + /** + * @param string|null $key + * @return string|null + */ + public function getMediaFolder(string $key = null): ?string; + + /** + * @return FlexStorageInterface + */ + public function getStorage(): FlexStorageInterface; + + /** + * @param array $data + * @param string $key + * @param bool $validate + * @return FlexObjectInterface + */ + public function createObject(array $data, string $key = '', bool $validate = false): FlexObjectInterface; + + /** + * @param array $entries + * @param string|null $keyField + * @return FlexCollectionInterface + * @phpstan-return FlexCollectionInterface + */ + public function createCollection(array $entries, string $keyField = null): FlexCollectionInterface; + + /** + * @param array $entries + * @param string|null $keyField + * @return FlexIndexInterface + * @phpstan-return FlexIndexInterface + */ + public function createIndex(array $entries, string $keyField = null): FlexIndexInterface; + + /** + * @return string + */ + public function getObjectClass(): string; + + /** + * @return string + */ + public function getCollectionClass(): string; + + /** + * @return string + */ + public function getIndexClass(): string; + + /** + * @param array $entries + * @param string|null $keyField + * @return FlexCollectionInterface + * @phpstan-return FlexCollectionInterface + */ + public function loadCollection(array $entries, string $keyField = null): FlexCollectionInterface; + + /** + * @param array $entries + * @return FlexObjectInterface[] + * @internal + */ + public function loadObjects(array $entries): array; + + /** + * @return void + */ + public function reloadIndex(): void; + + /** + * @param string $scope + * @param string $action + * @return string + */ + public function getAuthorizeRule(string $scope, string $action): string; +} diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexFormInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexFormInterface.php new file mode 100644 index 0000000..28c528c --- /dev/null +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexFormInterface.php @@ -0,0 +1,51 @@ + + */ +interface FlexIndexInterface extends FlexCollectionInterface +{ + /** + * Helper method to create Flex Index. + * + * @used-by FlexDirectory::getIndex() Official method to get Index from a Flex Directory. + * + * @param FlexDirectory $directory Flex directory. + * @return static Returns a new Flex Index. + */ + public static function createFromStorage(FlexDirectory $directory); + + /** + * Method to load index from the object storage, usually filesystem. + * + * @used-by FlexDirectory::getIndex() Official method to get Index from a Flex Directory. + * + * @param FlexStorageInterface $storage Flex Storage associated to the directory. + * @return array Returns a list of existing objects [storage_key => [storage_key => xxx, storage_timestamp => 123456, ...]] + */ + public static function loadEntriesFromStorage(FlexStorageInterface $storage): array; + + /** + * Return new collection with a different key. + * + * @param string|null $keyField Switch key field of the collection. + * @return static Returns a new Flex Collection with new key field. + * @phpstan-return static + * @api + */ + public function withKeyField(string $keyField = null); + + /** + * @param string|null $indexKey + * @return array + */ + public function getIndexMap(string $indexKey = null); +} diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexInterface.php new file mode 100644 index 0000000..3c9de49 --- /dev/null +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexInterface.php @@ -0,0 +1,100 @@ + + */ + public function getDirectories(array $types = null, bool $keepMissing = false): array; + + /** + * @param string $type + * @return FlexDirectory|null + */ + public function getDirectory(string $type): ?FlexDirectory; + + /** + * @param string $type + * @param array|null $keys + * @param string|null $keyField + * @return FlexCollectionInterface|null + * @phpstan-return FlexCollectionInterface|null + */ + public function getCollection(string $type, array $keys = null, string $keyField = null): ?FlexCollectionInterface; + + /** + * @param array $keys + * @param array $options In addition to the options in getObjects(), following options can be passed: + * collection_class: Class to be used to create the collection. Defaults to ObjectCollection. + * @return FlexCollectionInterface + * @throws RuntimeException + * @phpstan-return FlexCollectionInterface + */ + public function getMixedCollection(array $keys, array $options = []): FlexCollectionInterface; + + /** + * @param array $keys + * @param array $options Following optional options can be passed: + * types: List of allowed types. + * type: Allowed type if types isn't defined, otherwise acts as default_type. + * default_type: Set default type for objects given without type (only used if key_field isn't set). + * keep_missing: Set to true if you want to return missing objects as null. + * key_field: Key field which is used to match the objects. + * @return array + */ + public function getObjects(array $keys, array $options = []): array; + + /** + * @param string $key + * @param string|null $type + * @param string|null $keyField + * @return FlexObjectInterface|null + */ + public function getObject(string $key, string $type = null, string $keyField = null): ?FlexObjectInterface; + + /** + * @return int + */ + public function count(): int; +} diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexObjectFormInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexObjectFormInterface.php new file mode 100644 index 0000000..0370967 --- /dev/null +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexObjectFormInterface.php @@ -0,0 +1,27 @@ + + * @used-by \Grav\Framework\Flex\FlexObject + * @since 1.6 + */ +interface FlexObjectInterface extends FlexCommonInterface, NestedObjectInterface, ArrayAccess +{ + /** + * Construct a new Flex Object instance. + * + * @used-by FlexDirectory::createObject() Method to create Flex Object. + * + * @param array $elements Array of object properties. + * @param string $key Identifier key for the new object. + * @param FlexDirectory $directory Flex Directory the object belongs into. + * @param bool $validate True if the object should be validated against blueprint. + * @throws InvalidArgumentException + */ + public function __construct(array $elements, $key, FlexDirectory $directory, bool $validate = false); + + /** + * Search a string from the object, returns weight between 0 and 1. + * + * Note: If you override this function, make sure you return value in range 0...1! + * + * @used-by FlexCollectionInterface::search() If you want to search a string from a Flex Collection. + * + * @param string $search Search string. + * @param string|string[]|null $properties Properties to search for, defaults to configured properties. + * @param array|null $options Search options, defaults to configured options. + * @return float Returns a weight between 0 and 1. + * @api + */ + public function search(string $search, $properties = null, array $options = null): float; + + /** + * Returns true if object has a key. + * + * @return bool + */ + public function hasKey(); + + /** + * Get a unique key for the object. + * + * Flex Keys can be used without knowing the Directory the Object belongs into. + * + * @see Flex::getObject() If you want to get Flex Object from any Flex Directory. + * @see Flex::getObjects() If you want to get list of Flex Objects from any Flex Directory. + * + * NOTE: Please do not override the method! + * + * @return string Returns Flex Key of the object. + * @api + */ + public function getFlexKey(): string; + + /** + * Get an unique storage key (within the directory) which is used for figuring out the filename or database id. + * + * @see FlexDirectory::getObject() If you want to get Flex Object from the Flex Directory. + * @see FlexDirectory::getCollection() If you want to get Flex Collection with selected keys from the Flex Directory. + * + * @return string Returns storage key of the Object. + * @api + */ + public function getStorageKey(): string; + + /** + * Get index data associated to the object. + * + * @return array Returns metadata of the object. + */ + public function getMetaData(): array; + + /** + * Returns true if the object exists in the storage. + * + * @return bool Returns `true` if the object exists, `false` otherwise. + * @api + */ + public function exists(): bool; + + /** + * Prepare object for saving into the storage. + * + * @return array Returns an array of object properties containing only scalars and arrays. + */ + public function prepareStorage(): array; + + /** + * Updates object in the memory. + * + * @see FlexObjectInterface::save() You need to save the object after calling this method. + * + * @param array $data Data containing updated properties with their values. To unset a value, use `null`. + * @param array|UploadedFileInterface[] $files List of uploaded files to be saved within the object. + * @return static + * @throws RuntimeException + * @api + */ + public function update(array $data, array $files = []); + + /** + * Create new object into the storage. + * + * @see FlexDirectory::createObject() If you want to create a new object instance. + * @see FlexObjectInterface::update() If you want to update properties of the object. + * + * @param string|null $key Optional new key. If key isn't given, random key will be associated to the object. + * @return static + * @throws RuntimeException if object already exists. + * @api + */ + public function create(string $key = null); + + /** + * Save object into the storage. + * + * @see FlexObjectInterface::update() If you want to update properties of the object. + * + * @return static + * @api + */ + public function save(); + + /** + * Delete object from the storage. + * + * @return static + * @api + */ + public function delete(); + + /** + * Returns the blueprint of the object. + * + * @see FlexObjectInterface::getForm() + * @used-by FlexForm::getBlueprint() + * + * @param string $name Name of the Blueprint form. Used to create customized forms for different use cases. + * @return Blueprint Returns a Blueprint. + */ + public function getBlueprint(string $name = ''); + + /** + * Returns a form instance for the object. + * + * @param string $name Name of the form. Can be used to create customized forms for different use cases. + * @param array|null $options Options can be used to further customize the form. + * @return FlexFormInterface Returns a Form. + * @api + */ + public function getForm(string $name = '', array $options = null); + + /** + * Returns default value suitable to be used in a form for the given property. + * + * @see FlexObjectInterface::getForm() + * + * @param string $name Property name. + * @param string|null $separator Optional nested property separator. + * @return mixed|null Returns default value of the field, null if there is no default value. + */ + public function getDefaultValue(string $name, string $separator = null); + + /** + * Returns default values suitable to be used in a form for the given property. + * + * @see FlexObjectInterface::getForm() + * + * @return array Returns default values. + */ + public function getDefaultValues(): array; + + /** + * Returns raw value suitable to be used in a form for the given property. + * + * @see FlexObjectInterface::getForm() + * + * @param string $name Property name. + * @param mixed $default Default value. + * @param string|null $separator Optional nested property separator. + * @return mixed Returns value of the field. + */ + public function getFormValue(string $name, $default = null, string $separator = null); +} diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexStorageInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexStorageInterface.php new file mode 100644 index 0000000..4980696 --- /dev/null +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexStorageInterface.php @@ -0,0 +1,138 @@ + [storage_key => key, storage_timestamp => timestamp], ...]`. + */ + public function getExistingKeys(): array; + + /** + * Check if the key exists in the storage. + * + * @param string $key Storage key of an object. + * @return bool Returns `true` if the key exists in the storage, `false` otherwise. + */ + public function hasKey(string $key): bool; + + /** + * Check if the key exists in the storage. + * + * @param string[] $keys Storage key of an object. + * @return bool[] Returns keys with `true` if the key exists in the storage, `false` otherwise. + */ + public function hasKeys(array $keys): array; + + /** + * Create new rows into the storage. + * + * New keys will be assigned when the objects are created. + * + * @param array $rows List of rows as `[row, ...]`. + * @return array Returns created rows as `[key => row, ...] pairs. + */ + public function createRows(array $rows): array; + + /** + * Read rows from the storage. + * + * If you pass object or array as value, that value will be used to save I/O. + * + * @param array $rows Array of `[key => row, ...]` pairs. + * @param array|null $fetched Optional reference to store only fetched items. + * @return array Returns rows. Note that non-existing rows will have `null` as their value. + */ + public function readRows(array $rows, array &$fetched = null): array; + + /** + * Update existing rows in the storage. + * + * @param array $rows Array of `[key => row, ...]` pairs. + * @return array Returns updated rows. Note that non-existing rows will not be saved and have `null` as their value. + */ + public function updateRows(array $rows): array; + + /** + * Delete rows from the storage. + * + * @param array $rows Array of `[key => row, ...]` pairs. + * @return array Returns deleted rows. Note that non-existing rows have `null` as their value. + */ + public function deleteRows(array $rows): array; + + /** + * Replace rows regardless if they exist or not. + * + * All rows should have a specified key for replace to work properly. + * + * @param array $rows Array of `[key => row, ...]` pairs. + * @return array Returns both created and updated rows. + */ + public function replaceRows(array $rows): array; + + /** + * @param string $src + * @param string $dst + * @return bool + */ + public function copyRow(string $src, string $dst): bool; + + /** + * @param string $src + * @param string $dst + * @return bool + */ + public function renameRow(string $src, string $dst): bool; + + /** + * Get filesystem path for the collection or object storage. + * + * @param string|null $key Optional storage key. + * @return string|null Path in the filesystem. Can be URI or null if storage is not filesystem based. + */ + public function getStoragePath(string $key = null): ?string; + + /** + * Get filesystem path for the collection or object media. + * + * @param string|null $key Optional storage key. + * @return string|null Path in the filesystem. Can be URI or null if media isn't supported. + */ + public function getMediaPath(string $key = null): ?string; +} diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexTranslateInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexTranslateInterface.php new file mode 100644 index 0000000..1ae8b7e --- /dev/null +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexTranslateInterface.php @@ -0,0 +1,51 @@ + + */ +class FlexPageCollection extends FlexCollection +{ + /** + * @return array + */ + public static function getCachedMethods(): array + { + return [ + // Collection filtering + 'withPublished' => true, + 'withVisible' => true, + 'withRoutable' => true, + + 'isFirst' => true, + 'isLast' => true, + + // Find objects + 'prevSibling' => false, + 'nextSibling' => false, + 'adjacentSibling' => false, + 'currentPosition' => true, + + 'getNextOrder' => false, + ] + parent::getCachedMethods(); + } + + /** + * @param bool $bool + * @return static + * @phpstan-return static + */ + public function withPublished(bool $bool = true) + { + /** @var string[] $list */ + $list = array_keys(array_filter($this->call('isPublished', [$bool]))); + + /** @phpstan-var static */ + return $this->select($list); + } + + /** + * @param bool $bool + * @return static + * @phpstan-return static + */ + public function withVisible(bool $bool = true) + { + /** @var string[] $list */ + $list = array_keys(array_filter($this->call('isVisible', [$bool]))); + + /** @phpstan-var static */ + return $this->select($list); + } + + /** + * @param bool $bool + * @return static + * @phpstan-return static + */ + public function withRoutable(bool $bool = true) + { + /** @var string[] $list */ + $list = array_keys(array_filter($this->call('isRoutable', [$bool]))); + + /** @phpstan-var static */ + return $this->select($list); + } + + /** + * Check to see if this item is the first in the collection. + * + * @param string $path + * @return bool True if item is first. + */ + public function isFirst($path): bool + { + $keys = $this->getKeys(); + $first = reset($keys); + + return $path === $first; + } + + /** + * Check to see if this item is the last in the collection. + * + * @param string $path + * @return bool True if item is last. + */ + public function isLast($path): bool + { + $keys = $this->getKeys(); + $last = end($keys); + + return $path === $last; + } + + /** + * Gets the previous sibling based on current position. + * + * @param string $path + * @return PageInterface|false The previous item. + * @phpstan-return T|false + */ + public function prevSibling($path) + { + return $this->adjacentSibling($path, -1); + } + + /** + * Gets the next sibling based on current position. + * + * @param string $path + * @return PageInterface|false The next item. + * @phpstan-return T|false + */ + public function nextSibling($path) + { + return $this->adjacentSibling($path, 1); + } + + /** + * Returns the adjacent sibling based on a direction. + * + * @param string $path + * @param int $direction either -1 or +1 + * @return PageInterface|false The sibling item. + * @phpstan-return T|false + */ + public function adjacentSibling($path, $direction = 1) + { + $keys = $this->getKeys(); + $direction = (int)$direction; + $pos = array_search($path, $keys, true); + + if (is_int($pos)) { + $pos += $direction; + if (isset($keys[$pos])) { + return $this[$keys[$pos]]; + } + } + + return false; + } + + /** + * Returns the item in the current position. + * + * @param string $path the path the item + * @return int|null The index of the current page, null if not found. + */ + public function currentPosition($path): ?int + { + $pos = array_search($path, $this->getKeys(), true); + + return is_int($pos) ? $pos : null; + } + + /** + * @return string + */ + public function getNextOrder() + { + $directory = $this->getFlexDirectory(); + + $collection = $directory->getIndex(); + $keys = $collection->getStorageKeys(); + + // Assign next free order. + $last = null; + $order = 0; + foreach ($keys as $folder => $key) { + preg_match(FlexPageIndex::ORDER_PREFIX_REGEX, $folder, $test); + $test = $test[0] ?? null; + if ($test && $test > $order) { + $order = $test; + $last = $key; + } + } + + /** @var FlexPageObject|null $last */ + $last = $collection[$last]; + + return sprintf('%d.', $last ? $last->getFormValue('order') + 1 : 1); + } +} diff --git a/system/src/Grav/Framework/Flex/Pages/FlexPageIndex.php b/system/src/Grav/Framework/Flex/Pages/FlexPageIndex.php new file mode 100644 index 0000000..507a11f --- /dev/null +++ b/system/src/Grav/Framework/Flex/Pages/FlexPageIndex.php @@ -0,0 +1,48 @@ + + */ +class FlexPageIndex extends FlexIndex +{ + public const ORDER_PREFIX_REGEX = '/^\d+\./u'; + + /** + * @param string $route + * @return string + * @internal + */ + public static function normalizeRoute(string $route) + { + static $case_insensitive; + + if (null === $case_insensitive) { + $case_insensitive = Grav::instance()['config']->get('system.force_lowercase_urls', false); + } + + return $case_insensitive ? mb_strtolower($route) : $route; + } +} diff --git a/system/src/Grav/Framework/Flex/Pages/FlexPageObject.php b/system/src/Grav/Framework/Flex/Pages/FlexPageObject.php new file mode 100644 index 0000000..79d9284 --- /dev/null +++ b/system/src/Grav/Framework/Flex/Pages/FlexPageObject.php @@ -0,0 +1,496 @@ +header)) { + $this->header = clone($this->header); + } + } + + /** + * @return array + */ + public static function getCachedMethods(): array + { + return [ + // Page Content Interface + 'header' => false, + 'summary' => true, + 'content' => true, + 'value' => false, + 'media' => false, + 'title' => true, + 'menu' => true, + 'visible' => true, + 'published' => true, + 'publishDate' => true, + 'unpublishDate' => true, + 'process' => true, + 'slug' => true, + 'order' => true, + 'id' => true, + 'modified' => true, + 'lastModified' => true, + 'folder' => true, + 'date' => true, + 'dateformat' => true, + 'taxonomy' => true, + 'shouldProcess' => true, + 'isPage' => true, + 'isDir' => true, + 'folderExists' => true, + + // Page + 'isPublished' => true, + 'isOrdered' => true, + 'isVisible' => true, + 'isRoutable' => true, + 'getCreated_Timestamp' => true, + 'getPublish_Timestamp' => true, + 'getUnpublish_Timestamp' => true, + 'getUpdated_Timestamp' => true, + ] + parent::getCachedMethods(); + } + + /** + * @param bool $test + * @return bool + */ + public function isPublished(bool $test = true): bool + { + $time = time(); + $start = $this->getPublish_Timestamp(); + $stop = $this->getUnpublish_Timestamp(); + + return $this->published() && $start <= $time && (!$stop || $time <= $stop) === $test; + } + + /** + * @param bool $test + * @return bool + */ + public function isOrdered(bool $test = true): bool + { + return ($this->order() !== false) === $test; + } + + /** + * @param bool $test + * @return bool + */ + public function isVisible(bool $test = true): bool + { + return $this->visible() === $test; + } + + /** + * @param bool $test + * @return bool + */ + public function isRoutable(bool $test = true): bool + { + return $this->routable() === $test; + } + + /** + * @return int + */ + public function getCreated_Timestamp(): int + { + return $this->getFieldTimestamp('created_date') ?? 0; + } + + /** + * @return int + */ + public function getPublish_Timestamp(): int + { + return $this->getFieldTimestamp('publish_date') ?? $this->getCreated_Timestamp(); + } + + /** + * @return int|null + */ + public function getUnpublish_Timestamp(): ?int + { + return $this->getFieldTimestamp('unpublish_date'); + } + + /** + * @return int + */ + public function getUpdated_Timestamp(): int + { + return $this->getFieldTimestamp('updated_date') ?? $this->getPublish_Timestamp(); + } + + /** + * @inheritdoc + */ + public function getFormValue(string $name, $default = null, string $separator = null) + { + $test = new stdClass(); + + $value = $this->pageContentValue($name, $test); + if ($value !== $test) { + return $value; + } + + switch ($name) { + case 'name': + return $this->getProperty('template'); + case 'route': + return $this->hasKey() ? '/' . $this->getKey() : null; + case 'header.permissions.groups': + $encoded = json_encode($this->getPermissions()); + if ($encoded === false) { + throw new RuntimeException('json_encode(): failed to encode group permissions'); + } + + return json_decode($encoded, true); + } + + return parent::getFormValue($name, $default, $separator); + } + + /** + * Get master storage key. + * + * @return string + * @see FlexObjectInterface::getStorageKey() + */ + public function getMasterKey(): string + { + $key = (string)($this->storage_key ?? $this->getMetaData()['storage_key'] ?? null); + if (($pos = strpos($key, '|')) !== false) { + $key = substr($key, 0, $pos); + } + + return $key; + } + + /** + * {@inheritdoc} + * @see FlexObjectInterface::getCacheKey() + */ + public function getCacheKey(): string + { + return $this->hasKey() ? $this->getTypePrefix() . $this->getFlexType() . '.' . $this->getKey() . '.' . $this->getLanguage() : ''; + } + + /** + * @param string|null $key + * @return FlexObjectInterface + */ + public function createCopy(string $key = null) + { + $this->copy(); + + return parent::createCopy($key); + } + + /** + * @param array|bool $reorder + * @return FlexObject|FlexObjectInterface + */ + public function save($reorder = true) + { + return parent::save(); + } + + /** + * Gets the Page Unmodified (original) version of the page. + * + * Assumes that object has been cloned before modifying it. + * + * @return FlexPageObject|null The original version of the page. + */ + public function getOriginal() + { + return $this->_originalObject; + } + + /** + * Store the Page Unmodified (original) version of the page. + * + * Can be called multiple times, only the first call matters. + * + * @return void + */ + public function storeOriginal(): void + { + if (null === $this->_originalObject) { + $this->_originalObject = clone $this; + } + } + + /** + * Get display order for the associated media. + * + * @return array + */ + public function getMediaOrder(): array + { + $order = $this->getNestedProperty('header.media_order'); + + if (is_array($order)) { + return $order; + } + + if (!$order) { + return []; + } + + return array_map('trim', explode(',', $order)); + } + + // Overrides for header properties. + + /** + * Common logic to load header properties. + * + * @param string $property + * @param mixed $var + * @param callable $filter + * @return mixed|null + */ + protected function loadHeaderProperty(string $property, $var, callable $filter) + { + // We have to use parent methods in order to avoid loops. + $value = null === $var ? parent::getProperty($property) : null; + if (null === $value) { + $value = $filter($var ?? $this->getProperty('header')->get($property)); + + parent::setProperty($property, $value); + if ($this->doHasProperty($property)) { + $value = parent::getProperty($property); + } + } + + return $value; + } + + /** + * Common logic to load header properties. + * + * @param string $property + * @param mixed $var + * @param callable $filter + * @return mixed|null + */ + protected function loadProperty(string $property, $var, callable $filter) + { + // We have to use parent methods in order to avoid loops. + $value = null === $var ? parent::getProperty($property) : null; + if (null === $value) { + $value = $filter($var); + + parent::setProperty($property, $value); + if ($this->doHasProperty($property)) { + $value = parent::getProperty($property); + } + } + + return $value; + } + + /** + * @param string $property + * @param mixed $default + * @return mixed + */ + public function getProperty($property, $default = null) + { + $method = static::$headerProperties[$property] ?? static::$calculatedProperties[$property] ?? null; + if ($method && method_exists($this, $method)) { + return $this->{$method}(); + } + + return parent::getProperty($property, $default); + } + + /** + * @param string $property + * @param mixed $value + * @return $this + */ + public function setProperty($property, $value) + { + $method = static::$headerProperties[$property] ?? static::$calculatedProperties[$property] ?? null; + if ($method && method_exists($this, $method)) { + $this->{$method}($value); + + return $this; + } + + parent::setProperty($property, $value); + + return $this; + } + + /** + * @param string $property + * @param mixed $value + * @param string|null $separator + * @return $this + */ + public function setNestedProperty($property, $value, $separator = null) + { + $separator = $separator ?: '.'; + if (strpos($property, 'header' . $separator) === 0) { + $this->getProperty('header')->set(str_replace('header' . $separator, '', $property), $value, $separator); + + return $this; + } + + parent::setNestedProperty($property, $value, $separator); + + return $this; + } + + /** + * @param string $property + * @param string|null $separator + * @return $this + */ + public function unsetNestedProperty($property, $separator = null) + { + $separator = $separator ?: '.'; + if (strpos($property, 'header' . $separator) === 0) { + $this->getProperty('header')->undef(str_replace('header' . $separator, '', $property), $separator); + + return $this; + } + + parent::unsetNestedProperty($property, $separator); + + return $this; + } + + /** + * @param array $elements + * @param bool $extended + * @return void + */ + protected function filterElements(array &$elements, bool $extended = false): void + { + // Markdown storage conversion to page structure. + if (array_key_exists('content', $elements)) { + $elements['markdown'] = $elements['content']; + unset($elements['content']); + } + + if (!$extended) { + $folder = !empty($elements['folder']) ? trim($elements['folder']) : ''; + + if ($folder) { + $order = !empty($elements['order']) ? (int)$elements['order'] : null; + // TODO: broken + $elements['storage_key'] = $order ? sprintf('%02d.%s', $order, $folder) : $folder; + } + } + + parent::filterElements($elements); + } + + /** + * @param string $field + * @return int|null + */ + protected function getFieldTimestamp(string $field): ?int + { + $date = $this->getFieldDateTime($field); + + return $date ? $date->getTimestamp() : null; + } + + /** + * @param string $field + * @return DateTime|null + */ + protected function getFieldDateTime(string $field): ?DateTime + { + try { + $value = $this->getProperty($field); + if (is_numeric($value)) { + $value = '@' . $value; + } + $date = $value ? new DateTime($value) : null; + } catch (Exception $e) { + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $debugger->addException($e); + + $date = null; + } + + return $date; + } + + /** + * @return UserCollectionInterface|null + * @internal + */ + protected function loadAccounts() + { + return Grav::instance()['accounts'] ?? null; + } +} diff --git a/system/src/Grav/Framework/Flex/Pages/Traits/PageAuthorsTrait.php b/system/src/Grav/Framework/Flex/Pages/Traits/PageAuthorsTrait.php new file mode 100644 index 0000000..1061cbb --- /dev/null +++ b/system/src/Grav/Framework/Flex/Pages/Traits/PageAuthorsTrait.php @@ -0,0 +1,249 @@ + */ + private $_authors; + /** @var array|null */ + private $_permissionsCache; + + /** + * Returns true if object has the named author. + * + * @param string $username + * @return bool + */ + public function hasAuthor(string $username): bool + { + $authors = (array)$this->getNestedProperty('header.permissions.authors'); + if (empty($authors)) { + return false; + } + + foreach ($authors as $author) { + if ($username === $author) { + return true; + } + } + + return false; + } + + /** + * Get list of all author objects. + * + * @return array + */ + public function getAuthors(): array + { + if (null === $this->_authors) { + $this->_authors = $this->loadAuthors($this->getNestedProperty('header.permissions.authors', [])); + } + + return $this->_authors; + } + + /** + * @param bool $inherit + * @return array + */ + public function getPermissions(bool $inherit = false) + { + if (null === $this->_permissionsCache) { + $permissions = []; + if ($inherit && $this->getNestedProperty('header.permissions.inherit', true)) { + $parent = $this->parent(); + if ($parent && method_exists($parent, 'getPermissions')) { + $permissions = $parent->getPermissions($inherit); + } + } + + $this->_permissionsCache = $this->loadPermissions($permissions); + } + + return $this->_permissionsCache; + } + + /** + * @param iterable $authors + * @return array + */ + protected function loadAuthors(iterable $authors): array + { + $accounts = $this->loadAccounts(); + if (null === $accounts || empty($authors)) { + return []; + } + + $list = []; + foreach ($authors as $username) { + if (!is_string($username)) { + throw new InvalidArgumentException('Iterable should return username (string).', 500); + } + $list[] = $accounts->load($username); + } + + return $list; + } + + /** + * @param string $action + * @param string|null $scope + * @param UserInterface|null $user + * @param bool $isAuthor + * @return bool|null + */ + public function isParentAuthorized(string $action, string $scope = null, UserInterface $user = null, bool $isAuthor = false): ?bool + { + $scope = $scope ?? $this->getAuthorizeScope(); + + $isMe = null === $user; + if ($isMe) { + $user = $this->getActiveUser(); + } + + if (null === $user) { + return false; + } + + return $this->isAuthorizedByGroup($user, $action, $scope, $isMe, $isAuthor); + } + + /** + * @param UserInterface $user + * @param string $action + * @param string $scope + * @param bool $isMe + * @return bool|null + */ + protected function isAuthorizedOverride(UserInterface $user, string $action, string $scope, bool $isMe): ?bool + { + if ($action === 'delete' && $this->root()) { + // Do not allow deleting root. + return false; + } + + $isAuthor = !$isMe || $user->authorized ? $this->hasAuthor($user->username) : false; + + return $this->isAuthorizedByGroup($user, $action, $scope, $isMe, $isAuthor) ?? parent::isAuthorizedOverride($user, $action, $scope, $isMe); + } + + /** + * Group authorization works as follows: + * + * 1. if any of the groups deny access, return false + * 2. else if any of the groups allow access, return true + * 3. else return null + * + * @param UserInterface $user + * @param string $action + * @param string $scope + * @param bool $isMe + * @param bool $isAuthor + * @return bool|null + */ + protected function isAuthorizedByGroup(UserInterface $user, string $action, string $scope, bool $isMe, bool $isAuthor): ?bool + { + $authorized = null; + + // In admin we want to check against group permissions. + $pageGroups = $this->getPermissions(); + $userGroups = (array)$user->groups; + + /** @var Access $access */ + foreach ($pageGroups as $group => $access) { + if ($group === 'defaults') { + // Special defaults permissions group does not apply to guest. + if ($isMe && !$user->authorized) { + continue; + } + } elseif ($group === 'authors') { + if (!$isAuthor) { + continue; + } + } elseif (!in_array($group, $userGroups, true)) { + continue; + } + + $auth = $access->authorize($action); + if (is_bool($auth)) { + if ($auth === false) { + return false; + } + + $authorized = true; + } + } + + if (null === $authorized && $this->getNestedProperty('header.permissions.inherit', true)) { + // Authorize against parent page. + $parent = $this->parent(); + if ($parent && method_exists($parent, 'isParentAuthorized')) { + $authorized = $parent->isParentAuthorized($action, $scope, !$isMe ? $user : null, $isAuthor); + } + } + + return $authorized; + } + + /** + * @param array $parent + * @return array + */ + protected function loadPermissions(array $parent = []): array + { + static $rules = [ + 'c' => 'create', + 'r' => 'read', + 'u' => 'update', + 'd' => 'delete', + 'p' => 'publish', + 'l' => 'list' + ]; + + $permissions = $this->getNestedProperty('header.permissions.groups'); + $name = $this->root() ? '' : '/' . $this->getKey(); + + $list = []; + if (is_array($permissions)) { + foreach ($permissions as $group => $access) { + $list[$group] = new Access($access, $rules, $name); + } + } + foreach ($parent as $group => $access) { + if (isset($list[$group])) { + $object = $list[$group]; + } else { + $object = new Access([], $rules, $name); + $list[$group] = $object; + } + + $object->inherit($access); + } + + return $list; + } +} diff --git a/system/src/Grav/Framework/Flex/Pages/Traits/PageContentTrait.php b/system/src/Grav/Framework/Flex/Pages/Traits/PageContentTrait.php new file mode 100644 index 0000000..99c5dfd --- /dev/null +++ b/system/src/Grav/Framework/Flex/Pages/Traits/PageContentTrait.php @@ -0,0 +1,842 @@ + 'slug', + 'routes' => false, + 'title' => 'title', + 'language' => 'language', + 'template' => 'template', + 'menu' => 'menu', + 'routable' => 'routable', + 'visible' => 'visible', + 'redirect' => 'redirect', + 'external_url' => false, + 'order_dir' => 'orderDir', + 'order_by' => 'orderBy', + 'order_manual' => 'orderManual', + 'dateformat' => 'dateformat', + 'date' => 'date', + 'markdown_extra' => false, + 'taxonomy' => 'taxonomy', + 'max_count' => 'maxCount', + 'process' => 'process', + 'published' => 'published', + 'publish_date' => 'publishDate', + 'unpublish_date' => 'unpublishDate', + 'expires' => 'expires', + 'cache_control' => 'cacheControl', + 'etag' => 'eTag', + 'last_modified' => 'lastModified', + 'ssl' => 'ssl', + 'template_format' => 'templateFormat', + 'debugger' => false, + ]; + + /** @var array */ + protected static $calculatedProperties = [ + 'name' => 'name', + 'parent' => 'parent', + 'parent_key' => 'parentStorageKey', + 'folder' => 'folder', + 'order' => 'order', + 'template' => 'template', + ]; + + /** @var object|null */ + protected $header; + + /** @var string|null */ + protected $_summary; + + /** @var string|null */ + protected $_content; + + /** + * Method to normalize the route. + * + * @param string $route + * @return string + * @internal + */ + public static function normalizeRoute($route): string + { + $case_insensitive = Grav::instance()['config']->get('system.force_lowercase_urls'); + + return $case_insensitive ? mb_strtolower($route) : $route; + } + + /** + * @inheritdoc + * @return Header + */ + public function header($var = null) + { + if (null !== $var) { + $this->setProperty('header', $var); + } + + return $this->getProperty('header'); + } + + /** + * @inheritdoc + */ + public function summary($size = null, $textOnly = false): string + { + return $this->processSummary($size, $textOnly); + } + + /** + * @inheritdoc + */ + public function setSummary($summary): void + { + $this->_summary = $summary; + } + + /** + * @inheritdoc + * @throws Exception + */ + public function content($var = null): string + { + if (null !== $var) { + $this->_content = $var; + } + + return $this->_content ?? $this->processContent($this->getRawContent()); + } + + /** + * @inheritdoc + */ + public function getRawContent(): string + { + return $this->_content ?? $this->getArrayProperty('markdown') ?? ''; + } + + /** + * @inheritdoc + */ + public function setRawContent($content): void + { + $this->_content = $content ?? ''; + } + + /** + * @inheritdoc + */ + public function rawMarkdown($var = null): string + { + if ($var !== null) { + $this->setProperty('markdown', $var); + } + + return $this->getProperty('markdown') ?? ''; + } + + /** + * @inheritdoc + * + * Implement by calling: + * + * $test = new \stdClass(); + * $value = $this->pageContentValue($name, $test); + * if ($value !== $test) { + * return $value; + * } + * return parent::value($name, $default); + */ + abstract public function value($name, $default = null, $separator = null); + + /** + * @inheritdoc + */ + public function media($var = null): Media + { + if ($var instanceof Media) { + $this->setProperty('media', $var); + } + + return $this->getProperty('media'); + } + + /** + * @inheritdoc + */ + public function title($var = null): string + { + return $this->loadHeaderProperty( + 'title', + $var, + function ($value) { + return trim($value ?? ($this->root() ? '' : ucfirst($this->slug()))); + } + ); + } + + /** + * @inheritdoc + */ + public function menu($var = null): string + { + return $this->loadHeaderProperty( + 'menu', + $var, + function ($value) { + return trim($value ?: $this->title()); + } + ); + } + + /** + * @inheritdoc + */ + public function visible($var = null): bool + { + $value = $this->loadHeaderProperty( + 'visible', + $var, + function ($value) { + return ($value ?? $this->order() !== false) && !$this->isModule(); + } + ); + + return $value && $this->published(); + } + + /** + * @inheritdoc + */ + public function published($var = null): bool + { + return $this->loadHeaderProperty( + 'published', + $var, + static function ($value) { + return (bool)($value ?? true); + } + ); + } + + /** + * @inheritdoc + */ + public function publishDate($var = null): ?int + { + return $this->loadHeaderProperty( + 'publish_date', + $var, + function ($value) { + return $value ? Utils::date2timestamp($value, $this->getProperty('dateformat')) : null; + } + ); + } + + /** + * @inheritdoc + */ + public function unpublishDate($var = null): ?int + { + return $this->loadHeaderProperty( + 'unpublish_date', + $var, + function ($value) { + return $value ? Utils::date2timestamp($value, $this->getProperty('dateformat')) : null; + } + ); + } + + /** + * @inheritdoc + */ + public function process($var = null): array + { + return $this->loadHeaderProperty( + 'process', + $var, + function ($value) { + $value = array_replace(Grav::instance()['config']->get('system.pages.process', []), is_array($value) ? $value : []); + foreach ($value as $process => $status) { + $value[$process] = (bool)$status; + } + + return $value; + } + ); + } + + /** + * @inheritdoc + */ + public function slug($var = null) + { + return $this->loadHeaderProperty( + 'slug', + $var, + function ($value) { + if (is_string($value)) { + return $value; + } + + $folder = $this->folder(); + if (null === $folder) { + return null; + } + + $folder = preg_replace(static::PAGE_ORDER_PREFIX_REGEX, '', $folder); + if (null === $folder) { + return null; + } + + return static::normalizeRoute($folder); + } + ); + } + + /** + * @inheritdoc + */ + public function order($var = null) + { + $property = $this->loadProperty( + 'order', + $var, + function ($value) { + if (null === $value) { + $folder = $this->folder(); + if (null !== $folder) { + preg_match(static::PAGE_ORDER_REGEX, $folder, $order); + } + + $value = $order[1] ?? false; + } + + if ($value === '') { + $value = false; + } + if ($value !== false) { + $value = (int)$value; + } + + return $value; + } + ); + + return $property !== false ? sprintf('%02d.', $property) : false; + } + + /** + * @inheritdoc + */ + public function id($var = null): string + { + $property = 'id'; + $value = null === $var ? $this->getProperty($property) : null; + if (null === $value) { + $value = $this->language() . ($var ?? ($this->modified() . md5('flex-' . $this->getFlexType() . '-' . $this->getKey()))); + + $this->setProperty($property, $value); + if ($this->doHasProperty($property)) { + $value = $this->getProperty($property); + } + } + + return $value; + } + + /** + * @inheritdoc + */ + public function modified($var = null): int + { + $property = 'modified'; + $value = null === $var ? $this->getProperty($property) : null; + if (null === $value) { + $value = (int)($var ?: $this->getTimestamp()); + + $this->setProperty($property, $value); + if ($this->doHasProperty($property)) { + $value = $this->getProperty($property); + } + } + + return $value; + } + + /** + * @inheritdoc + */ + public function lastModified($var = null): bool + { + return $this->loadHeaderProperty( + 'last_modified', + $var, + static function ($value) { + return (bool)($value ?? Grav::instance()['config']->get('system.pages.last_modified')); + } + ); + } + + /** + * @inheritdoc + */ + public function date($var = null): int + { + return $this->loadHeaderProperty( + 'date', + $var, + function ($value) { + $value = $value ? Utils::date2timestamp($value, $this->getProperty('dateformat')) : false; + + return $value ?: $this->modified(); + } + ); + } + + /** + * @inheritdoc + */ + public function dateformat($var = null): ?string + { + return $this->loadHeaderProperty( + 'dateformat', + $var, + static function ($value) { + return $value; + } + ); + } + + /** + * @inheritdoc + */ + public function taxonomy($var = null): array + { + return $this->loadHeaderProperty( + 'taxonomy', + $var, + static function ($value) { + if (is_array($value)) { + // make sure first level are arrays + array_walk($value, static function (&$val) { + $val = (array) $val; + }); + // make sure all values are strings + array_walk_recursive($value, static function (&$val) { + $val = (string) $val; + }); + } + + return $value ?? []; + } + ); + } + + /** + * @inheritdoc + */ + public function shouldProcess($process): bool + { + $test = $this->process(); + + return !empty($test[$process]); + } + + /** + * @inheritdoc + */ + public function isPage(): bool + { + return !in_array($this->template(), ['', 'folder'], true); + } + + /** + * @inheritdoc + */ + public function isDir(): bool + { + return !$this->isPage(); + } + + /** + * @return bool + */ + public function isModule(): bool + { + return $this->modularTwig(); + } + + /** + * @param Header|stdClass|array|null $value + * @return Header + */ + protected function offsetLoad_header($value) + { + if ($value instanceof Header) { + return $value; + } + + if (null === $value) { + $value = []; + } elseif ($value instanceof stdClass) { + $value = (array)$value; + } + + return new Header($value); + } + + /** + * @param Header|stdClass|array|null $value + * @return Header + */ + protected function offsetPrepare_header($value) + { + return $this->offsetLoad_header($value); + } + + /** + * @param Header|null $value + * @return array + */ + protected function offsetSerialize_header(?Header $value) + { + return $value ? $value->toArray() : []; + } + + /** + * @param string $name + * @param mixed|null $default + * @return mixed + */ + protected function pageContentValue($name, $default = null) + { + switch ($name) { + case 'frontmatter': + $frontmatter = $this->getArrayProperty('frontmatter'); + if ($frontmatter === null) { + $header = $this->prepareStorage()['header'] ?? null; + if ($header) { + $formatter = new YamlFormatter(); + $frontmatter = $formatter->encode($header); + } else { + $frontmatter = ''; + } + } + return $frontmatter; + case 'content': + return $this->getProperty('markdown'); + case 'order': + return (string)$this->order(); + case 'menu': + return $this->menu(); + case 'ordering': + return $this->order() !== false ? '1' : '0'; + case 'folder': + $folder = $this->folder(); + + return null !== $folder ? preg_replace(static::PAGE_ORDER_PREFIX_REGEX, '', $folder) : ''; + case 'slug': + return $this->slug(); + case 'published': + return $this->published(); + case 'visible': + return $this->visible(); + case 'media': + return $this->media()->all(); + case 'media.file': + return $this->media()->files(); + case 'media.video': + return $this->media()->videos(); + case 'media.image': + return $this->media()->images(); + case 'media.audio': + return $this->media()->audios(); + } + + return $default; + } + + /** + * @param int|null $size + * @param bool $textOnly + * @return string + */ + protected function processSummary($size = null, $textOnly = false): string + { + $config = (array)Grav::instance()['config']->get('site.summary'); + $config_page = (array)$this->getNestedProperty('header.summary'); + if ($config_page) { + $config = array_merge($config, $config_page); + } + + // Summary is not enabled, return the whole content. + if (empty($config['enabled'])) { + return $this->content(); + } + + $content = $this->_summary ?? $this->content(); + if ($textOnly) { + $content = strip_tags($content); + } + $content_size = mb_strwidth($content, 'utf-8'); + $summary_size = $this->_summary !== null ? $content_size : $this->getProperty('summary_size'); + + // Return calculated summary based on summary divider's position. + $format = $config['format'] ?? ''; + + // Return entire page content on wrong/unknown format. + if ($format !== 'long' && $format !== 'short') { + return $content; + } + + if ($format === 'short' && null !== $summary_size) { + // Slice the string on breakpoint. + if ($content_size > $summary_size) { + return mb_substr($content, 0, $summary_size); + } + + return $content; + } + + // If needed, get summary size from the config. + $size = $size ?? $config['size'] ?? null; + + // Return calculated summary based on defaults. + $size = is_numeric($size) ? (int)$size : -1; + if ($size < 0) { + $size = 300; + } + + // If the size is zero or smaller than the summary limit, return the entire page content. + if ($size === 0 || $content_size <= $size) { + return $content; + } + + // Only return string but not html, wrap whatever html tag you want when using. + if ($textOnly) { + return mb_strimwidth($content, 0, $size, '...', 'UTF-8'); + } + + $summary = Utils::truncateHTML($content, $size); + + return html_entity_decode($summary, ENT_COMPAT | ENT_HTML5, 'UTF-8'); + } + + /** + * Gets and Sets the content based on content portion of the .md file + * + * @param string $content + * @return string + * @throws Exception + */ + protected function processContent($content): string + { + $content = is_string($content) ? $content : ''; + $grav = Grav::instance(); + + /** @var Config $config */ + $config = $grav['config']; + + $process_markdown = $this->shouldProcess('markdown'); + $process_twig = $this->shouldProcess('twig') || $this->isModule(); + $cache_enable = $this->getNestedProperty('header.cache_enable') ?? $config->get('system.cache.enabled', true); + + $twig_first = $this->getNestedProperty('header.twig_first') ?? $config->get('system.pages.twig_first', false); + $never_cache_twig = $this->getNestedProperty('header.never_cache_twig') ?? $config->get('system.pages.never_cache_twig', false); + + if ($cache_enable) { + $cache = $this->getCache('render'); + $key = md5($this->getCacheKey() . '-content'); + $cached = $cache->get($key); + if ($cached && $cached['checksum'] === $this->getCacheChecksum()) { + $this->_content = $cached['content'] ?? ''; + $this->_content_meta = $cached['content_meta'] ?? null; + + if ($process_twig && $never_cache_twig) { + $this->_content = $this->processTwig($this->_content); + } + } + } + + if (null === $this->_content) { + $markdown_options = []; + if ($process_markdown) { + // Build markdown options. + $markdown_options = (array)$config->get('system.pages.markdown'); + $markdown_page_options = (array)$this->getNestedProperty('header.markdown'); + if ($markdown_page_options) { + $markdown_options = array_merge($markdown_options, $markdown_page_options); + } + + // pages.markdown_extra is deprecated, but still check it... + if (!isset($markdown_options['extra'])) { + $extra = $this->getNestedProperty('header.markdown_extra') ?? $config->get('system.pages.markdown_extra'); + if (null !== $extra) { + user_error('Configuration option \'system.pages.markdown_extra\' is deprecated since Grav 1.5, use \'system.pages.markdown.extra\' instead', E_USER_DEPRECATED); + + $markdown_options['extra'] = $extra; + } + } + } + $options = [ + 'markdown' => $markdown_options, + 'images' => $config->get('system.images', []) + ]; + + $this->_content = $content; + $grav->fireEvent('onPageContentRaw', new Event(['page' => $this])); + + if ($twig_first && !$never_cache_twig) { + if ($process_twig) { + $this->_content = $this->processTwig($this->_content); + } + + if ($process_markdown) { + $this->_content = $this->processMarkdown($this->_content, $options); + } + + // Content Processed but not cached yet + $grav->fireEvent('onPageContentProcessed', new Event(['page' => $this])); + } else { + if ($process_markdown) { + $options['keep_twig'] = $process_twig; + $this->_content = $this->processMarkdown($this->_content, $options); + } + + // Content Processed but not cached yet + $grav->fireEvent('onPageContentProcessed', new Event(['page' => $this])); + + if ($cache_enable && $never_cache_twig) { + $this->cachePageContent(); + } + + if ($process_twig) { + \assert(is_string($this->_content)); + $this->_content = $this->processTwig($this->_content); + } + } + + if ($cache_enable && !$never_cache_twig) { + $this->cachePageContent(); + } + } + + \assert(is_string($this->_content)); + + // Handle summary divider + $delimiter = $config->get('site.summary.delimiter', '==='); + $divider_pos = mb_strpos($this->_content, "

    {$delimiter}

    "); + if ($divider_pos !== false) { + $this->setProperty('summary_size', $divider_pos); + $this->_content = str_replace("

    {$delimiter}

    ", '', $this->_content); + } + + // Fire event when Page::content() is called + $grav->fireEvent('onPageContent', new Event(['page' => $this])); + + return $this->_content; + } + + /** + * Process the Twig page content. + * + * @param string $content + * @return string + */ + protected function processTwig($content): string + { + /** @var Twig $twig */ + $twig = Grav::instance()['twig']; + + /** @var PageInterface $this */ + return $twig->processPage($this, $content); + } + + /** + * Process the Markdown content. + * + * Uses Parsedown or Parsedown Extra depending on configuration. + * + * @param string $content + * @param array $options + * @return string + * @throws Exception + */ + protected function processMarkdown($content, array $options = []): string + { + /** @var PageInterface $self */ + $self = $this; + + $excerpts = new Excerpts($self, $options); + + // Initialize the preferred variant of markdown parser. + if (isset($options['extra'])) { + $parsedown = new ParsedownExtra($excerpts); + } else { + $parsedown = new Parsedown($excerpts); + } + + $keepTwig = (bool)($options['keep_twig'] ?? false); + if ($keepTwig) { + $token = [ + '/' . Utils::generateRandomString(3), + Utils::generateRandomString(3) . '/' + ]; + // Base64 encode any twig. + $content = preg_replace_callback( + ['/({#.*?#})/mu', '/({{.*?}})/mu', '/({%.*?%})/mu'], + static function ($matches) use ($token) { return $token[0] . base64_encode($matches[1]) . $token[1]; }, + $content + ); + } + + $content = $parsedown->text($content); + + if ($keepTwig) { + // Base64 decode the encoded twig. + $content = preg_replace_callback( + ['`' . $token[0] . '([A-Za-z0-9+/]+={0,2})' . $token[1] . '`mu'], + static function ($matches) { return base64_decode($matches[1]); }, + $content + ); + } + + return $content; + } + + abstract protected function loadHeaderProperty(string $property, $var, callable $filter); +} diff --git a/system/src/Grav/Framework/Flex/Pages/Traits/PageLegacyTrait.php b/system/src/Grav/Framework/Flex/Pages/Traits/PageLegacyTrait.php new file mode 100644 index 0000000..77c218f --- /dev/null +++ b/system/src/Grav/Framework/Flex/Pages/Traits/PageLegacyTrait.php @@ -0,0 +1,1124 @@ +getFlexDirectory()->getStorage(); + if (method_exists($storage, 'readRaw')) { + return $storage->readRaw($this->getStorageKey()); + } + + $array = $this->prepareStorage(); + $formatter = new MarkdownFormatter(); + + return $formatter->encode($array); + } + + /** + * Gets and Sets the page frontmatter + * + * @param string|null $var + * @return string + */ + public function frontmatter($var = null): string + { + if (null !== $var) { + $formatter = new YamlFormatter(); + $this->setProperty('frontmatter', $var); + $this->setProperty('header', $formatter->decode($var)); + + return $var; + } + + $storage = $this->getFlexDirectory()->getStorage(); + if (method_exists($storage, 'readFrontmatter')) { + return $storage->readFrontmatter($this->getStorageKey()); + } + + $array = $this->prepareStorage(); + $formatter = new YamlFormatter(); + + return $formatter->encode($array['header'] ?? []); + } + + /** + * Modify a header value directly + * + * @param string $key + * @param string|array $value + * @return void + */ + public function modifyHeader($key, $value): void + { + $this->setNestedProperty("header.{$key}", $value); + } + + /** + * @return int + */ + public function httpResponseCode(): int + { + $code = (int)$this->getNestedProperty('header.http_response_code'); + + return $code ?: 200; + } + + /** + * @return array + */ + public function httpHeaders(): array + { + $headers = []; + + $format = $this->templateFormat(); + $cache_control = $this->cacheControl(); + $expires = $this->expires(); + + // Set Content-Type header. + $headers['Content-Type'] = Utils::getMimeByExtension($format, 'text/html'); + + // Calculate Expires Headers if set to > 0. + if ($expires > 0) { + $expires_date = gmdate('D, d M Y H:i:s', time() + $expires) . ' GMT'; + if (!$cache_control) { + $headers['Cache-Control'] = 'max-age=' . $expires; + } + $headers['Expires'] = $expires_date; + } + + // Set Cache-Control header. + if ($cache_control) { + $headers['Cache-Control'] = strtolower($cache_control); + } + + // Set Last-Modified header. + if ($this->lastModified()) { + $last_modified_date = gmdate('D, d M Y H:i:s', $this->modified()) . ' GMT'; + $headers['Last-Modified'] = $last_modified_date; + } + + // Calculate ETag based on the serialized page and modified time. + if ($this->eTag()) { + $headers['ETag'] = '1'; + } + + // Set Vary: Accept-Encoding header. + $grav = Grav::instance(); + if ($grav['config']->get('system.pages.vary_accept_encoding', false)) { + $headers['Vary'] = 'Accept-Encoding'; + } + + return $headers; + } + + /** + * Get the contentMeta array and initialize content first if it's not already + * + * @return array + */ + public function contentMeta(): array + { + // Content meta is generated during the content is being rendered, so make sure we have done it. + $this->content(); + + return $this->_content_meta ?? []; + } + + /** + * Add an entry to the page's contentMeta array + * + * @param string $name + * @param string $value + * @return void + */ + public function addContentMeta($name, $value): void + { + $this->_content_meta[$name] = $value; + } + + /** + * Return the whole contentMeta array as it currently stands + * + * @param string|null $name + * @return string|array|null + */ + public function getContentMeta($name = null) + { + if ($name) { + return $this->_content_meta[$name] ?? null; + } + + return $this->_content_meta ?? []; + } + + /** + * Sets the whole content meta array in one shot + * + * @param array $content_meta + * @return array + */ + public function setContentMeta($content_meta): array + { + return $this->_content_meta = $content_meta; + } + + /** + * Fires the onPageContentProcessed event, and caches the page content using a unique ID for the page + */ + public function cachePageContent(): void + { + $value = [ + 'checksum' => $this->getCacheChecksum(), + 'content' => $this->_content, + 'content_meta' => $this->_content_meta + ]; + + $cache = $this->getCache('render'); + $key = md5($this->getCacheKey() . '-content'); + + $cache->set($key, $value); + } + + /** + * Get file object to the page. + * + * @return MarkdownFile|null + */ + public function file(): ?MarkdownFile + { + // TODO: + throw new RuntimeException(__METHOD__ . '(): Not Implemented'); + } + + /** + * Prepare move page to new location. Moves also everything that's under the current page. + * + * You need to call $this->save() in order to perform the move. + * + * @param PageInterface $parent New parent page. + * @return $this + */ + public function move(PageInterface $parent) + { + if ($this->route() === $parent->route()) { + throw new RuntimeException('Failed: Cannot set page parent to self'); + } + $rawRoute = $this->rawRoute(); + if ($rawRoute && Utils::startsWith($parent->rawRoute(), $rawRoute)) { + throw new RuntimeException('Failed: Cannot set page parent to a child of current page'); + } + + $this->storeOriginal(); + + // TODO: + throw new RuntimeException(__METHOD__ . '(): Not Implemented'); + } + + /** + * Prepare a copy from the page. Copies also everything that's under the current page. + * + * Returns a new Page object for the copy. + * You need to call $this->save() in order to perform the move. + * + * @param PageInterface|null $parent New parent page. + * @return $this + */ + public function copy(PageInterface $parent = null) + { + $this->storeOriginal(); + + $filesystem = Filesystem::getInstance(false); + + $parentStorageKey = ltrim($filesystem->dirname("/{$this->getMasterKey()}"), '/'); + + /** @var FlexPageIndex> $index */ + $index = $this->getFlexDirectory()->getIndex(); + + if ($parent) { + if ($parent instanceof FlexPageObject) { + $k = $parent->getMasterKey(); + if ($k !== $parentStorageKey) { + $parentStorageKey = $k; + } + } else { + throw new RuntimeException('Cannot copy page, parent is of unknown type'); + } + } else { + $parent = $parentStorageKey + ? $this->getFlexDirectory()->getObject($parentStorageKey, 'storage_key') + : (method_exists($index, 'getRoot') ? $index->getRoot() : null); + } + + // Find non-existing key. + $parentKey = $parent ? $parent->getKey() : ''; + if ($this instanceof FlexPageObject) { + $key = trim($parentKey . '/' . $this->folder(), '/'); + $key = preg_replace(static::PAGE_ORDER_PREFIX_REGEX, '', $key); + \assert(is_string($key)); + } else { + $key = trim($parentKey . '/' . Utils::basename($this->getKey()), '/'); + } + + if ($index->containsKey($key)) { + $key = preg_replace('/\d+$/', '', $key); + $i = 1; + do { + $i++; + $test = "{$key}{$i}"; + } while ($index->containsKey($test)); + $key = $test; + } + $folder = Utils::basename($key); + + // Get the folder name. + $order = $this->getProperty('order'); + if ($order) { + $order++; + } + + $parts = []; + if ($parentStorageKey !== '') { + $parts[] = $parentStorageKey; + } + $parts[] = $order ? sprintf('%02d.%s', $order, $folder) : $folder; + + // Finally update the object. + $this->setKey($key); + $this->setStorageKey(implode('/', $parts)); + + $this->markAsCopy(); + + return $this; + } + + /** + * Get the blueprint name for this page. Use the blueprint form field if set + * + * @return string + */ + public function blueprintName(): string + { + if (!isset($_POST['blueprint'])) { + return $this->template(); + } + + $post_value = $_POST['blueprint']; + $sanitized_value = htmlspecialchars(strip_tags($post_value), ENT_QUOTES, 'UTF-8'); + + return $sanitized_value ?: $this->template(); + } + + /** + * Validate page header. + * + * @return void + * @throws Exception + */ + public function validate(): void + { + $blueprint = $this->getBlueprint(); + $blueprint->validate($this->toArray()); + } + + /** + * Filter page header from illegal contents. + * + * @return void + */ + public function filter(): void + { + $blueprints = $this->getBlueprint(); + $values = $blueprints->filter($this->toArray()); + if ($values && isset($values['header'])) { + $this->header($values['header']); + } + } + + /** + * Get unknown header variables. + * + * @return array + */ + public function extra(): array + { + $data = $this->prepareStorage(); + + return $this->getBlueprint()->extra((array)($data['header'] ?? []), 'header.'); + } + + /** + * Convert page to an array. + * + * @return array + */ + public function toArray(): array + { + return [ + 'header' => (array)$this->header(), + 'content' => (string)$this->getFormValue('content') + ]; + } + + /** + * Convert page to YAML encoded string. + * + * @return string + */ + public function toYaml(): string + { + return Yaml::dump($this->toArray(), 20); + } + + /** + * Convert page to JSON encoded string. + * + * @return string + */ + public function toJson(): string + { + $json = json_encode($this->toArray()); + if (!is_string($json)) { + throw new RuntimeException('Internal error'); + } + + return $json; + } + + /** + * Gets and sets the name field. If no name field is set, it will return 'default.md'. + * + * @param string|null $var The name of this page. + * @return string The name of this page. + */ + public function name($var = null): string + { + return $this->loadProperty( + 'name', + $var, + function ($value) { + $value = $value ?? $this->getMetaData()['template'] ?? 'default'; + if (!preg_match('/\.md$/', $value)) { + $language = $this->language(); + if ($language) { + // TODO: better language support + $value .= ".{$language}"; + } + $value .= '.md'; + } + $value = preg_replace('|^modular/|', '', $value); + + $this->unsetProperty('template'); + + return $value; + } + ); + } + + /** + * Returns child page type. + * + * @return string + */ + public function childType(): string + { + return (string)$this->getNestedProperty('header.child_type'); + } + + /** + * Gets and sets the template field. This is used to find the correct Twig template file to render. + * If no field is set, it will return the name without the .md extension + * + * @param string|null $var the template name + * @return string the template name + */ + public function template($var = null): string + { + return $this->loadHeaderProperty( + 'template', + $var, + function ($value) { + return trim($value ?? (($this->isModule() ? 'modular/' : '') . str_replace($this->extension(), '', $this->name()))); + } + ); + } + + /** + * Allows a page to override the output render format, usually the extension provided in the URL. + * (e.g. `html`, `json`, `xml`, etc). + * + * @param string|null $var + * @return string + */ + public function templateFormat($var = null): string + { + return $this->loadHeaderProperty( + 'template_format', + $var, + function ($value) { + return ltrim($value ?? $this->getNestedProperty('header.append_url_extension') ?: Utils::getPageFormat(), '.'); + } + ); + } + + /** + * Gets and sets the extension field. + * + * @param string|null $var + * @return string + */ + public function extension($var = null): string + { + if (null !== $var) { + $this->setProperty('format', $var); + } + + $language = $this->language(); + if ($language) { + $language = '.' . $language; + } + $format = '.' . ($this->getProperty('format') ?? Utils::pathinfo($this->name(), PATHINFO_EXTENSION)); + + return $language . $format; + } + + /** + * Gets and sets the expires field. If not set will return the default + * + * @param int|null $var The new expires value. + * @return int The expires value + */ + public function expires($var = null): int + { + return $this->loadHeaderProperty( + 'expires', + $var, + static function ($value) { + return (int)($value ?? Grav::instance()['config']->get('system.pages.expires')); + } + ); + } + + /** + * Gets and sets the cache-control property. If not set it will return the default value (null) + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control for more details on valid options + * + * @param string|null $var + * @return string|null + */ + public function cacheControl($var = null): ?string + { + return $this->loadHeaderProperty( + 'cache_control', + $var, + static function ($value) { + return ((string)($value ?? Grav::instance()['config']->get('system.pages.cache_control'))) ?: null; + } + ); + } + + /** + * @param bool|null $var + * @return bool|null + */ + public function ssl($var = null): ?bool + { + return $this->loadHeaderProperty( + 'ssl', + $var, + static function ($value) { + return $value ? (bool)$value : null; + } + ); + } + + /** + * Returns the state of the debugger override setting for this page + * + * @return bool + */ + public function debugger(): bool + { + return (bool)$this->getNestedProperty('header.debugger', true); + } + + /** + * Function to merge page metadata tags and build an array of Metadata objects + * that can then be rendered in the page. + * + * @param array|null $var an Array of metadata values to set + * @return array an Array of metadata values for the page + */ + public function metadata($var = null): array + { + if ($var !== null) { + $this->_metadata = (array)$var; + } + + // if not metadata yet, process it. + if (null === $this->_metadata) { + $this->_metadata = []; + + $config = Grav::instance()['config']; + + // Set the Generator tag + $defaultMetadata = ['generator' => 'GravCMS']; + $siteMetadata = $config->get('site.metadata', []); + $headerMetadata = $this->getNestedProperty('header.metadata', []); + + // Get initial metadata for the page + $metadata = array_merge($defaultMetadata, $siteMetadata, $headerMetadata); + + $header_tag_http_equivs = ['content-type', 'default-style', 'refresh', 'x-ua-compatible', 'content-security-policy']; + $escape = !$config->get('system.strict_mode.twig_compat', false) || $config->get('system.twig.autoescape', true); + + // Build an array of meta objects.. + foreach ($metadata as $key => $value) { + // Lowercase the key + $key = strtolower($key); + + // If this is a property type metadata: "og", "twitter", "facebook" etc + // Backward compatibility for nested arrays in metas + if (is_array($value)) { + foreach ($value as $property => $prop_value) { + $prop_key = $key . ':' . $property; + $this->_metadata[$prop_key] = [ + 'name' => $prop_key, + 'property' => $prop_key, + 'content' => $escape ? htmlspecialchars($prop_value, ENT_QUOTES | ENT_HTML5, 'UTF-8') : $prop_value + ]; + } + } elseif ($value) { + // If it this is a standard meta data type + if (in_array($key, $header_tag_http_equivs, true)) { + $this->_metadata[$key] = [ + 'http_equiv' => $key, + 'content' => $escape ? htmlspecialchars($value, ENT_COMPAT, 'UTF-8') : $value + ]; + } elseif ($key === 'charset') { + $this->_metadata[$key] = ['charset' => $escape ? htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8') : $value]; + } else { + // if it's a social metadata with separator, render as property + $separator = strpos($key, ':'); + $hasSeparator = $separator && $separator < strlen($key) - 1; + $entry = [ + 'content' => $escape ? htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8') : $value + ]; + + if ($hasSeparator && !Utils::startsWith($key, 'twitter')) { + $entry['property'] = $key; + } else { + $entry['name'] = $key; + } + + $this->_metadata[$key] = $entry; + } + } + } + } + + return $this->_metadata; + } + + /** + * Reset the metadata and pull from header again + */ + public function resetMetadata(): void + { + $this->_metadata = null; + } + + /** + * Gets and sets the option to show the etag header for the page. + * + * @param bool|null $var show etag header + * @return bool show etag header + */ + public function eTag($var = null): bool + { + return $this->loadHeaderProperty( + 'etag', + $var, + static function ($value) { + return (bool)($value ?? Grav::instance()['config']->get('system.pages.etag')); + } + ); + } + + /** + * Gets and sets the path to the .md file for this Page object. + * + * @param string|null $var the file path + * @return string|null the file path + */ + public function filePath($var = null): ?string + { + if (null !== $var) { + // TODO: + throw new RuntimeException(__METHOD__ . '(string): Not Implemented'); + } + + $folder = $this->getStorageFolder(); + if (!$folder) { + return null; + } + + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $folder = $locator->isStream($folder) ? $locator->getResource($folder) : GRAV_ROOT . "/{$folder}"; + + return $folder . '/' . ($this->isPage() ? $this->name() : 'default.md'); + } + + /** + * Gets the relative path to the .md file + * + * @return string|null The relative file path + */ + public function filePathClean(): ?string + { + $folder = $this->getStorageFolder(); + if (!$folder) { + return null; + } + + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $folder = $locator->isStream($folder) ? $locator->getResource($folder, false) : $folder; + + return $folder . '/' . ($this->isPage() ? $this->name() : 'default.md'); + } + + /** + * Gets and sets the order by which any sub-pages should be sorted. + * + * @param string|null $var the order, either "asc" or "desc" + * @return string the order, either "asc" or "desc" + */ + public function orderDir($var = null): string + { + return $this->loadHeaderProperty( + 'order_dir', + $var, + static function ($value) { + return strtolower(trim($value) ?: Grav::instance()['config']->get('system.pages.order.dir')) === 'desc' ? 'desc' : 'asc'; + } + ); + } + + /** + * Gets and sets the order by which the sub-pages should be sorted. + * + * default - is the order based on the file system, ie 01.Home before 02.Advark + * title - is the order based on the title set in the pages + * date - is the order based on the date set in the pages + * folder - is the order based on the name of the folder with any numerics omitted + * + * @param string|null $var supported options include "default", "title", "date", and "folder" + * @return string supported options include "default", "title", "date", and "folder" + */ + public function orderBy($var = null): string + { + return $this->loadHeaderProperty( + 'order_by', + $var, + static function ($value) { + return trim($value) ?: Grav::instance()['config']->get('system.pages.order.by'); + } + ); + } + + /** + * Gets the manual order set in the header. + * + * @param string|null $var supported options include "default", "title", "date", and "folder" + * @return array + */ + public function orderManual($var = null): array + { + return $this->loadHeaderProperty( + 'order_manual', + $var, + static function ($value) { + return (array)$value; + } + ); + } + + /** + * Gets and sets the maxCount field which describes how many sub-pages should be displayed if the + * sub_pages header property is set for this page object. + * + * @param int|null $var the maximum number of sub-pages + * @return int the maximum number of sub-pages + */ + public function maxCount($var = null): int + { + return $this->loadHeaderProperty( + 'max_count', + $var, + static function ($value) { + return (int)($value ?? Grav::instance()['config']->get('system.pages.list.count')); + } + ); + } + + /** + * Gets and sets the modular var that helps identify this page is a modular child + * + * @param bool|null $var true if modular_twig + * @return bool true if modular_twig + * @deprecated 1.7 Use ->isModule() or ->modularTwig() method instead. + */ + public function modular($var = null): bool + { + user_error(__METHOD__ . '() is deprecated since Grav 1.7, use ->isModule() or ->modularTwig() method instead', E_USER_DEPRECATED); + + return $this->modularTwig($var); + } + + /** + * Gets and sets the modular_twig var that helps identify this page as a modular child page that will need + * twig processing handled differently from a regular page. + * + * @param bool|null $var true if modular_twig + * @return bool true if modular_twig + */ + public function modularTwig($var = null): bool + { + if ($var !== null) { + $this->setProperty('modular_twig', (bool)$var); + if ($var) { + $this->visible(false); + } + } + + return (bool)($this->getProperty('modular_twig') ?? strpos($this->slug(), '_') === 0); + } + + /** + * Returns children of this page. + * + * @return PageCollectionInterface|FlexIndexInterface + */ + public function children() + { + $meta = $this->getMetaData(); + $keys = array_keys($meta['children'] ?? []); + $prefix = $this->getMasterKey(); + if ($prefix) { + foreach ($keys as &$key) { + $key = $prefix . '/' . $key; + } + unset($key); + } + + return $this->getFlexDirectory()->getIndex($keys, 'storage_key'); + } + + /** + * Check to see if this item is the first in an array of sub-pages. + * + * @return bool True if item is first. + */ + public function isFirst(): bool + { + $parent = $this->parent(); + $children = $parent ? $parent->children() : null; + if ($children instanceof FlexCollectionInterface) { + $children = $children->withKeyField(); + } + + return $children instanceof PageCollectionInterface ? $children->isFirst($this->getKey()) : true; + } + + /** + * Check to see if this item is the last in an array of sub-pages. + * + * @return bool True if item is last + */ + public function isLast(): bool + { + $parent = $this->parent(); + $children = $parent ? $parent->children() : null; + if ($children instanceof FlexCollectionInterface) { + $children = $children->withKeyField(); + } + + return $children instanceof PageCollectionInterface ? $children->isLast($this->getKey()) : true; + } + + /** + * Gets the previous sibling based on current position. + * + * @return PageInterface|false the previous Page item + */ + public function prevSibling() + { + return $this->adjacentSibling(-1); + } + + /** + * Gets the next sibling based on current position. + * + * @return PageInterface|false the next Page item + */ + public function nextSibling() + { + return $this->adjacentSibling(1); + } + + /** + * Returns the adjacent sibling based on a direction. + * + * @param int $direction either -1 or +1 + * @return PageInterface|false the sibling page + */ + public function adjacentSibling($direction = 1) + { + $parent = $this->parent(); + $children = $parent ? $parent->children() : null; + if ($children instanceof FlexCollectionInterface) { + $children = $children->withKeyField(); + } + + if ($children instanceof PageCollectionInterface) { + $child = $children->adjacentSibling($this->getKey(), $direction); + if ($child instanceof PageInterface) { + return $child; + } + } + + return false; + } + + /** + * Helper method to return an ancestor page. + * + * @param string|null $lookup Name of the parent folder + * @return PageInterface|null page you were looking for if it exists + */ + public function ancestor($lookup = null) + { + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + return $pages->ancestor($this->getProperty('parent_route'), $lookup); + } + + /** + * Helper method to return an ancestor page to inherit from. The current + * page object is returned. + * + * @param string $field Name of the parent folder + * @return PageInterface|null + */ + public function inherited($field) + { + [$inherited, $currentParams] = $this->getInheritedParams($field); + + $this->modifyHeader($field, $currentParams); + + return $inherited; + } + + /** + * Helper method to return an ancestor field only to inherit from. The + * first occurrence of an ancestor field will be returned if at all. + * + * @param string $field Name of the parent folder + * @return array + */ + public function inheritedField($field): array + { + [, $currentParams] = $this->getInheritedParams($field); + + return $currentParams; + } + + /** + * Method that contains shared logic for inherited() and inheritedField() + * + * @param string $field Name of the parent folder + * @return array + */ + protected function getInheritedParams($field): array + { + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + $inherited = $pages->inherited($this->getProperty('parent_route'), $field); + $inheritedParams = $inherited ? (array)$inherited->value('header.' . $field) : []; + $currentParams = (array)$this->getFormValue('header.' . $field); + if ($inheritedParams && is_array($inheritedParams)) { + $currentParams = array_replace_recursive($inheritedParams, $currentParams); + } + + return [$inherited, $currentParams]; + } + + /** + * Helper method to return a page. + * + * @param string $url the url of the page + * @param bool $all + * @return PageInterface|null page you were looking for if it exists + */ + public function find($url, $all = false) + { + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + return $pages->find($url, $all); + } + + /** + * Get a collection of pages in the current context. + * + * @param string|array $params + * @param bool $pagination + * @return PageCollectionInterface|Collection + * @throws InvalidArgumentException + */ + public function collection($params = 'content', $pagination = true) + { + if (is_string($params)) { + // Look into a page header field. + $params = (array)$this->getFormValue('header.' . $params); + } elseif (!is_array($params)) { + throw new InvalidArgumentException('Argument should be either header variable name or array of parameters'); + } + + if (!$pagination) { + $params['pagination'] = false; + } + $context = [ + 'pagination' => $pagination, + 'self' => $this + ]; + + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + return $pages->getCollection($params, $context); + } + + /** + * @param string|array $value + * @param bool $only_published + * @return PageCollectionInterface|Collection + */ + public function evaluate($value, $only_published = true) + { + $params = [ + 'items' => $value, + 'published' => $only_published + ]; + $context = [ + 'event' => false, + 'pagination' => false, + 'url_taxonomy_filters' => false, + 'self' => $this + ]; + + /** @var Pages $pages */ + $pages = Grav::instance()['pages']; + + return $pages->getCollection($params, $context); + } + + /** + * Returns whether or not the current folder exists + * + * @return bool + */ + public function folderExists(): bool + { + return $this->exists() || is_dir($this->getStorageFolder() ?? ''); + } + + /** + * Gets the action. + * + * @return string|null The Action string. + */ + public function getAction(): ?string + { + $meta = $this->getMetaData(); + if (!empty($meta['copy'])) { + return 'copy'; + } + if (isset($meta['storage_key']) && $this->getStorageKey() !== $meta['storage_key']) { + return 'move'; + } + + return null; + } +} diff --git a/system/src/Grav/Framework/Flex/Pages/Traits/PageRoutableTrait.php b/system/src/Grav/Framework/Flex/Pages/Traits/PageRoutableTrait.php new file mode 100644 index 0000000..918ad67 --- /dev/null +++ b/system/src/Grav/Framework/Flex/Pages/Traits/PageRoutableTrait.php @@ -0,0 +1,550 @@ +loadHeaderProperty( + 'url_extension', + null, + function ($value) { + if ($this->home()) { + return ''; + } + + return $value ?? Grav::instance()['config']->get('system.pages.append_url_extension', ''); + } + ); + } + + /** + * Gets and Sets whether or not this Page is routable, ie you can reach it via a URL. + * The page must be *routable* and *published* + * + * @param bool|null $var true if the page is routable + * @return bool true if the page is routable + */ + public function routable($var = null): bool + { + $value = $this->loadHeaderProperty( + 'routable', + $var, + static function ($value) { + return $value ?? true; + } + ); + + return $value && $this->published() && !$this->isModule() && !$this->root() && $this->getLanguages(true); + } + + /** + * Gets the URL for a page - alias of url(). + * + * @param bool $include_host + * @return string the permalink + */ + public function link($include_host = false): string + { + return $this->url($include_host); + } + + /** + * Gets the URL with host information, aka Permalink. + * @return string The permalink. + */ + public function permalink(): string + { + return $this->url(true, false, true, true); + } + + /** + * Returns the canonical URL for a page + * + * @param bool $include_lang + * @return string + */ + public function canonical($include_lang = true): string + { + return $this->url(true, true, $include_lang); + } + + /** + * Gets the url for the Page. + * + * @param bool $include_host Defaults false, but true would include http://yourhost.com + * @param bool $canonical true to return the canonical URL + * @param bool $include_base + * @param bool $raw_route + * @return string The url. + */ + public function url($include_host = false, $canonical = false, $include_base = true, $raw_route = false): string + { + // Override any URL when external_url is set + $external = $this->getNestedProperty('header.external_url'); + if ($external) { + return $external; + } + + $grav = Grav::instance(); + + /** @var Pages $pages */ + $pages = $grav['pages']; + + /** @var Config $config */ + $config = $grav['config']; + + // get base route (multi-site base and language) + $route = $include_base ? $pages->baseRoute() : ''; + + // add full route if configured to do so + if (!$include_host && $config->get('system.absolute_urls', false)) { + $include_host = true; + } + + if ($canonical) { + $route .= $this->routeCanonical(); + } elseif ($raw_route) { + $route .= $this->rawRoute(); + } else { + $route .= $this->route(); + } + + /** @var Uri $uri */ + $uri = $grav['uri']; + $url = $uri->rootUrl($include_host) . '/' . trim($route, '/') . $this->urlExtension(); + + return Uri::filterPath($url); + } + + /** + * Gets the route for the page based on the route headers if available, else from + * the parents route and the current Page's slug. + * + * @param string $var Set new default route. + * @return string|null The route for the Page. + */ + public function route($var = null): ?string + { + if (null !== $var) { + // TODO: not the best approach, but works... + $this->setNestedProperty('header.routes.default', $var); + } + + // Return default route if given. + $default = $this->getNestedProperty('header.routes.default'); + if (is_string($default)) { + return $default; + } + + return $this->routeInternal(); + } + + /** + * @return string|null + */ + protected function routeInternal(): ?string + { + $route = $this->_route; + if (null !== $route) { + return $route; + } + + if ($this->root()) { + return null; + } + + // Root and orphan nodes have no route. + $parent = $this->parent(); + if (!$parent) { + return null; + } + + if ($parent->home()) { + /** @var Config $config */ + $config = Grav::instance()['config']; + $hide = (bool)$config->get('system.home.hide_in_urls', false); + $route = '/' . ($hide ? '' : $parent->slug()); + } else { + $route = $parent->route(); + } + + if ($route !== '' && $route !== '/') { + $route .= '/'; + } + + if (!$this->home()) { + $route .= $this->slug(); + } + + $this->_route = $route; + + return $route; + } + + /** + * Helper method to clear the route out so it regenerates next time you use it + */ + public function unsetRouteSlug(): void + { + // TODO: + throw new RuntimeException(__METHOD__ . '(): Not Implemented'); + } + + /** + * Gets and Sets the page raw route + * + * @param string|null $var + * @return string|null + */ + public function rawRoute($var = null): ?string + { + if (null !== $var) { + // TODO: + throw new RuntimeException(__METHOD__ . '(string): Not Implemented'); + } + + if ($this->root()) { + return null; + } + + return '/' . $this->getKey(); + } + + /** + * Gets the route aliases for the page based on page headers. + * + * @param array|null $var list of route aliases + * @return array The route aliases for the Page. + */ + public function routeAliases($var = null): array + { + if (null !== $var) { + $this->setNestedProperty('header.routes.aliases', (array)$var); + } + + $aliases = (array)$this->getNestedProperty('header.routes.aliases'); + $default = $this->getNestedProperty('header.routes.default'); + if ($default) { + $aliases[] = $default; + } + + return $aliases; + } + + /** + * Gets the canonical route for this page if its set. If provided it will use + * that value, else if it's `true` it will use the default route. + * + * @param string|null $var + * @return string|null + */ + public function routeCanonical($var = null): ?string + { + if (null !== $var) { + $this->setNestedProperty('header.routes.canonical', (array)$var); + } + + $canonical = $this->getNestedProperty('header.routes.canonical'); + + return is_string($canonical) ? $canonical : $this->route(); + } + + /** + * Gets the redirect set in the header. + * + * @param string|null $var redirect url + * @return string|null + */ + public function redirect($var = null): ?string + { + return $this->loadHeaderProperty( + 'redirect', + $var, + static function ($value) { + return trim($value) ?: null; + } + ); + } + + /** + * Returns the clean path to the page file + * + * Needed in admin for Page Media. + */ + public function relativePagePath(): ?string + { + $folder = $this->getMediaFolder(); + if (!$folder) { + return null; + } + + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $path = $locator->isStream($folder) ? $locator->findResource($folder, false) : $folder; + + return is_string($path) ? $path : null; + } + + /** + * Gets and sets the path to the folder where the .md for this Page object resides. + * This is equivalent to the filePath but without the filename. + * + * @param string|null $var the path + * @return string|null the path + */ + public function path($var = null): ?string + { + if (null !== $var) { + // TODO: + throw new RuntimeException(__METHOD__ . '(string): Not Implemented'); + } + + $path = $this->_path; + if ($path) { + return $path; + } + + if ($this->root()) { + $folder = $this->getFlexDirectory()->getStorageFolder(); + } else { + $folder = $this->getStorageFolder(); + } + + if ($folder) { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $folder = $locator->isStream($folder) ? $locator->getResource($folder) : GRAV_ROOT . "/{$folder}"; + } + + return $this->_path = is_string($folder) ? $folder : null; + } + + /** + * Get/set the folder. + * + * @param string|null $var Optional path, including numeric prefix. + * @return string|null + */ + public function folder($var = null): ?string + { + return $this->loadProperty( + 'folder', + $var, + function ($value) { + if (null === $value) { + $value = $this->getMasterKey() ?: $this->getKey(); + } + + return Utils::basename($value) ?: null; + } + ); + } + + /** + * Get/set the folder. + * + * @param string|null $var Optional path, including numeric prefix. + * @return string|null + */ + public function parentStorageKey($var = null): ?string + { + return $this->loadProperty( + 'parent_key', + $var, + function ($value) { + if (null === $value) { + $filesystem = Filesystem::getInstance(false); + $value = $this->getMasterKey() ?: $this->getKey(); + $value = ltrim($filesystem->dirname("/{$value}"), '/') ?: ''; + } + + return $value; + } + ); + } + + /** + * Gets and Sets the parent object for this page + * + * @param PageInterface|null $var the parent page object + * @return PageInterface|null the parent page object if it exists. + */ + public function parent(PageInterface $var = null) + { + if (null !== $var) { + // TODO: + throw new RuntimeException(__METHOD__ . '(PageInterface): Not Implemented'); + } + + if ($this->_parentCache || $this->root()) { + return $this->_parentCache; + } + + // Use filesystem as \dirname() does not work in Windows because of '/foo' becomes '\'. + $filesystem = Filesystem::getInstance(false); + $directory = $this->getFlexDirectory(); + $parentKey = ltrim($filesystem->dirname("/{$this->getKey()}"), '/'); + if ('' !== $parentKey) { + $parent = $directory->getObject($parentKey); + $language = $this->getLanguage(); + if ($language && $parent && method_exists($parent, 'getTranslation')) { + $parent = $parent->getTranslation($language) ?? $parent; + } + + $this->_parentCache = $parent; + } else { + $index = $directory->getIndex(); + + $this->_parentCache = \is_callable([$index, 'getRoot']) ? $index->getRoot() : null; + } + + return $this->_parentCache; + } + + /** + * Gets the top parent object for this page. Can return page itself. + * + * @return PageInterface The top parent page object. + */ + public function topParent() + { + $topParent = $this; + while ($topParent) { + $parent = $topParent->parent(); + if (!$parent || !$parent->parent()) { + break; + } + $topParent = $parent; + } + + return $topParent; + } + + /** + * Returns the item in the current position. + * + * @return int|null the index of the current page. + */ + public function currentPosition(): ?int + { + $parent = $this->parent(); + $collection = $parent ? $parent->collection('content', false) : null; + if ($collection instanceof PageCollectionInterface && $path = $this->path()) { + return $collection->currentPosition($path); + } + + return 1; + } + + /** + * Returns whether or not this page is the currently active page requested via the URL. + * + * @return bool True if it is active + */ + public function active(): bool + { + $grav = Grav::instance(); + $uri_path = rtrim(urldecode($grav['uri']->path()), '/') ?: '/'; + $routes = $grav['pages']->routes(); + + return isset($routes[$uri_path]) && $routes[$uri_path] === $this->path(); + } + + /** + * Returns whether or not this URI's URL contains the URL of the active page. + * Or in other words, is this page's URL in the current URL + * + * @return bool True if active child exists + */ + public function activeChild(): bool + { + $grav = Grav::instance(); + /** @var Uri $uri */ + $uri = $grav['uri']; + /** @var Pages $pages */ + $pages = $grav['pages']; + $uri_path = rtrim(urldecode($uri->path()), '/'); + $routes = $pages->routes(); + + if (isset($routes[$uri_path])) { + $page = $pages->find($uri->route()); + /** @var PageInterface|null $child_page */ + $child_page = $page ? $page->parent() : null; + while ($child_page && !$child_page->root()) { + if ($this->path() === $child_page->path()) { + return true; + } + $child_page = $child_page->parent(); + } + } + + return false; + } + + /** + * Returns whether or not this page is the currently configured home page. + * + * @return bool True if it is the homepage + */ + public function home(): bool + { + $home = Grav::instance()['config']->get('system.home.alias'); + + return '/' . $this->getKey() === $home; + } + + /** + * Returns whether or not this page is the root node of the pages tree. + * + * @param bool|null $var + * @return bool True if it is the root + */ + public function root($var = null): bool + { + if (null !== $var) { + $this->root = (bool)$var; + } + + return $this->root === true || $this->getKey() === '/'; + } +} diff --git a/system/src/Grav/Framework/Flex/Pages/Traits/PageTranslateTrait.php b/system/src/Grav/Framework/Flex/Pages/Traits/PageTranslateTrait.php new file mode 100644 index 0000000..2bdfa87 --- /dev/null +++ b/system/src/Grav/Framework/Flex/Pages/Traits/PageTranslateTrait.php @@ -0,0 +1,291 @@ +translatedLanguages(true); + } + + /** + * @param string|null $languageCode + * @param bool|null $fallback + * @return bool + */ + public function hasTranslation(string $languageCode = null, bool $fallback = null): bool + { + $code = $this->findTranslation($languageCode, $fallback); + + return null !== $code; + } + + /** + * @param string|null $languageCode + * @param bool|null $fallback + * @return FlexObjectInterface|PageInterface|null + */ + public function getTranslation(string $languageCode = null, bool $fallback = null) + { + if ($this->root()) { + return $this; + } + + $code = $this->findTranslation($languageCode, $fallback); + if (null === $code) { + $object = null; + } elseif ('' === $code) { + $object = $this->getLanguage() ? $this->getFlexDirectory()->getObject($this->getMasterKey(), 'storage_key') : $this; + } else { + $meta = $this->getMetaData(); + $meta['template'] = $this->getLanguageTemplates()[$code] ?? $meta['template']; + $key = $this->getStorageKey() . '|' . $meta['template'] . '.' . $code; + $meta['storage_key'] = $key; + $meta['lang'] = $code; + $object = $this->getFlexDirectory()->loadObjects([$key => $meta])[$key] ?? null; + } + + return $object; + } + + /** + * @param bool $includeDefault If set to true, return separate entries for '' and 'en' (default) language. + * @return array + */ + public function getAllLanguages(bool $includeDefault = false): array + { + $grav = Grav::instance(); + + /** @var Language $language */ + $language = $grav['language']; + $languages = $language->getLanguages(); + if (!$languages) { + return []; + } + + $translated = $this->getLanguageTemplates(); + + if ($includeDefault) { + $languages[] = ''; + } elseif (isset($translated[''])) { + $default = $language->getDefault(); + if (is_bool($default)) { + $default = ''; + } + $translated[$default] = $translated['']; + unset($translated['']); + } + + $languages = array_fill_keys($languages, false); + $translated = array_fill_keys(array_keys($translated), true); + + return array_replace($languages, $translated); + } + + /** + * Returns all translated languages. + * + * @param bool $includeDefault If set to true, return separate entries for '' and 'en' (default) language. + * @return array + */ + public function getLanguages(bool $includeDefault = false): array + { + $languages = $this->getLanguageTemplates(); + + if (!$includeDefault && isset($languages[''])) { + $grav = Grav::instance(); + + /** @var Language $language */ + $language = $grav['language']; + $default = $language->getDefault(); + if (is_bool($default)) { + $default = ''; + } + $languages[$default] = $languages['']; + unset($languages['']); + } + + return array_keys($languages); + } + + /** + * @return string + */ + public function getLanguage(): string + { + return $this->language() ?? ''; + } + + /** + * @param string|null $languageCode + * @param bool|null $fallback + * @return string|null + */ + public function findTranslation(string $languageCode = null, bool $fallback = null): ?string + { + $translated = $this->getLanguageTemplates(); + + // If there's no translations (including default), we have an empty folder. + if (!$translated) { + return ''; + } + + // FIXME: only published is not implemented... + $languages = $this->getFallbackLanguages($languageCode, $fallback); + + $language = null; + foreach ($languages as $code) { + if (isset($translated[$code])) { + $language = $code; + break; + } + } + + return $language; + } + + /** + * Return an array with the routes of other translated languages + * + * @param bool $onlyPublished only return published translations + * @return array the page translated languages + */ + public function translatedLanguages($onlyPublished = false): array + { + // FIXME: only published is not implemented... + $translated = $this->getLanguageTemplates(); + if (!$translated) { + return $translated; + } + + $grav = Grav::instance(); + + /** @var Language $language */ + $language = $grav['language']; + $languages = $language->getLanguages(); + $languages[] = ''; + + $translated = array_intersect_key($translated, array_flip($languages)); + $list = array_fill_keys($languages, null); + foreach ($translated as $languageCode => $languageFile) { + $path = ($languageCode ? '/' : '') . $languageCode; + $list[$languageCode] = "{$path}/{$this->getKey()}"; + } + + return array_filter($list); + } + + /** + * Return an array listing untranslated languages available + * + * @param bool $includeUnpublished also list unpublished translations + * @return array the page untranslated languages + */ + public function untranslatedLanguages($includeUnpublished = false): array + { + $grav = Grav::instance(); + + /** @var Language $language */ + $language = $grav['language']; + + $languages = $language->getLanguages(); + $translated = array_keys($this->translatedLanguages(!$includeUnpublished)); + + return array_values(array_diff($languages, $translated)); + } + + /** + * Get page language + * + * @param string|null $var + * @return string|null + */ + public function language($var = null): ?string + { + return $this->loadHeaderProperty( + 'lang', + $var, + function ($value) { + $value = $value ?? $this->getMetaData()['lang'] ?? ''; + + return trim($value) ?: null; + } + ); + } + + /** + * @return array + */ + protected function getLanguageTemplates(): array + { + if (null === $this->_languages) { + $template = $this->getProperty('template'); + $meta = $this->getMetaData(); + $translations = $meta['markdown'] ?? []; + $list = []; + foreach ($translations as $code => $search) { + if (isset($search[$template])) { + // Use main template if possible. + $list[$code] = $template; + } elseif (!empty($search)) { + // Fall back to first matching template. + $list[$code] = key($search); + } + } + + $this->_languages = $list; + } + + return $this->_languages; + } + + /** + * @param string|null $languageCode + * @param bool|null $fallback + * @return array + */ + protected function getFallbackLanguages(string $languageCode = null, bool $fallback = null): array + { + $fallback = $fallback ?? true; + if (!$fallback && null !== $languageCode) { + return [$languageCode]; + } + + $grav = Grav::instance(); + + /** @var Language $language */ + $language = $grav['language']; + $languageCode = $languageCode ?? ($language->getLanguage() ?: ''); + if ($languageCode === '' && $fallback) { + return $language->getFallbackLanguages(null, true); + } + + return $fallback ? $language->getFallbackLanguages($languageCode, true) : [$languageCode]; + } +} diff --git a/system/src/Grav/Framework/Flex/Storage/AbstractFilesystemStorage.php b/system/src/Grav/Framework/Flex/Storage/AbstractFilesystemStorage.php new file mode 100644 index 0000000..d919f3a --- /dev/null +++ b/system/src/Grav/Framework/Flex/Storage/AbstractFilesystemStorage.php @@ -0,0 +1,232 @@ +hasKey((string)$key); + } + + return $list; + } + + /** + * {@inheritDoc} + * @see FlexStorageInterface::getKeyField() + */ + public function getKeyField(): string + { + return $this->keyField; + } + + /** + * @param array $keys + * @param bool $includeParams + * @return string + */ + public function buildStorageKey(array $keys, bool $includeParams = true): string + { + $key = $keys['key'] ?? ''; + $params = $includeParams ? $this->buildStorageKeyParams($keys) : ''; + + return $params ? "{$key}|{$params}" : $key; + } + + /** + * @param array $keys + * @return string + */ + public function buildStorageKeyParams(array $keys): string + { + return ''; + } + + /** + * @param array $row + * @return array + */ + public function extractKeysFromRow(array $row): array + { + return [ + 'key' => $this->normalizeKey($row[$this->keyField] ?? '') + ]; + } + + /** + * @param string $key + * @return array + */ + public function extractKeysFromStorageKey(string $key): array + { + return [ + 'key' => $key + ]; + } + + /** + * @param string|array $formatter + * @return void + */ + protected function initDataFormatter($formatter): void + { + // Initialize formatter. + if (!is_array($formatter)) { + $formatter = ['class' => $formatter]; + } + $formatterClassName = $formatter['class'] ?? JsonFormatter::class; + $formatterOptions = $formatter['options'] ?? []; + + if (!is_a($formatterClassName, FileFormatterInterface::class, true)) { + throw new \InvalidArgumentException('Bad Data Formatter'); + } + + $this->dataFormatter = new $formatterClassName($formatterOptions); + } + + /** + * @param string $filename + * @return string|null + */ + protected function detectDataFormatter(string $filename): ?string + { + if (preg_match('|(\.[a-z0-9]*)$|ui', $filename, $matches)) { + switch ($matches[1]) { + case '.json': + return JsonFormatter::class; + case '.yaml': + return YamlFormatter::class; + case '.md': + return MarkdownFormatter::class; + } + } + + return null; + } + + /** + * @param string $filename + * @return CompiledJsonFile|CompiledYamlFile|CompiledMarkdownFile + */ + protected function getFile(string $filename) + { + $filename = $this->resolvePath($filename); + + // TODO: start using the new file classes. + switch ($this->dataFormatter->getDefaultFileExtension()) { + case '.json': + $file = CompiledJsonFile::instance($filename); + break; + case '.yaml': + $file = CompiledYamlFile::instance($filename); + break; + case '.md': + $file = CompiledMarkdownFile::instance($filename); + break; + default: + throw new RuntimeException('Unknown extension type ' . $this->dataFormatter->getDefaultFileExtension()); + } + + return $file; + } + + /** + * @param string $path + * @return string + */ + protected function resolvePath(string $path): string + { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + + if (!$locator->isStream($path)) { + return GRAV_ROOT . "/{$path}"; + } + + return $locator->getResource($path); + } + + /** + * Generates a random, unique key for the row. + * + * @return string + */ + protected function generateKey(): string + { + return substr(hash('sha256', random_bytes($this->keyLen)), 0, $this->keyLen); + } + + /** + * @param string $key + * @return string + */ + public function normalizeKey(string $key): string + { + if ($this->caseSensitive === true) { + return $key; + } + + return mb_strtolower($key); + } + + /** + * Checks if a key is valid. + * + * @param string $key + * @return bool + */ + protected function validateKey(string $key): bool + { + return $key && (bool) preg_match('/^[^\\/?*:;{}\\\\\\n]+$/u', $key); + } +} diff --git a/system/src/Grav/Framework/Flex/Storage/FileStorage.php b/system/src/Grav/Framework/Flex/Storage/FileStorage.php new file mode 100644 index 0000000..2770128 --- /dev/null +++ b/system/src/Grav/Framework/Flex/Storage/FileStorage.php @@ -0,0 +1,160 @@ +dataPattern = '{FOLDER}/{KEY}{EXT}'; + + if (!isset($options['formatter']) && isset($options['pattern'])) { + $options['formatter'] = $this->detectDataFormatter($options['pattern']); + } + + parent::__construct($options); + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::getMediaPath() + */ + public function getMediaPath(string $key = null): ?string + { + $path = $this->getStoragePath(); + if (!$path) { + return null; + } + + return $key ? "{$path}/{$key}" : $path; + } + + /** + * @param string $src + * @param string $dst + * @return bool + */ + public function copyRow(string $src, string $dst): bool + { + if ($this->hasKey($dst)) { + throw new RuntimeException("Cannot copy object: key '{$dst}' is already taken"); + } + + if (!$this->hasKey($src)) { + return false; + } + + return true; + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::renameRow() + */ + public function renameRow(string $src, string $dst): bool + { + if (!$this->hasKey($src)) { + return false; + } + + // Remove old file. + $path = $this->getPathFromKey($src); + $file = $this->getFile($path); + $file->delete(); + $file->free(); + unset($file); + + return true; + } + + /** + * @param string $src + * @param string $dst + * @return bool + */ + protected function copyFolder(string $src, string $dst): bool + { + // Nothing to copy. + return true; + } + + /** + * @param string $src + * @param string $dst + * @return bool + */ + protected function moveFolder(string $src, string $dst): bool + { + // Nothing to move. + return true; + } + + /** + * @param string $key + * @return bool + */ + protected function canDeleteFolder(string $key): bool + { + return false; + } + + /** + * {@inheritdoc} + */ + protected function getKeyFromPath(string $path): string + { + return Utils::basename($path, $this->dataFormatter->getDefaultFileExtension()); + } + + /** + * {@inheritdoc} + */ + protected function buildIndex(): array + { + $this->clearCache(); + + $path = $this->getStoragePath(); + if (!$path || !file_exists($path)) { + return []; + } + + $flags = FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS; + $iterator = new FilesystemIterator($path, $flags); + $list = []; + /** @var SplFileInfo $info */ + foreach ($iterator as $filename => $info) { + if (!$info->isFile() || !($key = $this->getKeyFromPath($filename)) || strpos($info->getFilename(), '.') === 0) { + continue; + } + + $list[$key] = $this->getObjectMeta($key); + } + + ksort($list, SORT_NATURAL | SORT_FLAG_CASE); + + return $list; + } +} diff --git a/system/src/Grav/Framework/Flex/Storage/FolderStorage.php b/system/src/Grav/Framework/Flex/Storage/FolderStorage.php new file mode 100644 index 0000000..157449d --- /dev/null +++ b/system/src/Grav/Framework/Flex/Storage/FolderStorage.php @@ -0,0 +1,708 @@ + '%1$s', 'KEY' => '%2$s', 'KEY:2' => '%3$s', 'FILE' => '%4$s', 'EXT' => '%5$s']; + /** @var string Filename for the object. */ + protected $dataFile; + /** @var string File extension for the object. */ + protected $dataExt; + /** @var bool */ + protected $prefixed; + /** @var bool */ + protected $indexed; + /** @var array */ + protected $meta = []; + + /** + * {@inheritdoc} + */ + public function __construct(array $options) + { + if (!isset($options['folder'])) { + throw new InvalidArgumentException("Argument \$options is missing 'folder'"); + } + + $this->initDataFormatter($options['formatter'] ?? []); + $this->initOptions($options); + } + + /** + * @return bool + */ + public function isIndexed(): bool + { + return $this->indexed; + } + + /** + * @return void + */ + public function clearCache(): void + { + $this->meta = []; + } + + /** + * @param string[] $keys + * @param bool $reload + * @return array + */ + public function getMetaData(array $keys, bool $reload = false): array + { + $list = []; + foreach ($keys as $key) { + $list[$key] = $this->getObjectMeta((string)$key, $reload); + } + + return $list; + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::getExistingKeys() + */ + public function getExistingKeys(): array + { + return $this->buildIndex(); + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::hasKey() + */ + public function hasKey(string $key): bool + { + $meta = $this->getObjectMeta($key); + + return array_key_exists('exists', $meta) ? $meta['exists'] : !empty($meta['storage_timestamp']); + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::createRows() + */ + public function createRows(array $rows): array + { + $list = []; + foreach ($rows as $key => $row) { + $list[$key] = $this->saveRow('@@', $row); + } + + return $list; + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::readRows() + */ + public function readRows(array $rows, array &$fetched = null): array + { + $list = []; + foreach ($rows as $key => $row) { + if (null === $row || is_scalar($row)) { + // Only load rows which haven't been loaded before. + $key = (string)$key; + $list[$key] = $this->loadRow($key); + + if (null !== $fetched) { + $fetched[$key] = $list[$key]; + } + } else { + // Keep the row if it has been loaded. + $list[$key] = $row; + } + } + + return $list; + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::updateRows() + */ + public function updateRows(array $rows): array + { + $list = []; + foreach ($rows as $key => $row) { + $key = (string)$key; + $list[$key] = $this->hasKey($key) ? $this->saveRow($key, $row) : null; + } + + return $list; + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::deleteRows() + */ + public function deleteRows(array $rows): array + { + $list = []; + $baseMediaPath = $this->getMediaPath(); + foreach ($rows as $key => $row) { + $key = (string)$key; + if (!$this->hasKey($key)) { + $list[$key] = null; + } else { + $path = $this->getPathFromKey($key); + $file = $this->getFile($path); + $list[$key] = $this->deleteFile($file); + + if ($this->canDeleteFolder($key)) { + $storagePath = $this->getStoragePath($key); + $mediaPath = $this->getMediaPath($key); + + if ($storagePath) { + $this->deleteFolder($storagePath, true); + } + if ($mediaPath && $mediaPath !== $storagePath && $mediaPath !== $baseMediaPath) { + $this->deleteFolder($mediaPath, true); + } + } + } + } + + return $list; + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::replaceRows() + */ + public function replaceRows(array $rows): array + { + $list = []; + foreach ($rows as $key => $row) { + $key = (string)$key; + $list[$key] = $this->saveRow($key, $row); + } + + return $list; + } + + /** + * @param string $src + * @param string $dst + * @return bool + * @throws RuntimeException + */ + public function copyRow(string $src, string $dst): bool + { + if ($this->hasKey($dst)) { + throw new RuntimeException("Cannot copy object: key '{$dst}' is already taken"); + } + + if (!$this->hasKey($src)) { + return false; + } + + $srcPath = $this->getStoragePath($src); + $dstPath = $this->getStoragePath($dst); + if (!$srcPath || !$dstPath) { + return false; + } + + return $this->copyFolder($srcPath, $dstPath); + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::renameRow() + * @throws RuntimeException + */ + public function renameRow(string $src, string $dst): bool + { + if (!$this->hasKey($src)) { + return false; + } + + $srcPath = $this->getStoragePath($src); + $dstPath = $this->getStoragePath($dst); + if (!$srcPath || !$dstPath) { + throw new RuntimeException("Destination path '{$dst}' is empty"); + } + + if ($srcPath === $dstPath) { + return true; + } + + if ($this->hasKey($dst)) { + throw new RuntimeException("Cannot rename object '{$src}': key '{$dst}' is already taken $srcPath $dstPath"); + } + + return $this->moveFolder($srcPath, $dstPath); + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::getStoragePath() + */ + public function getStoragePath(string $key = null): ?string + { + if (null === $key || $key === '') { + $path = $this->dataFolder; + } else { + $parts = $this->parseKey($key, false); + $options = [ + $this->dataFolder, // {FOLDER} + $parts['key'], // {KEY} + $parts['key:2'], // {KEY:2} + '***', // {FILE} + '***' // {EXT} + ]; + + $path = rtrim(explode('***', sprintf($this->dataPattern, ...$options))[0], '/'); + } + + return $path; + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::getMediaPath() + */ + public function getMediaPath(string $key = null): ?string + { + return $this->getStoragePath($key); + } + + /** + * Get filesystem path from the key. + * + * @param string $key + * @return string + */ + public function getPathFromKey(string $key): string + { + $parts = $this->parseKey($key); + $options = [ + $this->dataFolder, // {FOLDER} + $parts['key'], // {KEY} + $parts['key:2'], // {KEY:2} + $parts['file'], // {FILE} + $this->dataExt // {EXT} + ]; + + return sprintf($this->dataPattern, ...$options); + } + + /** + * @param string $key + * @param bool $variations + * @return array + */ + public function parseKey(string $key, bool $variations = true): array + { + $keys = [ + 'key' => $key, + 'key:2' => mb_substr($key, 0, 2), + ]; + if ($variations) { + $keys['file'] = $this->dataFile; + } + + return $keys; + } + + /** + * Get key from the filesystem path. + * + * @param string $path + * @return string + */ + protected function getKeyFromPath(string $path): string + { + return Utils::basename($path); + } + + /** + * Prepares the row for saving and returns the storage key for the record. + * + * @param array $row + * @return void + */ + protected function prepareRow(array &$row): void + { + if (array_key_exists($this->keyField, $row)) { + $key = $row[$this->keyField]; + if ($key === $this->normalizeKey($key)) { + unset($row[$this->keyField]); + } + } + } + + /** + * @param string $key + * @return array + */ + protected function loadRow(string $key): ?array + { + $path = $this->getPathFromKey($key); + $file = $this->getFile($path); + try { + $data = (array)$file->content(); + if (isset($data[0])) { + throw new RuntimeException('Broken object file'); + } + + // Add key field to the object. + $keyField = $this->keyField; + if ($keyField !== 'storage_key' && !isset($data[$keyField])) { + $data[$keyField] = $key; + } + } catch (RuntimeException $e) { + $data = ['__ERROR' => $e->getMessage()]; + } finally { + $file->free(); + unset($file); + } + + $data['__META'] = $this->getObjectMeta($key); + + return $data; + } + + /** + * @param string $key + * @param array $row + * @return array + */ + protected function saveRow(string $key, array $row): array + { + try { + if (isset($row[$this->keyField])) { + $key = $row[$this->keyField]; + } + if (strpos($key, '@@') !== false) { + $key = $this->getNewKey(); + } + + $key = $this->normalizeKey($key); + + // Check if the row already exists and if the key has been changed. + $oldKey = $row['__META']['storage_key'] ?? null; + if (is_string($oldKey) && $oldKey !== $key) { + $isCopy = $row['__META']['copy'] ?? false; + if ($isCopy) { + $this->copyRow($oldKey, $key); + } else { + $this->renameRow($oldKey, $key); + } + } + + $this->prepareRow($row); + unset($row['__META'], $row['__ERROR']); + + $path = $this->getPathFromKey($key); + $file = $this->getFile($path); + + $file->save($row); + + } catch (RuntimeException $e) { + throw new RuntimeException(sprintf('Flex saveFile(%s): %s', $path ?? $key, $e->getMessage())); + } finally { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $locator->clearCache(); + + if (isset($file)) { + $file->free(); + unset($file); + } + } + + $row['__META'] = $this->getObjectMeta($key, true); + + return $row; + } + + /** + * @param File $file + * @return array|string + */ + protected function deleteFile(File $file) + { + $filename = $file->filename(); + try { + $data = $file->content(); + if ($file->exists()) { + $file->delete(); + } + } catch (RuntimeException $e) { + throw new RuntimeException(sprintf('Flex deleteFile(%s): %s', $filename, $e->getMessage())); + } finally { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $locator->clearCache(); + + $file->free(); + } + + return $data; + } + + /** + * @param string $src + * @param string $dst + * @return bool + */ + protected function copyFolder(string $src, string $dst): bool + { + try { + Folder::copy($this->resolvePath($src), $this->resolvePath($dst)); + } catch (RuntimeException $e) { + throw new RuntimeException(sprintf('Flex copyFolder(%s, %s): %s', $src, $dst, $e->getMessage())); + } finally { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $locator->clearCache(); + } + + return true; + } + + /** + * @param string $src + * @param string $dst + * @return bool + */ + protected function moveFolder(string $src, string $dst): bool + { + try { + Folder::move($this->resolvePath($src), $this->resolvePath($dst)); + } catch (RuntimeException $e) { + throw new RuntimeException(sprintf('Flex moveFolder(%s, %s): %s', $src, $dst, $e->getMessage())); + } finally { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $locator->clearCache(); + } + + return true; + } + + /** + * @param string $path + * @param bool $include_target + * @return bool + */ + protected function deleteFolder(string $path, bool $include_target = false): bool + { + try { + return Folder::delete($this->resolvePath($path), $include_target); + } catch (RuntimeException $e) { + throw new RuntimeException(sprintf('Flex deleteFolder(%s): %s', $path, $e->getMessage())); + } finally { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $locator->clearCache(); + } + } + + /** + * @param string $key + * @return bool + */ + protected function canDeleteFolder(string $key): bool + { + return true; + } + + /** + * Returns list of all stored keys in [key => timestamp] pairs. + * + * @return array + */ + protected function buildIndex(): array + { + $this->clearCache(); + + $path = $this->getStoragePath(); + if (!$path || !file_exists($path)) { + return []; + } + + if ($this->prefixed) { + $list = $this->buildPrefixedIndexFromFilesystem($path); + } else { + $list = $this->buildIndexFromFilesystem($path); + } + + ksort($list, SORT_NATURAL | SORT_FLAG_CASE); + + return $list; + } + + /** + * @param string $key + * @param bool $reload + * @return array + */ + protected function getObjectMeta(string $key, bool $reload = false): array + { + if (!$reload && isset($this->meta[$key])) { + return $this->meta[$key]; + } + + if ($key && strpos($key, '@@') === false) { + $filename = $this->getPathFromKey($key); + $modified = is_file($filename) ? filemtime($filename) : 0; + } else { + $modified = 0; + } + + $meta = [ + 'storage_key' => $key, + 'storage_timestamp' => $modified + ]; + + $this->meta[$key] = $meta; + + return $meta; + } + + /** + * @param string $path + * @return array + */ + protected function buildIndexFromFilesystem($path) + { + $flags = FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS; + + $iterator = new FilesystemIterator($path, $flags); + $list = []; + /** @var SplFileInfo $info */ + foreach ($iterator as $filename => $info) { + if (!$info->isDir() || strpos($info->getFilename(), '.') === 0) { + continue; + } + + $key = $this->getKeyFromPath($filename); + $meta = $this->getObjectMeta($key); + if ($meta['storage_timestamp']) { + $list[$key] = $meta; + } + } + + return $list; + } + + /** + * @param string $path + * @return array + */ + protected function buildPrefixedIndexFromFilesystem($path) + { + $flags = FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS; + + $iterator = new FilesystemIterator($path, $flags); + $list = [[]]; + /** @var SplFileInfo $info */ + foreach ($iterator as $filename => $info) { + if (!$info->isDir() || strpos($info->getFilename(), '.') === 0) { + continue; + } + + $list[] = $this->buildIndexFromFilesystem($filename); + } + + return array_merge(...$list); + } + + /** + * @return string + */ + protected function getNewKey(): string + { + // Make sure that the file doesn't exist. + do { + $key = $this->generateKey(); + } while (file_exists($this->getPathFromKey($key))); + + return $key; + } + + /** + * @param array $options + * @return void + */ + protected function initOptions(array $options): void + { + $extension = $this->dataFormatter->getDefaultFileExtension(); + + /** @var string $pattern */ + $pattern = !empty($options['pattern']) ? $options['pattern'] : $this->dataPattern; + + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + $folder = $options['folder']; + if ($locator->isStream($folder)) { + $folder = $locator->getResource($folder, false); + } + + $this->dataFolder = $folder; + $this->dataFile = $options['file'] ?? 'item'; + $this->dataExt = $extension; + if (mb_strpos($pattern, '{FILE}') === false && mb_strpos($pattern, '{EXT}') === false) { + if (isset($options['file'])) { + $pattern .= '/{FILE}{EXT}'; + } else { + $filesystem = Filesystem::getInstance(true); + $this->dataFile = Utils::basename($pattern, $extension); + $pattern = $filesystem->dirname($pattern) . '/{FILE}{EXT}'; + } + } + $this->prefixed = (bool)($options['prefixed'] ?? strpos($pattern, '/{KEY:2}/')); + $this->indexed = (bool)($options['indexed'] ?? false); + $this->keyField = $options['key'] ?? 'storage_key'; + $this->keyLen = (int)($options['key_len'] ?? 32); + $this->caseSensitive = (bool)($options['case_sensitive'] ?? true); + + $pattern = Utils::simpleTemplate($pattern, $this->variables); + if (!$pattern) { + throw new RuntimeException('Bad storage folder pattern'); + } + + $this->dataPattern = $pattern; + } +} diff --git a/system/src/Grav/Framework/Flex/Storage/SimpleStorage.php b/system/src/Grav/Framework/Flex/Storage/SimpleStorage.php new file mode 100644 index 0000000..5a92023 --- /dev/null +++ b/system/src/Grav/Framework/Flex/Storage/SimpleStorage.php @@ -0,0 +1,507 @@ +detectDataFormatter($options['folder']); + $this->initDataFormatter($formatter); + + $filesystem = Filesystem::getInstance(true); + + $extension = $this->dataFormatter->getDefaultFileExtension(); + $pattern = Utils::basename($options['folder']); + + $this->dataPattern = Utils::basename($pattern, $extension) . $extension; + $this->dataFolder = $filesystem->dirname($options['folder']); + $this->keyField = $options['key'] ?? 'storage_key'; + $this->keyLen = (int)($options['key_len'] ?? 32); + $this->prefix = $options['prefix'] ?? null; + + // Make sure that the data folder exists. + if (!file_exists($this->dataFolder)) { + try { + Folder::create($this->dataFolder); + } catch (RuntimeException $e) { + throw new RuntimeException(sprintf('Flex: %s', $e->getMessage())); + } + } + } + + /** + * @return void + */ + public function clearCache(): void + { + $this->data = null; + $this->modified = 0; + } + + /** + * @param string[] $keys + * @param bool $reload + * @return array + */ + public function getMetaData(array $keys, bool $reload = false): array + { + if (null === $this->data || $reload) { + $this->buildIndex(); + } + + $list = []; + foreach ($keys as $key) { + $list[$key] = $this->getObjectMeta((string)$key); + } + + return $list; + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::getExistingKeys() + */ + public function getExistingKeys(): array + { + return $this->buildIndex(); + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::hasKey() + */ + public function hasKey(string $key): bool + { + if (null === $this->data) { + $this->buildIndex(); + } + + return $key && strpos($key, '@@') === false && isset($this->data[$key]); + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::createRows() + */ + public function createRows(array $rows): array + { + if (null === $this->data) { + $this->buildIndex(); + } + + $list = []; + foreach ($rows as $key => $row) { + $list[$key] = $this->saveRow('@@', $rows); + } + + if ($list) { + $this->save(); + } + + return $list; + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::readRows() + */ + public function readRows(array $rows, array &$fetched = null): array + { + if (null === $this->data) { + $this->buildIndex(); + } + + $list = []; + foreach ($rows as $key => $row) { + if (null === $row || is_scalar($row)) { + // Only load rows which haven't been loaded before. + $key = (string)$key; + $list[$key] = $this->hasKey($key) ? $this->loadRow($key) : null; + if (null !== $fetched) { + $fetched[$key] = $list[$key]; + } + } else { + // Keep the row if it has been loaded. + $list[$key] = $row; + } + } + + return $list; + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::updateRows() + */ + public function updateRows(array $rows): array + { + if (null === $this->data) { + $this->buildIndex(); + } + + $save = false; + $list = []; + foreach ($rows as $key => $row) { + $key = (string)$key; + if ($this->hasKey($key)) { + $list[$key] = $this->saveRow($key, $row); + $save = true; + } else { + $list[$key] = null; + } + } + + if ($save) { + $this->save(); + } + + return $list; + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::deleteRows() + */ + public function deleteRows(array $rows): array + { + if (null === $this->data) { + $this->buildIndex(); + } + + $list = []; + foreach ($rows as $key => $row) { + $key = (string)$key; + if ($this->hasKey($key)) { + unset($this->data[$key]); + $list[$key] = $row; + } + } + + if ($list) { + $this->save(); + } + + return $list; + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::replaceRows() + */ + public function replaceRows(array $rows): array + { + if (null === $this->data) { + $this->buildIndex(); + } + + $list = []; + foreach ($rows as $key => $row) { + $list[$key] = $this->saveRow((string)$key, $row); + } + + if ($list) { + $this->save(); + } + + return $list; + } + + /** + * @param string $src + * @param string $dst + * @return bool + */ + public function copyRow(string $src, string $dst): bool + { + if ($this->hasKey($dst)) { + throw new RuntimeException("Cannot copy object: key '{$dst}' is already taken"); + } + + if (!$this->hasKey($src)) { + return false; + } + + $this->data[$dst] = $this->data[$src]; + + return true; + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::renameRow() + */ + public function renameRow(string $src, string $dst): bool + { + if (null === $this->data) { + $this->buildIndex(); + } + + if ($this->hasKey($dst)) { + throw new RuntimeException("Cannot rename object: key '{$dst}' is already taken"); + } + + if (!$this->hasKey($src)) { + return false; + } + + // Change single key in the array without changing the order or value. + $keys = array_keys($this->data); + $keys[array_search($src, $keys, true)] = $dst; + + $data = array_combine($keys, $this->data); + if (false === $data) { + throw new LogicException('Bad data'); + } + + $this->data = $data; + + return true; + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::getStoragePath() + */ + public function getStoragePath(string $key = null): ?string + { + return $this->dataFolder . '/' . $this->dataPattern; + } + + /** + * {@inheritdoc} + * @see FlexStorageInterface::getMediaPath() + */ + public function getMediaPath(string $key = null): ?string + { + return null; + } + + /** + * Prepares the row for saving and returns the storage key for the record. + * + * @param array $row + */ + protected function prepareRow(array &$row): void + { + unset($row[$this->keyField]); + } + + /** + * @param string $key + * @return array + */ + protected function loadRow(string $key): ?array + { + $data = $this->data[$key] ?? []; + if ($this->keyField !== 'storage_key') { + $data[$this->keyField] = $key; + } + $data['__META'] = $this->getObjectMeta($key); + + return $data; + } + + /** + * @param string $key + * @param array $row + * @return array + */ + protected function saveRow(string $key, array $row): array + { + try { + if (isset($row[$this->keyField])) { + $key = $row[$this->keyField]; + } + if (strpos($key, '@@') !== false) { + $key = $this->getNewKey(); + } + + // Check if the row already exists and if the key has been changed. + $oldKey = $row['__META']['storage_key'] ?? null; + if (is_string($oldKey) && $oldKey !== $key) { + $isCopy = $row['__META']['copy'] ?? false; + if ($isCopy) { + $this->copyRow($oldKey, $key); + } else { + $this->renameRow($oldKey, $key); + } + } + + $this->prepareRow($row); + unset($row['__META'], $row['__ERROR']); + + $this->data[$key] = $row; + } catch (RuntimeException $e) { + throw new RuntimeException(sprintf('Flex saveRow(%s): %s', $key, $e->getMessage())); + } + + $row['__META'] = $this->getObjectMeta($key, true); + + return $row; + } + + /** + * @param string $key + * @param bool $variations + * @return array + */ + public function parseKey(string $key, bool $variations = true): array + { + return [ + 'key' => $key, + ]; + } + + protected function save(): void + { + if (null === $this->data) { + $this->buildIndex(); + } + + try { + $path = $this->getStoragePath(); + if (!$path) { + throw new RuntimeException('Storage path is not defined'); + } + $file = $this->getFile($path); + if ($this->prefix) { + $data = new Data((array)$file->content()); + $content = $data->set($this->prefix, $this->data)->toArray(); + } else { + $content = $this->data; + } + $file->save($content); + $this->modified = (int)$file->modified(); // cast false to 0 + } catch (RuntimeException $e) { + throw new RuntimeException(sprintf('Flex save(): %s', $e->getMessage())); + } finally { + if (isset($file)) { + $file->free(); + unset($file); + } + } + } + + /** + * Get key from the filesystem path. + * + * @param string $path + * @return string + */ + protected function getKeyFromPath(string $path): string + { + return Utils::basename($path); + } + + /** + * Returns list of all stored keys in [key => timestamp] pairs. + * + * @return array + */ + protected function buildIndex(): array + { + $path = $this->getStoragePath(); + if (!$path) { + $this->data = []; + + return []; + } + + $file = $this->getFile($path); + $this->modified = (int)$file->modified(); // cast false to 0 + + $content = (array) $file->content(); + if ($this->prefix) { + $data = new Data($content); + $content = $data->get($this->prefix, []); + } + + $file->free(); + unset($file); + + $this->data = $content; + + $list = []; + foreach ($this->data as $key => $info) { + $list[$key] = $this->getObjectMeta((string)$key); + } + + return $list; + } + + /** + * @param string $key + * @param bool $reload + * @return array + */ + protected function getObjectMeta(string $key, bool $reload = false): array + { + $modified = isset($this->data[$key]) ? $this->modified : 0; + + return [ + 'storage_key' => $key, + 'key' => $key, + 'storage_timestamp' => $modified + ]; + } + + /** + * @return string + */ + protected function getNewKey(): string + { + if (null === $this->data) { + $this->buildIndex(); + } + + // Make sure that the key doesn't exist. + do { + $key = $this->generateKey(); + } while (isset($this->data[$key])); + + return $key; + } +} diff --git a/system/src/Grav/Framework/Flex/Traits/FlexAuthorizeTrait.php b/system/src/Grav/Framework/Flex/Traits/FlexAuthorizeTrait.php new file mode 100644 index 0000000..a821300 --- /dev/null +++ b/system/src/Grav/Framework/Flex/Traits/FlexAuthorizeTrait.php @@ -0,0 +1,126 @@ +getAuthorizeAction($action); + $scope = $scope ?? $this->getAuthorizeScope(); + + $isMe = null === $user; + if ($isMe) { + $user = $this->getActiveUser(); + } + + if (null === $user) { + return false; + } + + // Finally authorize against given action. + return $this->isAuthorizedOverride($user, $action, $scope, $isMe); + } + + /** + * Please override this method + * + * @param UserInterface $user + * @param string $action + * @param string $scope + * @param bool $isMe + * @return bool|null + */ + protected function isAuthorizedOverride(UserInterface $user, string $action, string $scope, bool $isMe): ?bool + { + return $this->isAuthorizedAction($user, $action, $scope, $isMe); + } + + /** + * Check if user is authorized for the action. + * + * @param UserInterface $user + * @param string $action + * @param string $scope + * @param bool $isMe + * @return bool|null + */ + protected function isAuthorizedAction(UserInterface $user, string $action, string $scope, bool $isMe): ?bool + { + // Check if the action has been denied in the flex type configuration. + $directory = $this instanceof FlexDirectory ? $this : $this->getFlexDirectory(); + $config = $directory->getConfig(); + $allowed = $config->get("{$scope}.actions.{$action}") ?? $config->get("actions.{$action}") ?? true; + if (false === $allowed) { + return false; + } + + // TODO: Not needed anymore with flex users, remove in 2.0. + $auth = $user instanceof FlexObjectInterface ? null : $user->authorize('admin.super'); + if (true === $auth) { + return true; + } + + // Finally authorize the action. + return $user->authorize($this->getAuthorizeRule($scope, $action), !$isMe ? 'test' : null); + } + + /** + * @param UserInterface $user + * @return bool|null + * @deprecated 1.7 Not needed for Flex Users. + */ + protected function isAuthorizedSuperAdmin(UserInterface $user): ?bool + { + // Action authorization includes super user authorization if using Flex Users. + if ($user instanceof FlexObjectInterface) { + return null; + } + + return $user->authorize('admin.super'); + } + + /** + * @param string $scope + * @param string $action + * @return string + */ + protected function getAuthorizeRule(string $scope, string $action): string + { + if ($this instanceof FlexDirectory) { + return $this->getAuthorizeRule($scope, $action); + } + + return $this->getFlexDirectory()->getAuthorizeRule($scope, $action); + } +} diff --git a/system/src/Grav/Framework/Flex/Traits/FlexMediaTrait.php b/system/src/Grav/Framework/Flex/Traits/FlexMediaTrait.php new file mode 100644 index 0000000..a4d9a7e --- /dev/null +++ b/system/src/Grav/Framework/Flex/Traits/FlexMediaTrait.php @@ -0,0 +1,576 @@ +exists() ? $this->getFlexDirectory()->getStorageFolder($this->getStorageKey()) : null; + } + + /** + * @return string|null + */ + public function getMediaFolder() + { + return $this->exists() ? $this->getFlexDirectory()->getMediaFolder($this->getStorageKey()) : null; + } + + /** + * @return MediaCollectionInterface + */ + public function getMedia() + { + $media = $this->media; + if (null === $media) { + $media = $this->getExistingMedia(); + + // Include uploaded media to the object media. + $this->addUpdatedMedia($media); + } + + return $media; + } + + /** + * @param string $field + * @return MediaCollectionInterface|null + */ + public function getMediaField(string $field): ?MediaCollectionInterface + { + // Field specific media. + $settings = $this->getFieldSettings($field); + if (!empty($settings['media_field'])) { + $var = 'destination'; + } elseif (!empty($settings['media_picker_field'])) { + $var = 'folder'; + } + + if (empty($var)) { + // Not a media field. + $media = null; + } elseif ($settings['self']) { + // Uses main media. + $media = $this->getMedia(); + } else { + // Uses custom media. + $media = new Media($settings[$var]); + $this->addUpdatedMedia($media); + } + + return $media; + } + + /** + * @param string $field + * @return array|null + */ + public function getFieldSettings(string $field): ?array + { + if ($field === '') { + return null; + } + + // Load settings for the field. + $schema = $this->getBlueprint()->schema(); + $settings = (array)$schema->getProperty($field); + if (!is_array($settings)) { + return null; + } + + $type = $settings['type'] ?? ''; + + // Media field. + if (!empty($settings['media_field']) || array_key_exists('destination', $settings) || in_array($type, ['avatar', 'file', 'pagemedia'], true)) { + $settings['media_field'] = true; + $var = 'destination'; + } + + // Media picker field. + if (!empty($settings['media_picker_field']) || in_array($type, ['filepicker', 'pagemediaselect'], true)) { + $settings['media_picker_field'] = true; + $var = 'folder'; + } + + // Set media folder for media fields. + if (isset($var)) { + $folder = $settings[$var] ?? ''; + if (in_array(rtrim($folder, '/'), ['', '@self', 'self@', '@self@'], true)) { + $settings[$var] = $this->getMediaFolder(); + $settings['self'] = true; + } else { + $settings[$var] = Utils::getPathFromToken($folder, $this); + $settings['self'] = false; + } + } + + return $settings; + } + + /** + * @param string $field + * @return array + * @internal + */ + protected function getMediaFieldSettings(string $field): array + { + $settings = $this->getFieldSettings($field) ?? []; + + return $settings + ['accept' => '*', 'limit' => 1000, 'self' => true]; + } + + /** + * @return array + */ + protected function getMediaFields(): array + { + // Load settings for the field. + $schema = $this->getBlueprint()->schema(); + + $list = []; + foreach ($schema->getState()['items'] as $field => $settings) { + if (isset($settings['type']) && (in_array($settings['type'], ['avatar', 'file', 'pagemedia']) || !empty($settings['destination']))) { + $list[] = $field; + } + } + + return $list; + } + + /** + * @param array|mixed $value + * @param array $settings + * @return array|mixed + */ + protected function parseFileProperty($value, array $settings = []) + { + if (!is_array($value)) { + return $value; + } + + $media = $this->getMedia(); + $originalMedia = is_callable([$this, 'getOriginalMedia']) ? $this->getOriginalMedia() : null; + + $list = []; + foreach ($value as $filename => $info) { + if (!is_array($info)) { + $list[$filename] = $info; + continue; + } + + if (is_int($filename)) { + $filename = $info['path'] ?? $info['name']; + } + + /** @var Medium|null $imageFile */ + $imageFile = $media[$filename]; + + /** @var Medium|null $originalFile */ + $originalFile = $originalMedia ? $originalMedia[$filename] : null; + + $url = $imageFile ? $imageFile->url() : null; + $originalUrl = $originalFile ? $originalFile->url() : null; + $list[$filename] = [ + 'name' => $info['name'] ?? null, + 'type' => $info['type'] ?? null, + 'size' => $info['size'] ?? null, + 'path' => $filename, + 'thumb_url' => $url, + 'image_url' => $originalUrl ?? $url + ]; + if ($originalFile) { + $list[$filename]['cropData'] = (object)($originalFile->metadata()['upload']['crop'] ?? []); + } + } + + return $list; + } + + /** + * @param UploadedFileInterface $uploadedFile + * @param string|null $filename + * @param string|null $field + * @return void + * @internal + */ + public function checkUploadedMediaFile(UploadedFileInterface $uploadedFile, string $filename = null, string $field = null) + { + $media = $this->getMedia(); + if (!$media instanceof MediaUploadInterface) { + throw new RuntimeException("Media for {$this->getFlexDirectory()->getFlexType()} doesn't support file uploads."); + } + + $media->checkUploadedFile($uploadedFile, $filename, $this->getMediaFieldSettings($field ?? '')); + } + + /** + * @param UploadedFileInterface $uploadedFile + * @param string|null $filename + * @param string|null $field + * @return void + * @internal + */ + public function uploadMediaFile(UploadedFileInterface $uploadedFile, string $filename = null, string $field = null): void + { + $settings = $this->getMediaFieldSettings($field ?? ''); + + $media = $field ? $this->getMediaField($field) : $this->getMedia(); + if (!$media instanceof MediaUploadInterface) { + throw new RuntimeException("Media for {$this->getFlexDirectory()->getFlexType()} doesn't support file uploads."); + } + + $filename = $media->checkUploadedFile($uploadedFile, $filename, $settings); + $media->copyUploadedFile($uploadedFile, $filename, $settings); + $this->clearMediaCache(); + } + + /** + * @param string $filename + * @return void + * @internal + */ + public function deleteMediaFile(string $filename): void + { + $media = $this->getMedia(); + if (!$media instanceof MediaUploadInterface) { + throw new RuntimeException("Media for {$this->getFlexDirectory()->getFlexType()} doesn't support file uploads."); + } + + $media->deleteFile($filename); + $this->clearMediaCache(); + } + + /** + * @return array + */ + #[\ReturnTypeWillChange] + public function __debugInfo() + { + return parent::__debugInfo() + [ + 'uploads:private' => $this->getUpdatedMedia() + ]; + } + + /** + * @param string|null $field + * @param string $filename + * @param MediaObjectInterface|null $image + * @return MediaObject|UploadedMediaObject + */ + protected function buildMediaObject(?string $field, string $filename, MediaObjectInterface $image = null) + { + if (!$image) { + $media = $field ? $this->getMediaField($field) : null; + if ($media) { + $image = $media[$filename]; + } + } + + return new MediaObject($field, $filename, $image, $this); + } + + /** + * @param string|null $field + * @return array + */ + protected function buildMediaList(?string $field): array + { + $names = $field ? (array)$this->getNestedProperty($field) : []; + $media = $field ? $this->getMediaField($field) : null; + if (null === $media) { + $media = $this->getMedia(); + } + + $list = []; + foreach ($names as $key => $val) { + $name = is_string($val) ? $val : $key; + $medium = $media[$name]; + if ($medium) { + if ($medium->uploaded_file) { + $upload = $medium->uploaded_file; + $id = $upload instanceof FormFlashFile ? $upload->getId() : "{$field}-{$name}"; + + $list[] = new UploadedMediaObject($id, $field, $name, $upload); + } else { + $list[] = $this->buildMediaObject($field, $name, $medium); + } + } + } + + return $list; + } + + /** + * @param array $files + * @return void + */ + protected function setUpdatedMedia(array $files): void + { + $media = $this->getMedia(); + if (!$media instanceof MediaUploadInterface) { + return; + } + + $filesystem = Filesystem::getInstance(false); + + $list = []; + foreach ($files as $field => $group) { + $field = (string)$field; + // Ignore files without a field and resized images. + if ($field === '' || strpos($field, '/')) { + continue; + } + + // Load settings for the field. + $settings = $this->getMediaFieldSettings($field); + foreach ($group as $filename => $file) { + if ($file) { + // File upload. + $filename = $file->getClientFilename(); + + /** @var FormFlashFile $file */ + $data = $file->jsonSerialize(); + unset($data['tmp_name'], $data['path']); + } else { + // File delete. + $data = null; + } + + if ($file) { + // Check file upload against media limits (except for max size). + $filename = $media->checkUploadedFile($file, $filename, ['filesize' => 0] + $settings); + } + + $self = $settings['self']; + if ($this->_loadMedia && $self) { + $filepath = $filename; + } else { + $filepath = "{$settings['destination']}/{$filename}"; + } + + // Calculate path without the retina scaling factor. + $realpath = $filesystem->pathname($filepath) . str_replace(['@3x', '@2x'], '', Utils::basename($filepath)); + + $list[$filename] = [$file, $settings]; + + $path = str_replace('.', "\n", $field); + if (null !== $data) { + $data['name'] = $filename; + $data['path'] = $filepath; + + $this->setNestedProperty("{$path}\n{$realpath}", $data, "\n"); + } else { + $this->unsetNestedProperty("{$path}\n{$realpath}", "\n"); + } + } + } + + $this->clearMediaCache(); + + $this->_uploads = $list; + } + + /** + * @param MediaCollectionInterface $media + */ + protected function addUpdatedMedia(MediaCollectionInterface $media): void + { + $updated = false; + foreach ($this->getUpdatedMedia() as $filename => $upload) { + if (is_array($upload)) { + /** @var array{UploadedFileInterface,array} $upload */ + $settings = $upload[1]; + if (isset($settings['destination']) && $settings['destination'] === $media->getPath()) { + $upload = $upload[0]; + } else { + $upload = false; + } + } + if (false !== $upload) { + $medium = $upload ? MediumFactory::fromUploadedFile($upload) : null; + $updated = true; + if ($medium) { + $medium->uploaded = true; + $medium->uploaded_file = $upload; + $media->add($filename, $medium); + } elseif (is_callable([$media, 'hide'])) { + $media->hide($filename); + } + } + } + + if ($updated) { + $media->setTimestamps(); + } + } + + /** + * @return array + */ + protected function getUpdatedMedia(): array + { + return $this->_uploads; + } + + /** + * @return void + */ + protected function saveUpdatedMedia(): void + { + $media = $this->getMedia(); + if (!$media instanceof MediaUploadInterface) { + return; + } + + // Upload/delete altered files. + /** + * @var string $filename + * @var UploadedFileInterface|array|null $file + */ + foreach ($this->getUpdatedMedia() as $filename => $file) { + if (is_array($file)) { + [$file, $settings] = $file; + } else { + $settings = null; + } + if ($file instanceof UploadedFileInterface) { + $media->copyUploadedFile($file, $filename, $settings); + } else { + $media->deleteFile($filename, $settings); + } + } + + $this->setUpdatedMedia([]); + $this->clearMediaCache(); + } + + /** + * @return void + */ + protected function freeMedia(): void + { + $this->unsetObjectProperty('media'); + } + + /** + * @param string $uri + * @return Medium|null + */ + protected function createMedium($uri) + { + $grav = Grav::instance(); + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + + $file = $uri && $locator->isStream($uri) ? $locator->findResource($uri) : $uri; + + return is_string($file) && file_exists($file) ? MediumFactory::fromFile($file) : null; + } + + /** + * @return CacheInterface + */ + protected function getMediaCache() + { + return $this->getCache('object'); + } + + /** + * @return MediaCollectionInterface + */ + protected function offsetLoad_media() + { + return $this->getMedia(); + } + + /** + * @return null + */ + protected function offsetSerialize_media() + { + return null; + } + + /** + * @return FlexDirectory + */ + abstract public function getFlexDirectory(): FlexDirectory; + + /** + * @return string + */ + abstract public function getStorageKey(): string; + + /** + * @param string $filename + * @return void + * @deprecated 1.7 Use Media class that implements MediaUploadInterface instead. + */ + public function checkMediaFilename(string $filename) + { + user_error(__METHOD__ . '() is deprecated since Grav 1.7, use Media class that implements MediaUploadInterface instead', E_USER_DEPRECATED); + + // Check the file extension. + $extension = strtolower(Utils::pathinfo($filename, PATHINFO_EXTENSION)); + + $grav = Grav::instance(); + + /** @var Config $config */ + $config = $grav['config']; + + // If not a supported type, return + if (!$extension || !$config->get("media.types.{$extension}")) { + $language = $grav['language']; + throw new RuntimeException($language->translate('PLUGIN_ADMIN.UNSUPPORTED_FILE_TYPE') . ': ' . $extension, 400); + } + } +} diff --git a/system/src/Grav/Framework/Flex/Traits/FlexRelatedDirectoryTrait.php b/system/src/Grav/Framework/Flex/Traits/FlexRelatedDirectoryTrait.php new file mode 100644 index 0000000..2922f03 --- /dev/null +++ b/system/src/Grav/Framework/Flex/Traits/FlexRelatedDirectoryTrait.php @@ -0,0 +1,59 @@ + + */ + protected function getCollectionByProperty($type, $property) + { + $directory = $this->getRelatedDirectory($type); + $collection = $directory->getCollection(); + $list = $this->getNestedProperty($property) ?: []; + + /** @var FlexCollectionInterface $collection */ + $collection = $collection->filter(static function ($object) use ($list) { + return in_array($object->getKey(), $list, true); + }); + + return $collection; + } + + /** + * @param string $type + * @return FlexDirectory + * @throws RuntimeException + */ + protected function getRelatedDirectory($type): FlexDirectory + { + $directory = $this->getFlexContainer()->getDirectory($type); + if (!$directory) { + throw new RuntimeException(ucfirst($type). ' directory does not exist!'); + } + + return $directory; + } +} diff --git a/system/src/Grav/Framework/Flex/Traits/FlexRelationshipsTrait.php b/system/src/Grav/Framework/Flex/Traits/FlexRelationshipsTrait.php new file mode 100644 index 0000000..2a73eba --- /dev/null +++ b/system/src/Grav/Framework/Flex/Traits/FlexRelationshipsTrait.php @@ -0,0 +1,61 @@ +_relationships)) { + $blueprint = $this->getBlueprint(); + $options = $blueprint->get('config/relationships', []); + $parent = FlexIdentifier::createFromObject($this); + + $this->_relationships = new Relationships($parent, $options); + } + + return $this->_relationships; + } + + /** + * @param string $name + * @return RelationshipInterface|null + */ + public function getRelationship(string $name): ?RelationshipInterface + { + return $this->getRelationships()[$name]; + } + + protected function resetRelationships(): void + { + $this->_relationships = null; + } + + /** + * @param iterable $collection + * @return array + */ + protected function buildFlexIdentifierList(iterable $collection): array + { + $list = []; + foreach ($collection as $object) { + $list[] = FlexIdentifier::createFromObject($object); + } + + return $list; + } +} diff --git a/system/src/Grav/Framework/Form/FormFlash.php b/system/src/Grav/Framework/Form/FormFlash.php new file mode 100644 index 0000000..db1d8d4 --- /dev/null +++ b/system/src/Grav/Framework/Form/FormFlash.php @@ -0,0 +1,586 @@ + $args[0], + 'unique_id' => $args[1] ?? null, + 'form_name' => $args[2] ?? null, + ]; + $config = array_filter($config, static function ($val) { + return $val !== null; + }); + } + + $this->id = $config['id'] ?? ''; + $this->sessionId = $config['session_id'] ?? ''; + $this->uniqueId = $config['unique_id'] ?? ''; + + $this->setUser($config['user'] ?? null); + + $folder = $config['folder'] ?? ($this->sessionId ? 'tmp://forms/' . $this->sessionId : ''); + + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + + $this->folder = $folder && $locator->isStream($folder) ? $locator->findResource($folder, true, true) : $folder; + + $this->init($this->loadStoredForm(), $config); + } + + /** + * @param array|null $data + * @param array $config + */ + protected function init(?array $data, array $config): void + { + if (null === $data) { + $this->exists = false; + $this->formName = $config['form_name'] ?? ''; + $this->url = ''; + $this->createdTimestamp = $this->updatedTimestamp = time(); + $this->files = []; + } else { + $this->exists = true; + $this->formName = $data['form'] ?? $config['form_name'] ?? ''; + $this->url = $data['url'] ?? ''; + $this->user = $data['user'] ?? null; + $this->updatedTimestamp = $data['timestamps']['updated'] ?? time(); + $this->createdTimestamp = $data['timestamps']['created'] ?? $this->updatedTimestamp; + $this->data = $data['data'] ?? null; + $this->files = $data['files'] ?? []; + } + } + + /** + * Load raw flex flash data from the filesystem. + * + * @return array|null + */ + protected function loadStoredForm(): ?array + { + $file = $this->getTmpIndex(); + $exists = $file && $file->exists(); + + $data = null; + if ($exists) { + try { + $data = (array)$file->content(); + } catch (Exception $e) { + } + } + + return $data; + } + + /** + * @inheritDoc + */ + public function getId(): string + { + return $this->id && $this->uniqueId ? $this->id . '/' . $this->uniqueId : ''; + } + + /** + * @inheritDoc + */ + public function getSessionId(): string + { + return $this->sessionId; + } + + /** + * @inheritDoc + */ + public function getUniqueId(): string + { + return $this->uniqueId; + } + + /** + * @return string + * @deprecated 1.6.11 Use '->getUniqueId()' method instead. + */ + public function getUniqieId(): string + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6.11, use ->getUniqueId() method instead', E_USER_DEPRECATED); + + return $this->getUniqueId(); + } + + /** + * @inheritDoc + */ + public function getFormName(): string + { + return $this->formName; + } + + + /** + * @inheritDoc + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * @inheritDoc + */ + public function getUsername(): string + { + return $this->user['username'] ?? ''; + } + + /** + * @inheritDoc + */ + public function getUserEmail(): string + { + return $this->user['email'] ?? ''; + } + + /** + * @inheritDoc + */ + public function getCreatedTimestamp(): int + { + return $this->createdTimestamp; + } + + /** + * @inheritDoc + */ + public function getUpdatedTimestamp(): int + { + return $this->updatedTimestamp; + } + + + /** + * @inheritDoc + */ + public function getData(): ?array + { + return $this->data; + } + + /** + * @inheritDoc + */ + public function setData(?array $data): void + { + $this->data = $data; + } + + /** + * @inheritDoc + */ + public function exists(): bool + { + return $this->exists; + } + + /** + * @inheritDoc + */ + public function save(bool $force = false) + { + if (!($this->folder && $this->uniqueId)) { + return $this; + } + + if ($force || $this->data || $this->files) { + // Only save if there is data or files to be saved. + $file = $this->getTmpIndex(); + if ($file) { + $file->save($this->jsonSerialize()); + $this->exists = true; + } + } elseif ($this->exists) { + // Delete empty form flash if it exists (it carries no information). + return $this->delete(); + } + + return $this; + } + + /** + * @inheritDoc + */ + public function delete() + { + if ($this->folder && $this->uniqueId) { + $this->removeTmpDir(); + $this->files = []; + $this->exists = false; + } + + return $this; + } + + /** + * @inheritDoc + */ + public function getFilesByField(string $field): array + { + if (!isset($this->uploadObjects[$field])) { + $objects = []; + foreach ($this->files[$field] ?? [] as $name => $upload) { + $objects[$name] = $upload ? new FormFlashFile($field, $upload, $this) : null; + } + $this->uploadedFiles[$field] = $objects; + } + + return $this->uploadedFiles[$field]; + } + + /** + * @inheritDoc + */ + public function getFilesByFields($includeOriginal = false): array + { + $list = []; + foreach ($this->files as $field => $values) { + if (!$includeOriginal && strpos($field, '/')) { + continue; + } + $list[$field] = $this->getFilesByField($field); + } + + return $list; + } + + /** + * @inheritDoc + */ + public function addUploadedFile(UploadedFileInterface $upload, string $field = null, array $crop = null): string + { + $tmp_dir = $this->getTmpDir(); + $tmp_name = Utils::generateRandomString(12); + $name = $upload->getClientFilename(); + if (!$name) { + throw new RuntimeException('Uploaded file has no filename'); + } + + // Prepare upload data for later save + $data = [ + 'name' => $name, + 'type' => $upload->getClientMediaType(), + 'size' => $upload->getSize(), + 'tmp_name' => $tmp_name + ]; + + Folder::create($tmp_dir); + $upload->moveTo("{$tmp_dir}/{$tmp_name}"); + + $this->addFileInternal($field, $name, $data, $crop); + + return $name; + } + + /** + * @inheritDoc + */ + public function addFile(string $filename, string $field, array $crop = null): bool + { + if (!file_exists($filename)) { + throw new RuntimeException("File not found: {$filename}"); + } + + // Prepare upload data for later save + $data = [ + 'name' => Utils::basename($filename), + 'type' => Utils::getMimeByLocalFile($filename), + 'size' => filesize($filename), + ]; + + $this->addFileInternal($field, $data['name'], $data, $crop); + + return true; + } + + /** + * @inheritDoc + */ + public function removeFile(string $name, string $field = null): bool + { + if (!$name) { + return false; + } + + $field = $field ?: 'undefined'; + + $upload = $this->files[$field][$name] ?? null; + if (null !== $upload) { + $this->removeTmpFile($upload['tmp_name'] ?? ''); + } + $upload = $this->files[$field . '/original'][$name] ?? null; + if (null !== $upload) { + $this->removeTmpFile($upload['tmp_name'] ?? ''); + } + + // Mark file as deleted. + $this->files[$field][$name] = null; + $this->files[$field . '/original'][$name] = null; + + unset( + $this->uploadedFiles[$field][$name], + $this->uploadedFiles[$field . '/original'][$name] + ); + + return true; + } + + /** + * @inheritDoc + */ + public function clearFiles() + { + foreach ($this->files as $files) { + foreach ($files as $upload) { + $this->removeTmpFile($upload['tmp_name'] ?? ''); + } + } + + $this->files = []; + } + + /** + * @inheritDoc + */ + public function jsonSerialize(): array + { + return [ + 'form' => $this->formName, + 'id' => $this->getId(), + 'unique_id' => $this->uniqueId, + 'url' => $this->url, + 'user' => $this->user, + 'timestamps' => [ + 'created' => $this->createdTimestamp, + 'updated' => time(), + ], + 'data' => $this->data, + 'files' => $this->files + ]; + } + + /** + * @param string $url + * @return $this + */ + public function setUrl(string $url): self + { + $this->url = $url; + + return $this; + } + + /** + * @param UserInterface|null $user + * @return $this + */ + public function setUser(UserInterface $user = null) + { + if ($user && $user->username) { + $this->user = [ + 'username' => $user->username, + 'email' => $user->email ?? '' + ]; + } else { + $this->user = null; + } + + return $this; + } + + /** + * @param string|null $username + * @return $this + */ + public function setUserName(string $username = null): self + { + $this->user['username'] = $username; + + return $this; + } + + /** + * @param string|null $email + * @return $this + */ + public function setUserEmail(string $email = null): self + { + $this->user['email'] = $email; + + return $this; + } + + /** + * @return string + */ + public function getTmpDir(): string + { + return $this->folder && $this->uniqueId ? "{$this->folder}/{$this->uniqueId}" : ''; + } + + /** + * @return ?YamlFile + */ + protected function getTmpIndex(): ?YamlFile + { + $tmpDir = $this->getTmpDir(); + + // Do not use CompiledYamlFile as the file can change multiple times per second. + return $tmpDir ? YamlFile::instance($tmpDir . '/index.yaml') : null; + } + + /** + * @param string $name + */ + protected function removeTmpFile(string $name): void + { + $tmpDir = $this->getTmpDir(); + $filename = $tmpDir ? $tmpDir . '/' . $name : ''; + if ($name && $filename && is_file($filename)) { + unlink($filename); + } + } + + /** + * @return void + */ + protected function removeTmpDir(): void + { + // Make sure that index file cache gets always cleared. + $file = $this->getTmpIndex(); + if ($file) { + $file->free(); + } + + $tmpDir = $this->getTmpDir(); + if ($tmpDir && file_exists($tmpDir)) { + Folder::delete($tmpDir); + } + } + + /** + * @param string|null $field + * @param string $name + * @param array $data + * @param array|null $crop + * @return void + */ + protected function addFileInternal(?string $field, string $name, array $data, array $crop = null): void + { + if (!($this->folder && $this->uniqueId)) { + throw new RuntimeException('Cannot upload files: form flash folder not defined'); + } + + $field = $field ?: 'undefined'; + if (!isset($this->files[$field])) { + $this->files[$field] = []; + } + + $oldUpload = $this->files[$field][$name] ?? null; + + if ($crop) { + // Deal with crop upload + if ($oldUpload) { + $originalUpload = $this->files[$field . '/original'][$name] ?? null; + if ($originalUpload) { + // If there is original file already present, remove the modified file + $this->files[$field . '/original'][$name]['crop'] = $crop; + $this->removeTmpFile($oldUpload['tmp_name'] ?? ''); + } else { + // Otherwise make the previous file as original + $oldUpload['crop'] = $crop; + $this->files[$field . '/original'][$name] = $oldUpload; + } + } else { + $this->files[$field . '/original'][$name] = [ + 'name' => $name, + 'type' => $data['type'], + 'crop' => $crop + ]; + } + } else { + // Deal with replacing upload + $originalUpload = $this->files[$field . '/original'][$name] ?? null; + $this->files[$field . '/original'][$name] = null; + + $this->removeTmpFile($oldUpload['tmp_name'] ?? ''); + $this->removeTmpFile($originalUpload['tmp_name'] ?? ''); + } + + // Prepare data to be saved later + $this->files[$field][$name] = $data; + } +} diff --git a/system/src/Grav/Framework/Form/FormFlashFile.php b/system/src/Grav/Framework/Form/FormFlashFile.php new file mode 100644 index 0000000..3dcf59e --- /dev/null +++ b/system/src/Grav/Framework/Form/FormFlashFile.php @@ -0,0 +1,266 @@ +id = $flash->getId() ?: $flash->getUniqueId(); + $this->field = $field; + $this->upload = $upload; + $this->flash = $flash; + + $tmpFile = $this->getTmpFile(); + if (!$tmpFile && $this->isOk()) { + $this->upload['error'] = \UPLOAD_ERR_NO_FILE; + } + + if (!isset($this->upload['size'])) { + $this->upload['size'] = $tmpFile && $this->isOk() ? filesize($tmpFile) : 0; + } + } + + /** + * @return StreamInterface + */ + public function getStream() + { + $this->validateActive(); + + $tmpFile = $this->getTmpFile(); + if (null === $tmpFile) { + throw new RuntimeException('No temporary file'); + } + + $resource = fopen($tmpFile, 'rb'); + if (false === $resource) { + throw new RuntimeException('No temporary file'); + } + + return Stream::create($resource); + } + + /** + * @param string $targetPath + * @return void + */ + public function moveTo($targetPath) + { + $this->validateActive(); + + if (!is_string($targetPath) || empty($targetPath)) { + throw new InvalidArgumentException('Invalid path provided for move operation; must be a non-empty string'); + } + $tmpFile = $this->getTmpFile(); + if (null === $tmpFile) { + throw new RuntimeException('No temporary file'); + } + + $this->moved = copy($tmpFile, $targetPath); + + if (false === $this->moved) { + throw new RuntimeException(sprintf('Uploaded file could not be moved to %s', $targetPath)); + } + + $filename = $this->getClientFilename(); + if ($filename) { + $this->flash->removeFile($filename, $this->field); + } + } + + public function getId(): string + { + return $this->id; + } + + /** + * @return string + */ + public function getField(): string + { + return $this->field; + } + + /** + * @return int + */ + public function getSize() + { + return $this->upload['size']; + } + + /** + * @return int + */ + public function getError() + { + return $this->upload['error'] ?? \UPLOAD_ERR_OK; + } + + /** + * @return string + */ + public function getClientFilename() + { + return $this->upload['name'] ?? 'unknown'; + } + + /** + * @return string + */ + public function getClientMediaType() + { + return $this->upload['type'] ?? 'application/octet-stream'; + } + + /** + * @return bool + */ + public function isMoved(): bool + { + return $this->moved; + } + + /** + * @return array + */ + public function getMetaData(): array + { + if (isset($this->upload['crop'])) { + return ['crop' => $this->upload['crop']]; + } + + return []; + } + + /** + * @return string + */ + public function getDestination() + { + return $this->upload['path'] ?? ''; + } + + /** + * @return array + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return $this->upload; + } + + /** + * @return void + */ + public function checkXss(): void + { + $tmpFile = $this->getTmpFile(); + $mime = $this->getClientMediaType(); + if (Utils::contains($mime, 'svg', false)) { + $response = Security::detectXssFromSvgFile($tmpFile); + if ($response) { + throw new RuntimeException(sprintf('SVG file XSS check failed on %s', $response)); + } + } + } + + /** + * @return string|null + */ + public function getTmpFile(): ?string + { + $tmpName = $this->upload['tmp_name'] ?? null; + + if (!$tmpName) { + return null; + } + + $tmpFile = $this->flash->getTmpDir() . '/' . $tmpName; + + return file_exists($tmpFile) ? $tmpFile : null; + } + + /** + * @return array + */ + #[\ReturnTypeWillChange] + public function __debugInfo() + { + return [ + 'id:private' => $this->id, + 'field:private' => $this->field, + 'moved:private' => $this->moved, + 'upload:private' => $this->upload, + ]; + } + + /** + * @return void + * @throws RuntimeException if is moved or not ok + */ + private function validateActive(): void + { + if (!$this->isOk()) { + throw new RuntimeException('Cannot retrieve stream due to upload error'); + } + + if ($this->moved) { + throw new RuntimeException('Cannot retrieve stream after it has already been moved'); + } + + if (!$this->getTmpFile()) { + throw new RuntimeException('Cannot retrieve stream as the file is missing'); + } + } + + /** + * @return bool return true if there is no upload error + */ + private function isOk(): bool + { + return \UPLOAD_ERR_OK === $this->getError(); + } +} diff --git a/system/src/Grav/Framework/Form/Interfaces/FormFactoryInterface.php b/system/src/Grav/Framework/Form/Interfaces/FormFactoryInterface.php new file mode 100644 index 0000000..1bc2ca6 --- /dev/null +++ b/system/src/Grav/Framework/Form/Interfaces/FormFactoryInterface.php @@ -0,0 +1,42 @@ +|Data|null */ + private $data; + /** @var UploadedFileInterface[] */ + private $files = []; + /** @var FormFlashInterface|null */ + private $flash; + /** @var string */ + private $flashFolder; + /** @var Blueprint */ + private $blueprint; + + /** + * @return string + */ + public function getId(): string + { + return $this->id; + } + + /** + * @param string $id + */ + public function setId(string $id): void + { + $this->id = $id; + } + + /** + * @return void + */ + public function disable(): void + { + $this->enabled = false; + } + + /** + * @return void + */ + public function enable(): void + { + $this->enabled = true; + } + + /** + * @return bool + */ + public function isEnabled(): bool + { + return $this->enabled; + } + + /** + * @return string + */ + public function getUniqueId(): string + { + return $this->uniqueid; + } + + /** + * @param string $uniqueId + * @return void + */ + public function setUniqueId(string $uniqueId): void + { + $this->uniqueid = $uniqueId; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @return string + */ + public function getFormName(): string + { + return $this->name; + } + + /** + * @return string + */ + public function getNonceName(): string + { + return 'form-nonce'; + } + + /** + * @return string + */ + public function getNonceAction(): string + { + return 'form'; + } + + /** + * @return string + */ + public function getNonce(): string + { + return Utils::getNonce($this->getNonceAction()); + } + + /** + * @return string + */ + public function getAction(): string + { + return ''; + } + + /** + * @return string + */ + public function getTask(): string + { + return $this->getBlueprint()->get('form/task') ?? ''; + } + + /** + * @param string|null $name + * @return mixed + */ + public function getData(string $name = null) + { + return null !== $name ? $this->data[$name] : $this->data; + } + + /** + * @return array|UploadedFileInterface[] + */ + public function getFiles(): array + { + return $this->files; + } + + /** + * @param string $name + * @return mixed|null + */ + public function getValue(string $name) + { + return $this->data[$name] ?? null; + } + + /** + * @param string $name + * @return mixed|null + */ + public function getDefaultValue(string $name) + { + $path = explode('.', $name); + $offset = array_shift($path); + + $current = $this->getDefaultValues(); + + if (!isset($current[$offset])) { + return null; + } + + $current = $current[$offset]; + + while ($path) { + $offset = array_shift($path); + + if ((is_array($current) || $current instanceof ArrayAccess) && isset($current[$offset])) { + $current = $current[$offset]; + } elseif (is_object($current) && isset($current->{$offset})) { + $current = $current->{$offset}; + } else { + return null; + } + }; + + return $current; + } + + /** + * @return array + */ + public function getDefaultValues(): array + { + return $this->getBlueprint()->getDefaults(); + } + + /** + * @param ServerRequestInterface $request + * @return FormInterface|$this + */ + public function handleRequest(ServerRequestInterface $request): FormInterface + { + // Set current form to be active. + $grav = Grav::instance(); + $forms = $grav['forms'] ?? null; + if ($forms) { + $forms->setActiveForm($this); + + /** @var Twig $twig */ + $twig = $grav['twig']; + $twig->twig_vars['form'] = $this; + } + + try { + [$data, $files] = $this->parseRequest($request); + + $this->submit($data, $files); + } catch (Exception $e) { + /** @var Debugger $debugger */ + $debugger = $grav['debugger']; + $debugger->addException($e); + + $this->setError($e->getMessage()); + } + + return $this; + } + + /** + * @param ServerRequestInterface $request + * @return FormInterface|$this + */ + public function setRequest(ServerRequestInterface $request): FormInterface + { + [$data, $files] = $this->parseRequest($request); + + $this->data = new Data($data, $this->getBlueprint()); + $this->files = $files; + + return $this; + } + + /** + * @return bool + */ + public function isValid(): bool + { + return $this->status === 'success'; + } + + /** + * @return string|null + */ + public function getError(): ?string + { + return !$this->isValid() ? $this->message : null; + } + + /** + * @return array + */ + public function getErrors(): array + { + return !$this->isValid() ? $this->messages : []; + } + + /** + * @return bool + */ + public function isSubmitted(): bool + { + return $this->submitted; + } + + /** + * @return bool + */ + public function validate(): bool + { + if (!$this->isValid()) { + return false; + } + + try { + $this->validateData($this->data); + $this->validateUploads($this->getFiles()); + } catch (ValidationException $e) { + $this->setErrors($e->getMessages()); + } catch (Exception $e) { + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $debugger->addException($e); + + $this->setError($e->getMessage()); + } + + $this->filterData($this->data); + + return $this->isValid(); + } + + /** + * @param array $data + * @param UploadedFileInterface[]|null $files + * @return FormInterface|$this + */ + public function submit(array $data, array $files = null): FormInterface + { + try { + if ($this->isSubmitted()) { + throw new RuntimeException('Form has already been submitted'); + } + + $this->data = new Data($data, $this->getBlueprint()); + $this->files = $files ?? []; + + if (!$this->validate()) { + return $this; + } + + $this->doSubmit($this->data->toArray(), $this->files); + + $this->submitted = true; + } catch (Exception $e) { + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $debugger->addException($e); + + $this->setError($e->getMessage()); + } + + return $this; + } + + /** + * @return void + */ + public function reset(): void + { + // Make sure that the flash object gets deleted. + $this->getFlash()->delete(); + + $this->data = null; + $this->files = []; + $this->status = 'success'; + $this->message = null; + $this->messages = []; + $this->submitted = false; + $this->flash = null; + } + + /** + * @return array + */ + public function getFields(): array + { + return $this->getBlueprint()->fields(); + } + + /** + * @return array + */ + public function getButtons(): array + { + return $this->getBlueprint()->get('form/buttons') ?? []; + } + + /** + * @return array + */ + public function getTasks(): array + { + return $this->getBlueprint()->get('form/tasks') ?? []; + } + + /** + * @return Blueprint + */ + abstract public function getBlueprint(): Blueprint; + + /** + * Get form flash object. + * + * @return FormFlashInterface + */ + public function getFlash() + { + if (null === $this->flash) { + $grav = Grav::instance(); + $config = [ + 'session_id' => $this->getSessionId(), + 'unique_id' => $this->getUniqueId(), + 'form_name' => $this->getName(), + 'folder' => $this->getFlashFolder(), + 'id' => $this->getFlashId() + ]; + + $this->flash = new FormFlash($config); + $this->flash->setUrl($grav['uri']->url)->setUser($grav['user'] ?? null); + } + + return $this->flash; + } + + /** + * Get all available form flash objects for this form. + * + * @return FormFlashInterface[] + */ + public function getAllFlashes(): array + { + $folder = $this->getFlashFolder(); + if (!$folder || !is_dir($folder)) { + return []; + } + + $name = $this->getName(); + + $list = []; + /** @var SplFileInfo $file */ + foreach (new FilesystemIterator($folder) as $file) { + $uniqueId = $file->getFilename(); + $config = [ + 'session_id' => $this->getSessionId(), + 'unique_id' => $uniqueId, + 'form_name' => $name, + 'folder' => $this->getFlashFolder(), + 'id' => $this->getFlashId() + ]; + $flash = new FormFlash($config); + if ($flash->exists() && $flash->getFormName() === $name) { + $list[] = $flash; + } + } + + return $list; + } + + /** + * {@inheritdoc} + * @see FormInterface::render() + */ + public function render(string $layout = null, array $context = []) + { + if (null === $layout) { + $layout = 'default'; + } + + $grav = Grav::instance(); + + $block = HtmlBlock::create(); + $block->disableCache(); + + $output = $this->getTemplate($layout)->render( + ['grav' => $grav, 'config' => $grav['config'], 'block' => $block, 'form' => $this, 'layout' => $layout] + $context + ); + + $block->setContent($output); + + return $block; + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + return $this->doSerialize(); + } + + /** + * @return array + */ + final public function __serialize(): array + { + return $this->doSerialize(); + } + + /** + * @param array $data + * @return void + */ + final public function __unserialize(array $data): void + { + $this->doUnserialize($data); + } + + protected function getSessionId(): string + { + if (null === $this->sessionid) { + /** @var Grav $grav */ + $grav = Grav::instance(); + + /** @var SessionInterface|null $session */ + $session = $grav['session'] ?? null; + + $this->sessionid = $session ? ($session->getId() ?? '') : ''; + } + + return $this->sessionid; + } + + /** + * @param string $sessionId + * @return void + */ + protected function setSessionId(string $sessionId): void + { + $this->sessionid = $sessionId; + } + + /** + * @return void + */ + protected function unsetFlash(): void + { + $this->flash = null; + } + + /** + * @return string|null + */ + protected function getFlashFolder(): ?string + { + $grav = Grav::instance(); + + /** @var UserInterface|null $user */ + $user = $grav['user'] ?? null; + if (null !== $user && $user->exists()) { + $username = $user->username; + $mediaFolder = $user->getMediaFolder(); + } else { + $username = null; + $mediaFolder = null; + } + $session = $grav['session'] ?? null; + $sessionId = $session ? $session->getId() : null; + + // Fill template token keys/value pairs. + $dataMap = [ + '[FORM_NAME]' => $this->getName(), + '[SESSIONID]' => $sessionId ?? '!!', + '[USERNAME]' => $username ?? '!!', + '[USERNAME_OR_SESSIONID]' => $username ?? $sessionId ?? '!!', + '[ACCOUNT]' => $mediaFolder ?? '!!' + ]; + + $flashLookupFolder = $this->getFlashLookupFolder(); + + $path = str_replace(array_keys($dataMap), array_values($dataMap), $flashLookupFolder); + + // Make sure we only return valid paths. + return strpos($path, '!!') === false ? rtrim($path, '/') : null; + } + + /** + * @return string|null + */ + protected function getFlashId(): ?string + { + // Fill template token keys/value pairs. + $dataMap = [ + '[FORM_NAME]' => $this->getName(), + '[SESSIONID]' => 'session', + '[USERNAME]' => '!!', + '[USERNAME_OR_SESSIONID]' => '!!', + '[ACCOUNT]' => 'account' + ]; + + $flashLookupFolder = $this->getFlashLookupFolder(); + + $path = str_replace(array_keys($dataMap), array_values($dataMap), $flashLookupFolder); + + // Make sure we only return valid paths. + return strpos($path, '!!') === false ? rtrim($path, '/') : null; + } + + /** + * @return string + */ + protected function getFlashLookupFolder(): string + { + if (null === $this->flashFolder) { + $this->flashFolder = $this->getBlueprint()->get('form/flash_folder') ?? 'tmp://forms/[SESSIONID]'; + } + + return $this->flashFolder; + } + + /** + * @param string $folder + * @return void + */ + protected function setFlashLookupFolder(string $folder): void + { + $this->flashFolder = $folder; + } + + /** + * Set a single error. + * + * @param string $error + * @return void + */ + protected function setError(string $error): void + { + $this->status = 'error'; + $this->message = $error; + } + + /** + * Set all errors. + * + * @param array $errors + * @return void + */ + protected function setErrors(array $errors): void + { + $this->status = 'error'; + $this->messages = $errors; + } + + /** + * @param string $layout + * @return Template|TemplateWrapper + * @throws LoaderError + * @throws SyntaxError + */ + protected function getTemplate($layout) + { + $grav = Grav::instance(); + + /** @var Twig $twig */ + $twig = $grav['twig']; + + return $twig->twig()->resolveTemplate( + [ + "forms/{$layout}/form.html.twig", + 'forms/default/form.html.twig' + ] + ); + } + + /** + * Parse PSR-7 ServerRequest into data and files. + * + * @param ServerRequestInterface $request + * @return array + */ + protected function parseRequest(ServerRequestInterface $request): array + { + $method = $request->getMethod(); + if (!in_array($method, ['PUT', 'POST', 'PATCH'])) { + throw new RuntimeException(sprintf('FlexForm: Bad HTTP method %s', $method)); + } + + $body = (array)$request->getParsedBody(); + $data = isset($body['data']) ? $this->decodeData($body['data']) : null; + + $flash = $this->getFlash(); + /* + if (null !== $data) { + $flash->setData($data); + $flash->save(); + } + */ + + $blueprint = $this->getBlueprint(); + $includeOriginal = (bool)($blueprint->form()['images']['original'] ?? null); + $files = $flash->getFilesByFields($includeOriginal); + + $data = $blueprint->processForm($data ?? [], $body['toggleable_data'] ?? []); + + return [ + $data, + $files + ]; + } + + /** + * Validate data and throw validation exceptions if validation fails. + * + * @param ArrayAccess|Data|null $data + * @return void + * @throws ValidationException + * @phpstan-param ArrayAccess|Data|null $data + * @throws Exception + */ + protected function validateData($data = null): void + { + if ($data instanceof Data) { + $data->validate(); + } + } + + /** + * Filter validated data. + * + * @param ArrayAccess|Data|null $data + * @return void + * @phpstan-param ArrayAccess|Data|null $data + */ + protected function filterData($data = null): void + { + if ($data instanceof Data) { + $data->filter(); + } + } + + /** + * Validate all uploaded files. + * + * @param array $files + * @return void + */ + protected function validateUploads(array $files): void + { + foreach ($files as $file) { + if (null === $file) { + continue; + } + if ($file instanceof UploadedFileInterface) { + $this->validateUpload($file); + } else { + $this->validateUploads($file); + } + } + } + + /** + * Validate uploaded file. + * + * @param UploadedFileInterface $file + * @return void + */ + protected function validateUpload(UploadedFileInterface $file): void + { + // Handle bad filenames. + $filename = $file->getClientFilename(); + if ($filename && !Utils::checkFilename($filename)) { + $grav = Grav::instance(); + throw new RuntimeException( + sprintf($grav['language']->translate('PLUGIN_FORM.FILEUPLOAD_UNABLE_TO_UPLOAD', null, true), $filename, 'Bad filename') + ); + } + + if ($file instanceof FormFlashFile) { + $file->checkXss(); + } + } + + /** + * Decode POST data + * + * @param array $data + * @return array + */ + protected function decodeData($data): array + { + if (!is_array($data)) { + return []; + } + + // Decode JSON encoded fields and merge them to data. + if (isset($data['_json'])) { + $data = array_replace_recursive($data, $this->jsonDecode($data['_json'])); + + unset($data['_json']); + } + + return $data; + } + + /** + * Recursively JSON decode POST data. + * + * @param array $data + * @return array + */ + protected function jsonDecode(array $data): array + { + foreach ($data as $key => &$value) { + if (is_array($value)) { + $value = $this->jsonDecode($value); + } elseif (trim($value) === '') { + unset($data[$key]); + } else { + $value = json_decode($value, true); + if ($value === null && json_last_error() !== JSON_ERROR_NONE) { + unset($data[$key]); + $this->setError("Badly encoded JSON data (for {$key}) was sent to the form"); + } + } + } + + return $data; + } + + /** + * @return array + */ + protected function doSerialize(): array + { + $data = $this->data instanceof Data ? $this->data->toArray() : null; + + return [ + 'name' => $this->name, + 'id' => $this->id, + 'uniqueid' => $this->uniqueid, + 'submitted' => $this->submitted, + 'status' => $this->status, + 'message' => $this->message, + 'messages' => $this->messages, + 'data' => $data, + 'files' => $this->files, + ]; + } + + /** + * @param array $data + * @return void + */ + protected function doUnserialize(array $data): void + { + $this->name = $data['name']; + $this->id = $data['id']; + $this->uniqueid = $data['uniqueid']; + $this->submitted = $data['submitted'] ?? false; + $this->status = $data['status'] ?? 'success'; + $this->message = $data['message'] ?? null; + $this->messages = $data['messages'] ?? []; + $this->data = isset($data['data']) ? new Data($data['data'], $this->getBlueprint()) : null; + $this->files = $data['files'] ?? []; + } +} diff --git a/system/src/Grav/Framework/Interfaces/RenderInterface.php b/system/src/Grav/Framework/Interfaces/RenderInterface.php new file mode 100644 index 0000000..0cefae3 --- /dev/null +++ b/system/src/Grav/Framework/Interfaces/RenderInterface.php @@ -0,0 +1,38 @@ +render('custom', ['variable' => 'value']); + * @example {% render object layout 'custom' with { variable: 'value' } %} + * + * @param string|null $layout Layout to be used. + * @param array $context Extra context given to the renderer. + * + * @return ContentBlockInterface|HtmlBlock Returns `HtmlBlock` containing the rendered output. + * @api + */ + public function render(string $layout = null, array $context = []); +} diff --git a/system/src/Grav/Framework/Logger/Processors/UserProcessor.php b/system/src/Grav/Framework/Logger/Processors/UserProcessor.php new file mode 100644 index 0000000..b42c09e --- /dev/null +++ b/system/src/Grav/Framework/Logger/Processors/UserProcessor.php @@ -0,0 +1,34 @@ +exists()) { + $record['extra']['user'] = ['username' => $user->username, 'email' => $user->email]; + } + + return $record; + } +} diff --git a/system/src/Grav/Framework/Media/Interfaces/MediaCollectionInterface.php b/system/src/Grav/Framework/Media/Interfaces/MediaCollectionInterface.php new file mode 100644 index 0000000..f0b5636 --- /dev/null +++ b/system/src/Grav/Framework/Media/Interfaces/MediaCollectionInterface.php @@ -0,0 +1,23 @@ + + * @extends Iterator + */ +interface MediaCollectionInterface extends ArrayAccess, Countable, Iterator +{ +} diff --git a/system/src/Grav/Framework/Media/Interfaces/MediaInterface.php b/system/src/Grav/Framework/Media/Interfaces/MediaInterface.php new file mode 100644 index 0000000..a4c0d0d --- /dev/null +++ b/system/src/Grav/Framework/Media/Interfaces/MediaInterface.php @@ -0,0 +1,37 @@ +get('this.is.my.nested.variable'); + * + * @param string $name Dot separated path to the requested value. + * @param mixed $default Default value (or null). + * @param string|null $separator Separator, defaults to '.' + * @return mixed Value. + */ + public function get($name, $default = null, $separator = null); +} diff --git a/system/src/Grav/Framework/Media/MediaIdentifier.php b/system/src/Grav/Framework/Media/MediaIdentifier.php new file mode 100644 index 0000000..986e997 --- /dev/null +++ b/system/src/Grav/Framework/Media/MediaIdentifier.php @@ -0,0 +1,150 @@ + + */ +class MediaIdentifier extends Identifier +{ + /** @var MediaObjectInterface|null */ + private $object = null; + + /** + * @param MediaObjectInterface $object + * @return MediaIdentifier + */ + public static function createFromObject(MediaObjectInterface $object): MediaIdentifier + { + $instance = new static($object->getId()); + $instance->setObject($object); + + return $instance; + } + + /** + * @param string $id + */ + public function __construct(string $id) + { + parent::__construct($id, 'media'); + } + + /** + * @return T + */ + public function getObject(): ?MediaObjectInterface + { + if (!isset($this->object)) { + $type = $this->getType(); + $id = $this->getId(); + + $parts = explode('/', $id); + if ($type === 'media' && str_starts_with($id, 'uploads/')) { + array_shift($parts); + [, $folder, $uniqueId, $field, $filename] = $this->findFlash($parts); + + $flash = $this->getFlash($folder, $uniqueId); + if ($flash->exists()) { + + $uploadedFile = $flash->getFilesByField($field)[$filename] ?? null; + + $this->object = UploadedMediaObject::createFromFlash($flash, $field, $filename, $uploadedFile); + } + } else { + $type = array_shift($parts); + $key = array_shift($parts); + $field = array_shift($parts); + $filename = implode('/', $parts); + + $flexObject = $this->getFlexObject($type, $key); + if ($flexObject && method_exists($flexObject, 'getMediaField') && method_exists($flexObject, 'getMedia')) { + $media = $field !== 'media' ? $flexObject->getMediaField($field) : $flexObject->getMedia(); + $image = null; + if ($media) { + $image = $media[$filename]; + } + + $this->object = new MediaObject($field, $filename, $image, $flexObject); + } + } + + if (!isset($this->object)) { + throw new \RuntimeException(sprintf('Object not found for identifier {type: "%s", id: "%s"}', $type, $id)); + } + } + + return $this->object; + } + + /** + * @param T $object + */ + public function setObject(MediaObjectInterface $object): void + { + $type = $this->getType(); + $objectType = $object->getType(); + + if ($type !== $objectType) { + throw new \RuntimeException(sprintf('Object has to be type %s, %s given', $type, $objectType)); + } + + $this->object = $object; + } + + protected function findFlash(array $parts): ?array + { + $type = array_shift($parts); + if ($type === 'account') { + /** @var UserInterface|null $user */ + $user = Grav::instance()['user'] ?? null; + $folder = $user->getMediaFolder(); + } else { + $folder = 'tmp://'; + } + + if (!$folder) { + return null; + } + + do { + $part = array_shift($parts); + $folder .= "/{$part}"; + } while (!str_starts_with($part, 'flex-')); + + $uniqueId = array_shift($parts); + $field = array_shift($parts); + $filename = implode('/', $parts); + + return [$type, $folder, $uniqueId, $field, $filename]; + } + + protected function getFlash(string $folder, string $uniqueId): FlexFormFlash + { + $config = [ + 'unique_id' => $uniqueId, + 'folder' => $folder + ]; + + return new FlexFormFlash($config); + } + + protected function getFlexObject(string $type, string $key): ?FlexObjectInterface + { + /** @var Flex $flex */ + $flex = Grav::instance()['flex']; + + return $flex->getObject($key, $type); + } +} diff --git a/system/src/Grav/Framework/Media/MediaObject.php b/system/src/Grav/Framework/Media/MediaObject.php new file mode 100644 index 0000000..8a438bf --- /dev/null +++ b/system/src/Grav/Framework/Media/MediaObject.php @@ -0,0 +1,215 @@ +field = $field; + $this->filename = $filename; + $this->media = $media; + $this->object = $object; + } + + /** + * @return string + */ + public function getType(): string + { + return 'media'; + } + + /** + * @return string + */ + public function getId(): string + { + $field = $this->field; + $object = $this->object; + $path = $field ? "/{$field}/" : '/media/'; + + return $object->getType() . '/' . $object->getKey() . $path . basename($this->filename); + } + + /** + * @return bool + */ + public function exists(): bool + { + return $this->media !== null; + } + + /** + * @return array + */ + public function getMeta(): array + { + if (!isset($this->media)) { + return []; + } + + return $this->media->getMeta(); + } + + /** + * @param string $field + * @return mixed|null + */ + public function get(string $field) + { + if (!isset($this->media)) { + return null; + } + + return $this->media->get($field); + } + + /** + * @return string + */ + public function getUrl(): string + { + if (!isset($this->media)) { + return ''; + } + + return $this->media->url(); + } + + /** + * Create media response. + * + * @param array $actions + * @return Response + */ + public function createResponse(array $actions): ResponseInterface + { + if (!isset($this->media)) { + return $this->create404Response($actions); + } + + $media = $this->media; + + if ($actions) { + $media = $this->processMediaActions($media, $actions); + } + + // FIXME: This only works for images + if (!$media instanceof ImageMedium) { + throw new \RuntimeException('Not Implemented', 500); + } + + $filename = $media->path(false); + $time = filemtime($filename); + $size = filesize($filename); + $body = fopen($filename, 'rb'); + $headers = [ + 'Content-Type' => $media->get('mime'), + 'Last-Modified' => gmdate('D, d M Y H:i:s', $time) . ' GMT', + 'ETag' => sprintf('%x-%x', $size, $time) + ]; + + return new Response(200, $headers, $body); + } + + /** + * Process media actions + * + * @param GravMediaObjectInterface $medium + * @param array $actions + * @return GravMediaObjectInterface + */ + protected function processMediaActions(GravMediaObjectInterface $medium, array $actions): GravMediaObjectInterface + { + // loop through actions for the image and call them + foreach ($actions as $method => $params) { + $matches = []; + + if (preg_match('/\[(.*)]/', $params, $matches)) { + $args = [explode(',', $matches[1])]; + } else { + $args = explode(',', $params); + } + + try { + $medium->{$method}(...$args); + } catch (Throwable $e) { + // Ignore all errors for now and just skip the action. + } + } + + return $medium; + } + + /** + * @param array $actions + * @return Response + */ + protected function create404Response(array $actions): Response + { + // Display placeholder image. + $filename = static::$placeholderImage; + + $time = filemtime($filename); + $size = filesize($filename); + $body = fopen($filename, 'rb'); + $headers = [ + 'Content-Type' => 'image/svg', + 'Last-Modified' => gmdate('D, d M Y H:i:s', $time) . ' GMT', + 'ETag' => sprintf('%x-%x', $size, $time) + ]; + + return new Response(404, $headers, $body); + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + return [ + 'type' => $this->getType(), + 'id' => $this->getId() + ]; + } + + /** + * @return string[] + */ + public function __debugInfo(): array + { + return $this->jsonSerialize(); + } +} diff --git a/system/src/Grav/Framework/Media/UploadedMediaObject.php b/system/src/Grav/Framework/Media/UploadedMediaObject.php new file mode 100644 index 0000000..0fe12e1 --- /dev/null +++ b/system/src/Grav/Framework/Media/UploadedMediaObject.php @@ -0,0 +1,172 @@ +getId(); + + return new static($id, $field, $filename, $uploadedFile); + } + + /** + * @param string $id + * @param string|null $field + * @param string $filename + * @param UploadedFileInterface|null $uploadedFile + */ + public function __construct(string $id, ?string $field, string $filename, ?UploadedFileInterface $uploadedFile = null) + { + $this->id = $id; + $this->field = $field; + $this->filename = $filename; + $this->uploadedFile = $uploadedFile; + if ($uploadedFile) { + $this->meta = [ + 'filename' => $uploadedFile->getClientFilename(), + 'mime' => $uploadedFile->getClientMediaType(), + 'size' => $uploadedFile->getSize() + ]; + } else { + $this->meta = []; + } + } + + /** + * @return string + */ + public function getType(): string + { + return 'media'; + } + + /** + * @return string + */ + public function getId(): string + { + $id = $this->id; + $field = $this->field; + $path = $field ? "/{$field}/" : ''; + + return 'uploads/' . $id . $path . basename($this->filename); + } + + /** + * @return bool + */ + public function exists(): bool + { + //return $this->uploadedFile !== null; + return false; + } + + /** + * @return array + */ + public function getMeta(): array + { + return $this->meta; + } + + /** + * @param string $field + * @return mixed|null + */ + public function get(string $field) + { + return $this->meta[$field] ?? null; + } + + /** + * @return string + */ + public function getUrl(): string + { + return ''; + } + + /** + * @return UploadedFileInterface|null + */ + public function getUploadedFile(): ?UploadedFileInterface + { + return $this->uploadedFile; + } + + /** + * @param array $actions + * @return Response + */ + public function createResponse(array $actions): ResponseInterface + { + // Display placeholder image. + $filename = static::$placeholderImage; + + $time = filemtime($filename); + $size = filesize($filename); + $body = fopen($filename, 'rb'); + $headers = [ + 'Content-Type' => 'image/svg', + 'Last-Modified' => gmdate('D, d M Y H:i:s', $time) . ' GMT', + 'ETag' => sprintf('%x-%x', $size, $time) + ]; + + return new Response(404, $headers, $body); + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + return [ + 'type' => $this->getType(), + 'id' => $this->getId() + ]; + } + + /** + * @return string[] + */ + public function __debugInfo(): array + { + return $this->jsonSerialize(); + } +} diff --git a/system/src/Grav/Framework/Mime/MimeTypes.php b/system/src/Grav/Framework/Mime/MimeTypes.php new file mode 100644 index 0000000..bc81f92 --- /dev/null +++ b/system/src/Grav/Framework/Mime/MimeTypes.php @@ -0,0 +1,107 @@ + ['mime/type', 'mime/type2']] + */ + public static function createFromMimes(array $mimes): self + { + $extensions = []; + foreach ($mimes as $ext => $list) { + foreach ($list as $mime) { + $list = $extensions[$mime] ?? []; + if (!in_array($ext, $list, true)) { + $list[] = $ext; + $extensions[$mime] = $list; + } + } + } + + return new static($extensions, $mimes); + } + + /** + * @param string $extension + * @return string|null + */ + public function getMimeType(string $extension): ?string + { + $extension = $this->cleanInput($extension); + + return $this->mimes[$extension][0] ?? null; + } + + /** + * @param string $mime + * @return string|null + */ + public function getExtension(string $mime): ?string + { + $mime = $this->cleanInput($mime); + + return $this->extensions[$mime][0] ?? null; + } + + /** + * @param string $extension + * @return array + */ + public function getMimeTypes(string $extension): array + { + $extension = $this->cleanInput($extension); + + return $this->mimes[$extension] ?? []; + } + + /** + * @param string $mime + * @return array + */ + public function getExtensions(string $mime): array + { + $mime = $this->cleanInput($mime); + + return $this->extensions[$mime] ?? []; + } + + /** + * @param string $input + * @return string + */ + protected function cleanInput(string $input): string + { + return strtolower(trim($input)); + } + + /** + * @param array $extensions + * @param array $mimes + */ + protected function __construct(array $extensions, array $mimes) + { + $this->extensions = $extensions; + $this->mimes = $mimes; + } +} diff --git a/system/src/Grav/Framework/Object/Access/ArrayAccessTrait.php b/system/src/Grav/Framework/Object/Access/ArrayAccessTrait.php new file mode 100644 index 0000000..de6c6b9 --- /dev/null +++ b/system/src/Grav/Framework/Object/Access/ArrayAccessTrait.php @@ -0,0 +1,66 @@ +hasProperty($offset); + } + + /** + * Returns the value at specified offset. + * + * @param mixed $offset The offset to retrieve. + * @return mixed Can return all value types. + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->getProperty($offset); + } + + /** + * Assigns a value to the specified offset. + * + * @param mixed $offset The offset to assign the value to. + * @param mixed $value The value to set. + * @return void + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + $this->setProperty($offset, $value); + } + + /** + * Unsets an offset. + * + * @param mixed $offset The offset to unset. + * @return void + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + $this->unsetProperty($offset); + } +} diff --git a/system/src/Grav/Framework/Object/Access/NestedArrayAccessTrait.php b/system/src/Grav/Framework/Object/Access/NestedArrayAccessTrait.php new file mode 100644 index 0000000..938ec26 --- /dev/null +++ b/system/src/Grav/Framework/Object/Access/NestedArrayAccessTrait.php @@ -0,0 +1,66 @@ +hasNestedProperty($offset); + } + + /** + * Returns the value at specified offset. + * + * @param mixed $offset The offset to retrieve. + * @return mixed Can return all value types. + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->getNestedProperty($offset); + } + + /** + * Assigns a value to the specified offset. + * + * @param mixed $offset The offset to assign the value to. + * @param mixed $value The value to set. + * @return void + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + $this->setNestedProperty($offset, $value); + } + + /** + * Unsets an offset. + * + * @param mixed $offset The offset to unset. + * @return void + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + $this->unsetNestedProperty($offset); + } +} diff --git a/system/src/Grav/Framework/Object/Access/NestedPropertyCollectionTrait.php b/system/src/Grav/Framework/Object/Access/NestedPropertyCollectionTrait.php new file mode 100644 index 0000000..1d749e3 --- /dev/null +++ b/system/src/Grav/Framework/Object/Access/NestedPropertyCollectionTrait.php @@ -0,0 +1,120 @@ +getIterator() as $id => $element) { + $list[$id] = $element->hasNestedProperty($property, $separator); + } + + return $list; + } + + /** + * @param string $property Object property to be fetched. + * @param mixed $default Default value if not set. + * @param string|null $separator Separator, defaults to '.' + * @return array Key/Value pairs of the properties. + */ + public function getNestedProperty($property, $default = null, $separator = null) + { + $list = []; + + /** @var NestedObjectInterface $element */ + foreach ($this->getIterator() as $id => $element) { + $list[$id] = $element->getNestedProperty($property, $default, $separator); + } + + return $list; + } + + /** + * @param string $property Object property to be updated. + * @param mixed $value New value. + * @param string|null $separator Separator, defaults to '.' + * @return $this + */ + public function setNestedProperty($property, $value, $separator = null) + { + /** @var NestedObjectInterface $element */ + foreach ($this->getIterator() as $element) { + $element->setNestedProperty($property, $value, $separator); + } + + return $this; + } + + /** + * @param string $property Object property to be updated. + * @param string|null $separator Separator, defaults to '.' + * @return $this + */ + public function unsetNestedProperty($property, $separator = null) + { + /** @var NestedObjectInterface $element */ + foreach ($this->getIterator() as $element) { + $element->unsetNestedProperty($property, $separator); + } + + return $this; + } + + /** + * @param string $property Object property to be updated. + * @param string $default Default value. + * @param string|null $separator Separator, defaults to '.' + * @return $this + */ + public function defNestedProperty($property, $default, $separator = null) + { + /** @var NestedObjectInterface $element */ + foreach ($this->getIterator() as $element) { + $element->defNestedProperty($property, $default, $separator); + } + + return $this; + } + + /** + * Group items in the collection by a field. + * + * @param string $property Object property to be used to make groups. + * @param string|null $separator Separator, defaults to '.' + * @return array + */ + public function group($property, $separator = null) + { + $list = []; + + /** @var NestedObjectInterface $element */ + foreach ($this->getIterator() as $element) { + $list[(string) $element->getNestedProperty($property, null, $separator)][] = $element; + } + + return $list; + } +} diff --git a/system/src/Grav/Framework/Object/Access/NestedPropertyTrait.php b/system/src/Grav/Framework/Object/Access/NestedPropertyTrait.php new file mode 100644 index 0000000..3bfebe0 --- /dev/null +++ b/system/src/Grav/Framework/Object/Access/NestedPropertyTrait.php @@ -0,0 +1,180 @@ +getNestedProperty($property, $test, $separator) !== $test; + } + + /** + * @param string $property Object property to be fetched. + * @param mixed|null $default Default value if property has not been set. + * @param string|null $separator Separator, defaults to '.' + * @return mixed Property value. + */ + public function getNestedProperty($property, $default = null, $separator = null) + { + $separator = $separator ?: '.'; + $path = explode($separator, (string) $property); + $offset = array_shift($path); + + if (!$this->hasProperty($offset)) { + return $default; + } + + $current = $this->getProperty($offset); + + while ($path) { + // Get property of nested Object. + if ($current instanceof ObjectInterface) { + if (method_exists($current, 'getNestedProperty')) { + return $current->getNestedProperty(implode($separator, $path), $default, $separator); + } + return $current->getProperty(implode($separator, $path), $default); + } + + $offset = array_shift($path); + + if ((is_array($current) || is_a($current, 'ArrayAccess')) && isset($current[$offset])) { + $current = $current[$offset]; + } elseif (is_object($current) && isset($current->{$offset})) { + $current = $current->{$offset}; + } else { + return $default; + } + }; + + return $current; + } + + + /** + * @param string $property Object property to be updated. + * @param mixed $value New value. + * @param string|null $separator Separator, defaults to '.' + * @return $this + * @throws RuntimeException + */ + public function setNestedProperty($property, $value, $separator = null) + { + $separator = $separator ?: '.'; + $path = explode($separator, $property); + $offset = array_shift($path); + + if (!$path) { + $this->setProperty($offset, $value); + + return $this; + } + + $current = &$this->doGetProperty($offset, null, true); + + while ($path) { + $offset = array_shift($path); + + // Handle arrays and scalars. + if ($current === null) { + $current = [$offset => []]; + } elseif (is_array($current)) { + if (!isset($current[$offset])) { + $current[$offset] = []; + } + } else { + throw new RuntimeException("Cannot set nested property {$property} on non-array value"); + } + + $current = &$current[$offset]; + }; + + $current = $value; + + return $this; + } + + /** + * @param string $property Object property to be updated. + * @param string|null $separator Separator, defaults to '.' + * @return $this + * @throws RuntimeException + */ + public function unsetNestedProperty($property, $separator = null) + { + $separator = $separator ?: '.'; + $path = explode($separator, $property); + $offset = array_shift($path); + + if (!$path) { + $this->unsetProperty($offset); + + return $this; + } + + $last = array_pop($path); + $current = &$this->doGetProperty($offset, null, true); + + while ($path) { + $offset = array_shift($path); + + // Handle arrays and scalars. + if ($current === null) { + return $this; + } + if (is_array($current)) { + if (!isset($current[$offset])) { + return $this; + } + } else { + throw new RuntimeException("Cannot unset nested property {$property} on non-array value"); + } + + $current = &$current[$offset]; + }; + + unset($current[$last]); + + return $this; + } + + /** + * @param string $property Object property to be updated. + * @param mixed $default Default value. + * @param string|null $separator Separator, defaults to '.' + * @return $this + * @throws RuntimeException + */ + public function defNestedProperty($property, $default, $separator = null) + { + if (!$this->hasNestedProperty($property, $separator)) { + $this->setNestedProperty($property, $default, $separator); + } + + return $this; + } +} diff --git a/system/src/Grav/Framework/Object/Access/OverloadedPropertyTrait.php b/system/src/Grav/Framework/Object/Access/OverloadedPropertyTrait.php new file mode 100644 index 0000000..428473a --- /dev/null +++ b/system/src/Grav/Framework/Object/Access/OverloadedPropertyTrait.php @@ -0,0 +1,66 @@ +hasProperty($offset); + } + + /** + * Returns the value at specified offset. + * + * @param mixed $offset The offset to retrieve. + * @return mixed Can return all value types. + */ + #[\ReturnTypeWillChange] + public function __get($offset) + { + return $this->getProperty($offset); + } + + /** + * Assigns a value to the specified offset. + * + * @param mixed $offset The offset to assign the value to. + * @param mixed $value The value to set. + * @return void + */ + #[\ReturnTypeWillChange] + public function __set($offset, $value) + { + $this->setProperty($offset, $value); + } + + /** + * Magic method to unset the attribute + * + * @param mixed $offset The name value to unset + * @return void + */ + #[\ReturnTypeWillChange] + public function __unset($offset) + { + $this->unsetProperty($offset); + } +} diff --git a/system/src/Grav/Framework/Object/ArrayObject.php b/system/src/Grav/Framework/Object/ArrayObject.php new file mode 100644 index 0000000..e8d258a --- /dev/null +++ b/system/src/Grav/Framework/Object/ArrayObject.php @@ -0,0 +1,31 @@ + + */ +class ArrayObject implements NestedObjectInterface, ArrayAccess +{ + use ObjectTrait; + use ArrayPropertyTrait; + use NestedPropertyTrait; + use OverloadedPropertyTrait; + use NestedArrayAccessTrait; +} diff --git a/system/src/Grav/Framework/Object/Base/ObjectCollectionTrait.php b/system/src/Grav/Framework/Object/Base/ObjectCollectionTrait.php new file mode 100644 index 0000000..4c7f621 --- /dev/null +++ b/system/src/Grav/Framework/Object/Base/ObjectCollectionTrait.php @@ -0,0 +1,377 @@ +getTypePrefix() : ''; + + if (static::$type) { + return $type . static::$type; + } + + $class = get_class($this); + + return $type . strtolower(substr($class, strrpos($class, '\\') + 1)); + } + + /** + * @return string + */ + public function getKey() + { + return $this->_key ?: $this->getType() . '@@' . spl_object_hash($this); + } + + /** + * @return bool + */ + public function hasKey() + { + return !empty($this->_key); + } + + /** + * @param string $property Object property name. + * @return bool[] True if property has been defined (can be null). + */ + public function hasProperty($property) + { + return $this->doHasProperty($property); + } + + /** + * @param string $property Object property to be fetched. + * @param mixed $default Default value if property has not been set. + * @return mixed[] Property values. + */ + public function getProperty($property, $default = null) + { + return $this->doGetProperty($property, $default); + } + + /** + * @param string $property Object property to be updated. + * @param mixed $value New value. + * @return $this + */ + public function setProperty($property, $value) + { + $this->doSetProperty($property, $value); + + return $this; + } + + /** + * @param string $property Object property to be unset. + * @return $this + */ + public function unsetProperty($property) + { + $this->doUnsetProperty($property); + + return $this; + } + + /** + * @param string $property Object property to be defined. + * @param mixed $default Default value. + * @return $this + */ + public function defProperty($property, $default) + { + if (!$this->hasProperty($property)) { + $this->setProperty($property, $default); + } + + return $this; + } + + /** + * @return array + */ + final public function __serialize(): array + { + return $this->doSerialize(); + } + + /** + * @param array $data + * @return void + */ + final public function __unserialize(array $data): void + { + if (method_exists($this, 'initObjectProperties')) { + $this->initObjectProperties(); + } + + $this->doUnserialize($data); + } + + + /** + * @return array + */ + protected function doSerialize() + { + return [ + 'key' => $this->getKey(), + 'type' => $this->getType(), + 'elements' => $this->getElements() + ]; + } + + /** + * @param array $data + * @return void + */ + protected function doUnserialize(array $data) + { + if (!isset($data['key'], $data['type'], $data['elements']) || $data['type'] !== $this->getType()) { + throw new InvalidArgumentException("Cannot unserialize '{$this->getType()}': Bad data"); + } + + $this->setKey($data['key']); + $this->setElements($data['elements']); + } + + /** + * Implements JsonSerializable interface. + * + * @return array + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return $this->doSerialize(); + } + + /** + * Returns a string representation of this object. + * + * @return string + */ + #[\ReturnTypeWillChange] + public function __toString() + { + return $this->getKey(); + } + + /** + * @param string $key + * @return $this + */ + public function setKey($key) + { + $this->_key = (string) $key; + + return $this; + } + + /** + * Create a copy from this collection by cloning all objects in the collection. + * + * @return static + */ + public function copy() + { + $list = []; + foreach ($this->getIterator() as $key => $value) { + /** @phpstan-ignore-next-line */ + $list[$key] = is_object($value) ? clone $value : $value; + } + + /** @phpstan-var static */ + return $this->createFrom($list); + } + + /** + * @return string[] + */ + public function getObjectKeys() + { + return $this->call('getKey'); + } + + /** + * @param string $property Object property to be matched. + * @return bool[] Key/Value pairs of the properties. + */ + public function doHasProperty($property) + { + $list = []; + + /** @var ObjectInterface $element */ + foreach ($this->getIterator() as $id => $element) { + $list[$id] = (bool)$element->hasProperty($property); + } + + return $list; + } + + /** + * @param string $property Object property to be fetched. + * @param mixed $default Default value if not set. + * @param bool $doCreate Not being used. + * @return mixed[] Key/Value pairs of the properties. + */ + public function &doGetProperty($property, $default = null, $doCreate = false) + { + $list = []; + + /** @var ObjectInterface $element */ + foreach ($this->getIterator() as $id => $element) { + $list[$id] = $element->getProperty($property, $default); + } + + return $list; + } + + /** + * @param string $property Object property to be updated. + * @param mixed $value New value. + * @return $this + */ + public function doSetProperty($property, $value) + { + /** @var ObjectInterface $element */ + foreach ($this->getIterator() as $element) { + $element->setProperty($property, $value); + } + + return $this; + } + + /** + * @param string $property Object property to be updated. + * @return $this + */ + public function doUnsetProperty($property) + { + /** @var ObjectInterface $element */ + foreach ($this->getIterator() as $element) { + $element->unsetProperty($property); + } + + return $this; + } + + /** + * @param string $property Object property to be updated. + * @param mixed $default Default value. + * @return $this + */ + public function doDefProperty($property, $default) + { + /** @var ObjectInterface $element */ + foreach ($this->getIterator() as $element) { + $element->defProperty($property, $default); + } + + return $this; + } + + /** + * @param string $method Method name. + * @param array $arguments List of arguments passed to the function. + * @return mixed[] Return values. + */ + public function call($method, array $arguments = []) + { + $list = []; + + /** + * @var string|int $id + * @var ObjectInterface $element + */ + foreach ($this->getIterator() as $id => $element) { + $callable = [$element, $method]; + $list[$id] = is_callable($callable) ? call_user_func_array($callable, $arguments) : null; + } + + return $list; + } + + /** + * Group items in the collection by a field and return them as associated array. + * + * @param string $property + * @return array + * @phpstan-return array + */ + public function group($property) + { + $list = []; + + /** @var ObjectInterface $element */ + foreach ($this->getIterator() as $element) { + $list[(string) $element->getProperty($property)][] = $element; + } + + return $list; + } + + /** + * Group items in the collection by a field and return them as associated array of collections. + * + * @param string $property + * @return static[] + * @phpstan-return array> + */ + public function collectionGroup($property) + { + $collections = []; + foreach ($this->group($property) as $id => $elements) { + /** @phpstan-var static $collection */ + $collection = $this->createFrom($elements); + + $collections[$id] = $collection; + } + + return $collections; + } +} diff --git a/system/src/Grav/Framework/Object/Base/ObjectTrait.php b/system/src/Grav/Framework/Object/Base/ObjectTrait.php new file mode 100644 index 0000000..522e514 --- /dev/null +++ b/system/src/Grav/Framework/Object/Base/ObjectTrait.php @@ -0,0 +1,202 @@ +getTypePrefix() : ''; + + if (static::$type) { + return $type . static::$type; + } + + $class = get_class($this); + return $type . strtolower(substr($class, strrpos($class, '\\') + 1)); + } + + /** + * @return string + */ + public function getKey() + { + return $this->_key ?: $this->getType() . '@@' . spl_object_hash($this); + } + + /** + * @return bool + */ + public function hasKey() + { + return !empty($this->_key); + } + + /** + * @param string $property Object property name. + * @return bool True if property has been defined (can be null). + */ + public function hasProperty($property) + { + return $this->doHasProperty($property); + } + + /** + * @param string $property Object property to be fetched. + * @param mixed $default Default value if property has not been set. + * @return mixed Property value. + */ + public function getProperty($property, $default = null) + { + return $this->doGetProperty($property, $default); + } + + /** + * @param string $property Object property to be updated. + * @param mixed $value New value. + * @return $this + */ + public function setProperty($property, $value) + { + $this->doSetProperty($property, $value); + + return $this; + } + + /** + * @param string $property Object property to be unset. + * @return $this + */ + public function unsetProperty($property) + { + $this->doUnsetProperty($property); + + return $this; + } + + /** + * @param string $property Object property to be defined. + * @param mixed $default Default value. + * @return $this + */ + public function defProperty($property, $default) + { + if (!$this->hasProperty($property)) { + $this->setProperty($property, $default); + } + + return $this; + } + + /** + * @return array + */ + final public function __serialize(): array + { + return $this->doSerialize(); + } + + /** + * @param array $data + * @return void + */ + final public function __unserialize(array $data): void + { + if (method_exists($this, 'initObjectProperties')) { + $this->initObjectProperties(); + } + + $this->doUnserialize($data); + } + + /** + * @return array + */ + protected function doSerialize() + { + return ['key' => $this->getKey(), 'type' => $this->getType(), 'elements' => $this->getElements()]; + } + + /** + * @param array $serialized + * @return void + */ + protected function doUnserialize(array $serialized) + { + if (!isset($serialized['key'], $serialized['type'], $serialized['elements']) || $serialized['type'] !== $this->getType()) { + throw new InvalidArgumentException("Cannot unserialize '{$this->getType()}': Bad data"); + } + + $this->setKey($serialized['key']); + $this->setElements($serialized['elements']); + } + + /** + * Implements JsonSerializable interface. + * + * @return array + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return $this->doSerialize(); + } + + /** + * Returns a string representation of this object. + * + * @return string + */ + #[\ReturnTypeWillChange] + public function __toString() + { + return $this->getKey(); + } + + /** + * @param string $key + * @return $this + */ + protected function setKey($key) + { + $this->_key = (string) $key; + + return $this; + } +} diff --git a/system/src/Grav/Framework/Object/Collection/ObjectExpressionVisitor.php b/system/src/Grav/Framework/Object/Collection/ObjectExpressionVisitor.php new file mode 100644 index 0000000..5b28ab0 --- /dev/null +++ b/system/src/Grav/Framework/Object/Collection/ObjectExpressionVisitor.php @@ -0,0 +1,240 @@ +{$accessor}(); + break; + } + } + + if ($op) { + $function = 'filter' . ucfirst(strtolower($op)); + if (method_exists(static::class, $function)) { + $value = static::$function($value); + } + } + + return $value; + } + + /** + * @param string $str + * @return string + */ + public static function filterLower($str) + { + return mb_strtolower($str); + } + + /** + * @param string $str + * @return string + */ + public static function filterUpper($str) + { + return mb_strtoupper($str); + } + + /** + * @param string $str + * @return int + */ + public static function filterLength($str) + { + return mb_strlen($str); + } + + /** + * @param string $str + * @return string + */ + public static function filterLtrim($str) + { + return ltrim($str); + } + + /** + * @param string $str + * @return string + */ + public static function filterRtrim($str) + { + return rtrim($str); + } + + /** + * @param string $str + * @return string + */ + public static function filterTrim($str) + { + return trim($str); + } + + /** + * Helper for sorting arrays of objects based on multiple fields + orientations. + * + * Comparison between two strings is natural and case insensitive. + * + * @param string $name + * @param int $orientation + * @param Closure|null $next + * + * @return Closure + */ + public static function sortByField($name, $orientation = 1, Closure $next = null) + { + if (!$next) { + $next = function ($a, $b) { + return 0; + }; + } + + return function ($a, $b) use ($name, $next, $orientation) { + $aValue = static::getObjectFieldValue($a, $name); + $bValue = static::getObjectFieldValue($b, $name); + + if ($aValue === $bValue) { + return $next($a, $b); + } + + // For strings we use natural case insensitive sorting. + if (is_string($aValue) && is_string($bValue)) { + return strnatcasecmp($aValue, $bValue) * $orientation; + } + + return (($aValue > $bValue) ? 1 : -1) * $orientation; + }; + } + + /** + * {@inheritDoc} + */ + public function walkComparison(Comparison $comparison) + { + $field = $comparison->getField(); + $value = $comparison->getValue()->getValue(); // shortcut for walkValue() + + switch ($comparison->getOperator()) { + case Comparison::EQ: + return function ($object) use ($field, $value) { + return static::getObjectFieldValue($object, $field) === $value; + }; + + case Comparison::NEQ: + return function ($object) use ($field, $value) { + return static::getObjectFieldValue($object, $field) !== $value; + }; + + case Comparison::LT: + return function ($object) use ($field, $value) { + return static::getObjectFieldValue($object, $field) < $value; + }; + + case Comparison::LTE: + return function ($object) use ($field, $value) { + return static::getObjectFieldValue($object, $field) <= $value; + }; + + case Comparison::GT: + return function ($object) use ($field, $value) { + return static::getObjectFieldValue($object, $field) > $value; + }; + + case Comparison::GTE: + return function ($object) use ($field, $value) { + return static::getObjectFieldValue($object, $field) >= $value; + }; + + case Comparison::IN: + return function ($object) use ($field, $value) { + return in_array(static::getObjectFieldValue($object, $field), $value, true); + }; + + case Comparison::NIN: + return function ($object) use ($field, $value) { + return !in_array(static::getObjectFieldValue($object, $field), $value, true); + }; + + case Comparison::CONTAINS: + return function ($object) use ($field, $value) { + return false !== strpos(static::getObjectFieldValue($object, $field), $value); + }; + + case Comparison::MEMBER_OF: + return function ($object) use ($field, $value) { + $fieldValues = static::getObjectFieldValue($object, $field); + if (!is_array($fieldValues)) { + $fieldValues = iterator_to_array($fieldValues); + } + return in_array($value, $fieldValues, true); + }; + + case Comparison::STARTS_WITH: + return function ($object) use ($field, $value) { + return 0 === strpos(static::getObjectFieldValue($object, $field), $value); + }; + + case Comparison::ENDS_WITH: + return function ($object) use ($field, $value) { + return $value === substr(static::getObjectFieldValue($object, $field), -strlen($value)); + }; + + default: + throw new RuntimeException('Unknown comparison operator: ' . $comparison->getOperator()); + } + } +} diff --git a/system/src/Grav/Framework/Object/Identifiers/Identifier.php b/system/src/Grav/Framework/Object/Identifiers/Identifier.php new file mode 100644 index 0000000..69f41d2 --- /dev/null +++ b/system/src/Grav/Framework/Object/Identifiers/Identifier.php @@ -0,0 +1,66 @@ +id = $id; + $this->type = $type; + } + + /** + * @return string + * @phpstan-pure + */ + public function getId(): string + { + return $this->id; + } + + /** + * @return string + * @phpstan-pure + */ + public function getType(): string + { + return $this->type; + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + return [ + 'type' => $this->type, + 'id' => $this->id + ]; + } + + /** + * @return array + */ + public function __debugInfo(): array + { + return $this->jsonSerialize(); + } +} diff --git a/system/src/Grav/Framework/Object/Interfaces/NestedObjectCollectionInterface.php b/system/src/Grav/Framework/Object/Interfaces/NestedObjectCollectionInterface.php new file mode 100644 index 0000000..ed81bb2 --- /dev/null +++ b/system/src/Grav/Framework/Object/Interfaces/NestedObjectCollectionInterface.php @@ -0,0 +1,64 @@ + + */ +interface NestedObjectCollectionInterface extends ObjectCollectionInterface +{ + /** + * @param string $property Object property name. + * @param string|null $separator Separator, defaults to '.' + * @return bool[] List of [key => bool] pairs. + */ + public function hasNestedProperty($property, $separator = null); + + /** + * @param string $property Object property to be fetched. + * @param mixed|null $default Default value if property has not been set. + * @param string|null $separator Separator, defaults to '.' + * @return mixed[] List of [key => value] pairs. + */ + public function getNestedProperty($property, $default = null, $separator = null); + + /** + * @param string $property Object property to be updated. + * @param mixed $value New value. + * @param string|null $separator Separator, defaults to '.' + * @return $this + * @throws RuntimeException + */ + public function setNestedProperty($property, $value, $separator = null); + + /** + * @param string $property Object property to be defined. + * @param mixed $default Default value. + * @param string|null $separator Separator, defaults to '.' + * @return $this + * @throws RuntimeException + */ + public function defNestedProperty($property, $default, $separator = null); + + /** + * @param string $property Object property to be unset. + * @param string|null $separator Separator, defaults to '.' + * @return $this + * @throws RuntimeException + */ + public function unsetNestedProperty($property, $separator = null); +} diff --git a/system/src/Grav/Framework/Object/Interfaces/NestedObjectInterface.php b/system/src/Grav/Framework/Object/Interfaces/NestedObjectInterface.php new file mode 100644 index 0000000..647f6c7 --- /dev/null +++ b/system/src/Grav/Framework/Object/Interfaces/NestedObjectInterface.php @@ -0,0 +1,60 @@ + + * @extends Selectable + */ +interface ObjectCollectionInterface extends CollectionInterface, Selectable, Serializable +{ + /** + * @return string + */ + public function getType(); + + /** + * @return string + */ + public function getKey(); + + /** + * @param string $key + * @return $this + */ + public function setKey($key); + + /** + * @param string $property Object property name. + * @return bool[] List of [key => bool] pairs. + */ + public function hasProperty($property); + + /** + * @param string $property Object property to be fetched. + * @param mixed|null $default Default value if property has not been set. + * @return mixed[] List of [key => value] pairs. + */ + public function getProperty($property, $default = null); + + /** + * @param string $property Object property to be updated. + * @param mixed $value New value. + * @return $this + */ + public function setProperty($property, $value); + + /** + * @param string $property Object property to be defined. + * @param mixed $default Default value. + * @return $this + */ + public function defProperty($property, $default); + + /** + * @param string $property Object property to be unset. + * @return $this + */ + public function unsetProperty($property); + + /** + * Create a copy from this collection by cloning all objects in the collection. + * + * @return static + * @phpstan-return static + */ + public function copy(); + + /** + * @return array + */ + public function getObjectKeys(); + + /** + * @param string $name Method name. + * @param array $arguments List of arguments passed to the function. + * @return array Return values. + */ + public function call($name, array $arguments = []); + + /** + * Group items in the collection by a field and return them as associated array. + * + * @param string $property + * @return array + */ + public function group($property); + + /** + * Group items in the collection by a field and return them as associated array of collections. + * + * @param string $property + * @return static[] + * @phpstan-return array> + */ + public function collectionGroup($property); + + /** + * @param array $ordering + * @return ObjectCollectionInterface + * @phpstan-return static + */ + public function orderBy(array $ordering); + + /** + * @param int $start + * @param int|null $limit + * @return ObjectCollectionInterface + * @phpstan-return static + */ + public function limit($start, $limit = null); +} diff --git a/system/src/Grav/Framework/Object/Interfaces/ObjectInterface.php b/system/src/Grav/Framework/Object/Interfaces/ObjectInterface.php new file mode 100644 index 0000000..f505f47 --- /dev/null +++ b/system/src/Grav/Framework/Object/Interfaces/ObjectInterface.php @@ -0,0 +1,63 @@ + + */ +class LazyObject implements NestedObjectInterface, ArrayAccess +{ + use ObjectTrait; + use LazyPropertyTrait; + use NestedPropertyTrait; + use OverloadedPropertyTrait; + use NestedArrayAccessTrait; +} diff --git a/system/src/Grav/Framework/Object/ObjectCollection.php b/system/src/Grav/Framework/Object/ObjectCollection.php new file mode 100644 index 0000000..ce6fa0b --- /dev/null +++ b/system/src/Grav/Framework/Object/ObjectCollection.php @@ -0,0 +1,131 @@ + + * @implements NestedObjectCollectionInterface + */ +class ObjectCollection extends ArrayCollection implements NestedObjectCollectionInterface +{ + /** @phpstan-use ObjectCollectionTrait */ + use ObjectCollectionTrait; + use NestedPropertyCollectionTrait { + NestedPropertyCollectionTrait::group insteadof ObjectCollectionTrait; + } + + /** + * @param array $elements + * @param string|null $key + * @throws InvalidArgumentException + */ + public function __construct(array $elements = [], $key = null) + { + parent::__construct($this->setElements($elements)); + + $this->setKey($key ?? ''); + } + + /** + * @param array $ordering + * @return static + * @phpstan-return static + */ + public function orderBy(array $ordering) + { + $criteria = Criteria::create()->orderBy($ordering); + + return $this->matching($criteria); + } + + /** + * @param int $start + * @param int|null $limit + * @return static + * @phpstan-return static + */ + public function limit($start, $limit = null) + { + /** @phpstan-var static */ + return $this->createFrom($this->slice($start, $limit)); + } + + /** + * @param Criteria $criteria + * @return static + * @phpstan-return static + */ + public function matching(Criteria $criteria) + { + $expr = $criteria->getWhereExpression(); + $filtered = $this->getElements(); + + if ($expr) { + $visitor = new ObjectExpressionVisitor(); + $filter = $visitor->dispatch($expr); + $filtered = array_filter($filtered, $filter); + } + + if ($orderings = $criteria->getOrderings()) { + $next = null; + foreach (array_reverse($orderings) as $field => $ordering) { + $next = ObjectExpressionVisitor::sortByField($field, $ordering === Criteria::DESC ? -1 : 1, $next); + } + + /** @phpstan-ignore-next-line */ + if ($next) { + uasort($filtered, $next); + } + } + + $offset = $criteria->getFirstResult(); + $length = $criteria->getMaxResults(); + + if ($offset || $length) { + $filtered = array_slice($filtered, (int)$offset, $length); + } + + /** @phpstan-var static */ + return $this->createFrom($filtered); + } + + /** + * @return array + * @phpstan-return array + */ + protected function getElements() + { + return $this->toArray(); + } + + /** + * @param array $elements + * @return array + * @phpstan-return array + */ + protected function setElements(array $elements) + { + /** @phpstan-var array $elements */ + return $elements; + } +} diff --git a/system/src/Grav/Framework/Object/ObjectIndex.php b/system/src/Grav/Framework/Object/ObjectIndex.php new file mode 100644 index 0000000..a241eda --- /dev/null +++ b/system/src/Grav/Framework/Object/ObjectIndex.php @@ -0,0 +1,281 @@ + + * @implements NestedObjectCollectionInterface + */ +abstract class ObjectIndex extends AbstractIndexCollection implements NestedObjectCollectionInterface +{ + /** @var string */ + protected static $type; + + /** @var string */ + protected $_key; + + /** + * @param bool $prefix + * @return string + */ + public function getType($prefix = true) + { + $type = $prefix ? $this->getTypePrefix() : ''; + + if (static::$type) { + return $type . static::$type; + } + + $class = get_class($this); + return $type . strtolower(substr($class, strrpos($class, '\\') + 1)); + } + + /** + * @return string + */ + public function getKey() + { + return $this->_key ?: $this->getType() . '@@' . spl_object_hash($this); + } + + /** + * @param string $key + * @return $this + */ + public function setKey($key) + { + $this->_key = $key; + + return $this; + } + + /** + * @param string $property Object property name. + * @return bool[] True if property has been defined (can be null). + */ + public function hasProperty($property) + { + return $this->__call('hasProperty', [$property]); + } + + /** + * @param string $property Object property to be fetched. + * @param mixed $default Default value if property has not been set. + * @return mixed[] Property values. + */ + public function getProperty($property, $default = null) + { + return $this->__call('getProperty', [$property, $default]); + } + + /** + * @param string $property Object property to be updated. + * @param string $value New value. + * @return ObjectCollectionInterface + * @phpstan-return C + */ + public function setProperty($property, $value) + { + return $this->__call('setProperty', [$property, $value]); + } + + /** + * @param string $property Object property to be defined. + * @param mixed $default Default value. + * @return ObjectCollectionInterface + * @phpstan-return C + */ + public function defProperty($property, $default) + { + return $this->__call('defProperty', [$property, $default]); + } + + /** + * @param string $property Object property to be unset. + * @return ObjectCollectionInterface + * @phpstan-return C + */ + public function unsetProperty($property) + { + return $this->__call('unsetProperty', [$property]); + } + + /** + * @param string $property Object property name. + * @param string|null $separator Separator, defaults to '.' + * @return bool[] True if property has been defined (can be null). + */ + public function hasNestedProperty($property, $separator = null) + { + return $this->__call('hasNestedProperty', [$property, $separator]); + } + + /** + * @param string $property Object property to be fetched. + * @param mixed $default Default value if property has not been set. + * @param string|null $separator Separator, defaults to '.' + * @return mixed[] Property values. + */ + public function getNestedProperty($property, $default = null, $separator = null) + { + return $this->__call('getNestedProperty', [$property, $default, $separator]); + } + + /** + * @param string $property Object property to be updated. + * @param mixed $value New value. + * @param string|null $separator Separator, defaults to '.' + * @return ObjectCollectionInterface + * @phpstan-return C + */ + public function setNestedProperty($property, $value, $separator = null) + { + return $this->__call('setNestedProperty', [$property, $value, $separator]); + } + + /** + * @param string $property Object property to be defined. + * @param mixed $default Default value. + * @param string|null $separator Separator, defaults to '.' + * @return ObjectCollectionInterface + * @phpstan-return C + */ + public function defNestedProperty($property, $default, $separator = null) + { + return $this->__call('defNestedProperty', [$property, $default, $separator]); + } + + /** + * @param string $property Object property to be unset. + * @param string|null $separator Separator, defaults to '.' + * @return ObjectCollectionInterface + * @phpstan-return C + */ + public function unsetNestedProperty($property, $separator = null) + { + return $this->__call('unsetNestedProperty', [$property, $separator]); + } + + /** + * Create a copy from this collection by cloning all objects in the collection. + * + * @return static + * @return static + */ + public function copy() + { + $list = []; + foreach ($this->getIterator() as $key => $value) { + /** @phpstan-ignore-next-line */ + $list[$key] = is_object($value) ? clone $value : $value; + } + + /** @phpstan-var static */ + return $this->createFrom($list); + } + + /** + * @return array + */ + public function getObjectKeys() + { + return $this->getKeys(); + } + + /** + * @param array $ordering + * @return ObjectCollectionInterface + * @phpstan-return C + */ + public function orderBy(array $ordering) + { + return $this->__call('orderBy', [$ordering]); + } + + /** + * @param string $method + * @param array $arguments + * @return array|mixed + */ + public function call($method, array $arguments = []) + { + return $this->__call('call', [$method, $arguments]); + } + + /** + * Group items in the collection by a field and return them as associated array. + * + * @param string $property + * @return array + */ + public function group($property) + { + return $this->__call('group', [$property]); + } + + /** + * Group items in the collection by a field and return them as associated array of collections. + * + * @param string $property + * @return ObjectCollectionInterface[] + * @phpstan-return C[] + */ + public function collectionGroup($property) + { + return $this->__call('collectionGroup', [$property]); + } + + /** + * @param Criteria $criteria + * @return ObjectCollectionInterface + * @phpstan-return C + */ + public function matching(Criteria $criteria) + { + $collection = $this->loadCollection($this->getEntries()); + + /** @phpstan-var C $matching */ + $matching = $collection->matching($criteria); + + return $matching; + } + + /** + * @param string $name + * @param array $arguments + * @return mixed + */ + #[\ReturnTypeWillChange] + abstract public function __call($name, $arguments); + + /** + * @return string + */ + protected function getTypePrefix() + { + return ''; + } +} diff --git a/system/src/Grav/Framework/Object/Property/ArrayPropertyTrait.php b/system/src/Grav/Framework/Object/Property/ArrayPropertyTrait.php new file mode 100644 index 0000000..0c0a549 --- /dev/null +++ b/system/src/Grav/Framework/Object/Property/ArrayPropertyTrait.php @@ -0,0 +1,115 @@ +setElements($elements); + $this->setKey($key ?? ''); + } + + /** + * @param string $property Object property name. + * @return bool True if property has been defined (can be null). + */ + protected function doHasProperty($property) + { + return array_key_exists($property, $this->_elements); + } + + /** + * @param string $property Object property to be fetched. + * @param mixed $default Default value if property has not been set. + * @param bool $doCreate Set true to create variable. + * @return mixed Property value. + */ + protected function &doGetProperty($property, $default = null, $doCreate = false) + { + if (!array_key_exists($property, $this->_elements)) { + if ($doCreate) { + $this->_elements[$property] = null; + } else { + return $default; + } + } + + return $this->_elements[$property]; + } + + /** + * @param string $property Object property to be updated. + * @param mixed $value New value. + * @return void + */ + protected function doSetProperty($property, $value) + { + $this->_elements[$property] = $value; + } + + /** + * @param string $property Object property to be unset. + * @return void + */ + protected function doUnsetProperty($property) + { + unset($this->_elements[$property]); + } + + /** + * @param string $property + * @param mixed|null $default + * @return mixed|null + */ + protected function getElement($property, $default = null) + { + return array_key_exists($property, $this->_elements) ? $this->_elements[$property] : $default; + } + + /** + * @return array + */ + protected function getElements() + { + return array_filter($this->_elements, static function ($val) { + return $val !== null; + }); + } + + /** + * @param array $elements + * @return void + */ + protected function setElements(array $elements) + { + $this->_elements = $elements; + } + + abstract protected function setKey($key); +} diff --git a/system/src/Grav/Framework/Object/Property/LazyPropertyTrait.php b/system/src/Grav/Framework/Object/Property/LazyPropertyTrait.php new file mode 100644 index 0000000..fe00d50 --- /dev/null +++ b/system/src/Grav/Framework/Object/Property/LazyPropertyTrait.php @@ -0,0 +1,114 @@ +offsetLoad($offset, $value)` called first time object property gets accessed + * - `$this->offsetPrepare($offset, $value)` called on every object property set + * - `$this->offsetSerialize($offset, $value)` called when the raw or serialized object property value is needed + * + * @package Grav\Framework\Object\Property + */ +trait LazyPropertyTrait +{ + use ArrayPropertyTrait, ObjectPropertyTrait { + ObjectPropertyTrait::__construct insteadof ArrayPropertyTrait; + ArrayPropertyTrait::doHasProperty as hasArrayProperty; + ArrayPropertyTrait::doGetProperty as getArrayProperty; + ArrayPropertyTrait::doSetProperty as setArrayProperty; + ArrayPropertyTrait::doUnsetProperty as unsetArrayProperty; + ArrayPropertyTrait::getElement as getArrayElement; + ArrayPropertyTrait::getElements as getArrayElements; + ArrayPropertyTrait::setElements insteadof ObjectPropertyTrait; + ObjectPropertyTrait::doHasProperty as hasObjectProperty; + ObjectPropertyTrait::doGetProperty as getObjectProperty; + ObjectPropertyTrait::doSetProperty as setObjectProperty; + ObjectPropertyTrait::doUnsetProperty as unsetObjectProperty; + ObjectPropertyTrait::getElement as getObjectElement; + ObjectPropertyTrait::getElements as getObjectElements; + } + + /** + * @param string $property Object property name. + * @return bool True if property has been defined (can be null). + */ + protected function doHasProperty($property) + { + return $this->hasArrayProperty($property) || $this->hasObjectProperty($property); + } + + /** + * @param string $property Object property to be fetched. + * @param mixed $default Default value if property has not been set. + * @param bool $doCreate + * @return mixed Property value. + */ + protected function &doGetProperty($property, $default = null, $doCreate = false) + { + if ($this->hasObjectProperty($property)) { + return $this->getObjectProperty($property, $default, function ($default = null) use ($property) { + return $this->getArrayProperty($property, $default); + }); + } + + return $this->getArrayProperty($property, $default, $doCreate); + } + + /** + * @param string $property Object property to be updated. + * @param mixed $value New value. + * @return void + */ + protected function doSetProperty($property, $value) + { + if ($this->hasObjectProperty($property)) { + $this->setObjectProperty($property, $value); + } else { + $this->setArrayProperty($property, $value); + } + } + + /** + * @param string $property Object property to be unset. + * @return void + */ + protected function doUnsetProperty($property) + { + $this->hasObjectProperty($property) ? $this->unsetObjectProperty($property) : $this->unsetArrayProperty($property); + } + + /** + * @param string $property + * @param mixed|null $default + * @return mixed|null + */ + protected function getElement($property, $default = null) + { + if ($this->isPropertyLoaded($property)) { + return $this->getObjectElement($property, $default); + } + + return $this->getArrayElement($property, $default); + } + + /** + * @return array + */ + protected function getElements() + { + return $this->getObjectElements() + $this->getArrayElements(); + } +} diff --git a/system/src/Grav/Framework/Object/Property/MixedPropertyTrait.php b/system/src/Grav/Framework/Object/Property/MixedPropertyTrait.php new file mode 100644 index 0000000..3734760 --- /dev/null +++ b/system/src/Grav/Framework/Object/Property/MixedPropertyTrait.php @@ -0,0 +1,121 @@ +offsetLoad($offset, $value)` called first time object property gets accessed + * - `$this->offsetPrepare($offset, $value)` called on every object property set + * - `$this->offsetSerialize($offset, $value)` called when the raw or serialized object property value is needed + + * + * @package Grav\Framework\Object\Property + */ +trait MixedPropertyTrait +{ + use ArrayPropertyTrait, ObjectPropertyTrait { + ObjectPropertyTrait::__construct insteadof ArrayPropertyTrait; + ArrayPropertyTrait::doHasProperty as hasArrayProperty; + ArrayPropertyTrait::doGetProperty as getArrayProperty; + ArrayPropertyTrait::doSetProperty as setArrayProperty; + ArrayPropertyTrait::doUnsetProperty as unsetArrayProperty; + ArrayPropertyTrait::getElement as getArrayElement; + ArrayPropertyTrait::getElements as getArrayElements; + ArrayPropertyTrait::setElements as setArrayElements; + ObjectPropertyTrait::doHasProperty as hasObjectProperty; + ObjectPropertyTrait::doGetProperty as getObjectProperty; + ObjectPropertyTrait::doSetProperty as setObjectProperty; + ObjectPropertyTrait::doUnsetProperty as unsetObjectProperty; + ObjectPropertyTrait::getElement as getObjectElement; + ObjectPropertyTrait::getElements as getObjectElements; + ObjectPropertyTrait::setElements as setObjectElements; + } + + /** + * @param string $property Object property name. + * @return bool True if property has been defined (can be null). + */ + protected function doHasProperty($property) + { + return $this->hasArrayProperty($property) || $this->hasObjectProperty($property); + } + + /** + * @param string $property Object property to be fetched. + * @param mixed $default Default value if property has not been set. + * @param bool $doCreate + * @return mixed Property value. + */ + protected function &doGetProperty($property, $default = null, $doCreate = false) + { + if ($this->hasObjectProperty($property)) { + return $this->getObjectProperty($property); + } + + return $this->getArrayProperty($property, $default, $doCreate); + } + + /** + * @param string $property Object property to be updated. + * @param mixed $value New value. + * @return void + */ + protected function doSetProperty($property, $value) + { + $this->hasObjectProperty($property) + ? $this->setObjectProperty($property, $value) : $this->setArrayProperty($property, $value); + } + + /** + * @param string $property Object property to be unset. + * @return void + */ + protected function doUnsetProperty($property) + { + $this->hasObjectProperty($property) ? + $this->unsetObjectProperty($property) : $this->unsetArrayProperty($property); + } + + /** + * @param string $property + * @param mixed|null $default + * @return mixed|null + */ + protected function getElement($property, $default = null) + { + if ($this->hasObjectProperty($property)) { + return $this->getObjectElement($property, $default); + } + + return $this->getArrayElement($property, $default); + } + + /** + * @return array + */ + protected function getElements() + { + return $this->getObjectElements() + $this->getArrayElements(); + } + + /** + * @param array $elements + * @return void + */ + protected function setElements(array $elements) + { + $this->setObjectElements(array_intersect_key($elements, $this->_definedProperties)); + $this->setArrayElements(array_diff_key($elements, $this->_definedProperties)); + } +} diff --git a/system/src/Grav/Framework/Object/Property/ObjectPropertyTrait.php b/system/src/Grav/Framework/Object/Property/ObjectPropertyTrait.php new file mode 100644 index 0000000..618dbbd --- /dev/null +++ b/system/src/Grav/Framework/Object/Property/ObjectPropertyTrait.php @@ -0,0 +1,213 @@ +offsetLoad($offset, $value)` called first time object property gets accessed + * - `$this->offsetPrepare($offset, $value)` called on every object property set + * - `$this->offsetSerialize($offset, $value)` called when the raw or serialized object property value is needed + * + * @package Grav\Framework\Object\Property + */ +trait ObjectPropertyTrait +{ + /** @var array */ + private $_definedProperties; + + /** + * @param array $elements + * @param string|null $key + * @throws InvalidArgumentException + */ + public function __construct(array $elements = [], $key = null) + { + $this->initObjectProperties(); + $this->setElements($elements); + $this->setKey($key ?? ''); + } + + /** + * @param string $property Object property name. + * @return bool True if property has been loaded. + */ + protected function isPropertyLoaded($property) + { + return !empty($this->_definedProperties[$property]); + } + + /** + * @param string $offset + * @param mixed $value + * @return mixed + */ + protected function offsetLoad($offset, $value) + { + $methodName = "offsetLoad_{$offset}"; + + return method_exists($this, $methodName)? $this->{$methodName}($value) : $value; + } + + /** + * @param string $offset + * @param mixed $value + * @return mixed + */ + protected function offsetPrepare($offset, $value) + { + $methodName = "offsetPrepare_{$offset}"; + + return method_exists($this, $methodName) ? $this->{$methodName}($value) : $value; + } + + /** + * @param string $offset + * @param mixed $value + * @return mixed + */ + protected function offsetSerialize($offset, $value) + { + $methodName = "offsetSerialize_{$offset}"; + + return method_exists($this, $methodName) ? $this->{$methodName}($value) : $value; + } + + /** + * @param string $property Object property name. + * @return bool True if property has been defined (can be null). + */ + protected function doHasProperty($property) + { + return array_key_exists($property, $this->_definedProperties); + } + + /** + * @param string $property Object property to be fetched. + * @param mixed $default Default value if property has not been set. + * @param callable|bool $doCreate Set true to create variable. + * @return mixed Property value. + */ + protected function &doGetProperty($property, $default = null, $doCreate = false) + { + if (!array_key_exists($property, $this->_definedProperties)) { + throw new InvalidArgumentException("Property '{$property}' does not exist in the object!"); + } + + if (empty($this->_definedProperties[$property])) { + if ($doCreate === true) { + $this->_definedProperties[$property] = true; + $this->{$property} = null; + } elseif (is_callable($doCreate)) { + $this->_definedProperties[$property] = true; + $this->{$property} = $this->offsetLoad($property, $doCreate()); + } else { + return $default; + } + } + + return $this->{$property}; + } + + /** + * @param string $property Object property to be updated. + * @param mixed $value New value. + * @return void + * @throws InvalidArgumentException + */ + protected function doSetProperty($property, $value) + { + if (!array_key_exists($property, $this->_definedProperties)) { + throw new InvalidArgumentException("Property '{$property}' does not exist in the object!"); + } + + $this->_definedProperties[$property] = true; + $this->{$property} = $this->offsetPrepare($property, $value); + } + + /** + * @param string $property Object property to be unset. + * @return void + */ + protected function doUnsetProperty($property) + { + if (!array_key_exists($property, $this->_definedProperties)) { + return; + } + + $this->_definedProperties[$property] = false; + $this->{$property} = null; + } + + /** + * @return void + */ + protected function initObjectProperties() + { + $this->_definedProperties = []; + foreach (get_object_vars($this) as $property => $value) { + if ($property[0] !== '_') { + $this->_definedProperties[$property] = ($value !== null); + } + } + } + + /** + * @param string $property + * @param mixed|null $default + * @return mixed|null + */ + protected function getElement($property, $default = null) + { + if (empty($this->_definedProperties[$property])) { + return $default; + } + + return $this->offsetSerialize($property, $this->{$property}); + } + + /** + * @return array + */ + protected function getElements() + { + $properties = array_intersect_key(get_object_vars($this), array_filter($this->_definedProperties)); + + $elements = []; + foreach ($properties as $offset => $value) { + $serialized = $this->offsetSerialize($offset, $value); + if ($serialized !== null) { + $elements[$offset] = $this->offsetSerialize($offset, $value); + } + } + + return $elements; + } + + /** + * @param array $elements + * @return void + */ + protected function setElements(array $elements) + { + foreach ($elements as $property => $value) { + $this->setProperty($property, $value); + } + } +} diff --git a/system/src/Grav/Framework/Object/PropertyObject.php b/system/src/Grav/Framework/Object/PropertyObject.php new file mode 100644 index 0000000..b61d154 --- /dev/null +++ b/system/src/Grav/Framework/Object/PropertyObject.php @@ -0,0 +1,32 @@ + + */ +class PropertyObject implements NestedObjectInterface, ArrayAccess +{ + use ObjectTrait; + use ObjectPropertyTrait; + use NestedPropertyTrait; + use OverloadedPropertyTrait; + use NestedArrayAccessTrait; +} diff --git a/system/src/Grav/Framework/Pagination/AbstractPagination.php b/system/src/Grav/Framework/Pagination/AbstractPagination.php new file mode 100644 index 0000000..084fb1d --- /dev/null +++ b/system/src/Grav/Framework/Pagination/AbstractPagination.php @@ -0,0 +1,429 @@ + 'page', + 'limit' => 10, + 'display' => 5, + 'opening' => 0, + 'ending' => 0, + 'url' => null, + 'param' => null, + 'use_query_param' => false + ]; + /** @var array */ + private $items; + + /** + * @return bool + */ + public function isEnabled(): bool + { + return $this->count() > 1; + } + + /** + * @return array + */ + public function getOptions(): array + { + return $this->options; + } + + /** + * @return Route|null + */ + public function getRoute(): ?Route + { + return $this->route; + } + + /** + * @return int + */ + public function getTotalPages(): int + { + return $this->pages; + } + + /** + * @return int + */ + public function getPageNumber(): int + { + return $this->page ?? 1; + } + + /** + * @param int $count + * @return int|null + */ + public function getPrevNumber(int $count = 1): ?int + { + $page = $this->page - $count; + + return $page >= 1 ? $page : null; + } + + /** + * @param int $count + * @return int|null + */ + public function getNextNumber(int $count = 1): ?int + { + $page = $this->page + $count; + + return $page <= $this->pages ? $page : null; + } + + /** + * @param int $page + * @param string|null $label + * @return PaginationPage|null + */ + public function getPage(int $page, string $label = null): ?PaginationPage + { + if ($page < 1 || $page > $this->pages) { + return null; + } + + $start = ($page - 1) * $this->limit; + $type = $this->getOptions()['type']; + $param = $this->getOptions()['param']; + $useQuery = $this->getOptions()['use_query_param']; + if ($type === 'page') { + $param = $param ?? 'page'; + $offset = $page; + } else { + $param = $param ?? 'start'; + $offset = $start; + } + + if ($useQuery) { + $route = $this->route->withQueryParam($param, $offset); + } else { + $route = $this->route->withGravParam($param, $offset); + } + + return new PaginationPage( + [ + 'label' => $label ?? (string)$page, + 'number' => $page, + 'offset_start' => $start, + 'offset_end' => min($start + $this->limit, $this->total) - 1, + 'enabled' => $page !== $this->page || $this->viewAll, + 'active' => $page === $this->page, + 'route' => $route + ] + ); + } + + /** + * @param string|null $label + * @param int $count + * @return PaginationPage|null + */ + public function getFirstPage(string $label = null, int $count = 0): ?PaginationPage + { + return $this->getPage(1 + $count, $label ?? $this->getOptions()['label_first'] ?? null); + } + + /** + * @param string|null $label + * @param int $count + * @return PaginationPage|null + */ + public function getPrevPage(string $label = null, int $count = 1): ?PaginationPage + { + return $this->getPage($this->page - $count, $label ?? $this->getOptions()['label_prev'] ?? null); + } + + /** + * @param string|null $label + * @param int $count + * @return PaginationPage|null + */ + public function getNextPage(string $label = null, int $count = 1): ?PaginationPage + { + return $this->getPage($this->page + $count, $label ?? $this->getOptions()['label_next'] ?? null); + } + + /** + * @param string|null $label + * @param int $count + * @return PaginationPage|null + */ + public function getLastPage(string $label = null, int $count = 0): ?PaginationPage + { + return $this->getPage($this->pages - $count, $label ?? $this->getOptions()['label_last'] ?? null); + } + + /** + * @return int + */ + public function getStart(): int + { + return $this->start ?? 0; + } + + /** + * @return int + */ + public function getLimit(): int + { + return $this->limit; + } + + /** + * @return int + */ + public function getTotal(): int + { + return $this->total; + } + + /** + * @return int + */ + public function count(): int + { + $this->loadItems(); + + return count($this->items); + } + + /** + * @return ArrayIterator + * @phpstan-return ArrayIterator + */ + #[\ReturnTypeWillChange] + public function getIterator() + { + $this->loadItems(); + + return new ArrayIterator($this->items); + } + + /** + * @return array + */ + public function getPages(): array + { + $this->loadItems(); + + return $this->items; + } + + /** + * @return void + */ + protected function loadItems() + { + $this->calculateRange(); + + // Make list like: 1 ... 4 5 6 ... 10 + $range = range($this->pagesStart, $this->pagesStop); + //$range[] = 1; + //$range[] = $this->pages; + natsort($range); + $range = array_unique($range); + + $this->items = []; + foreach ($range as $i) { + $this->items[$i] = $this->getPage($i); + } + } + + /** + * @param Route $route + * @return $this + */ + protected function setRoute(Route $route) + { + $this->route = $route; + + return $this; + } + + /** + * @param array|null $options + * @return $this + */ + protected function setOptions(array $options = null) + { + $this->options = $options ? array_merge($this->defaultOptions, $options) : $this->defaultOptions; + + return $this; + } + + /** + * @param int|null $page + * @return $this + */ + protected function setPage(int $page = null) + { + $this->page = (int)max($page, 1); + $this->start = null; + + return $this; + } + + /** + * @param int|null $start + * @return $this + */ + protected function setStart(int $start = null) + { + $this->start = (int)max($start, 0); + $this->page = null; + + return $this; + } + + /** + * @param int|null $limit + * @return $this + */ + protected function setLimit(int $limit = null) + { + $this->limit = (int)max($limit ?? $this->getOptions()['limit'], 0); + + // No limit, display all records in a single page. + $this->viewAll = !$limit; + + return $this; + } + + /** + * @param int $total + * @return $this + */ + protected function setTotal(int $total) + { + $this->total = (int)max($total, 0); + + return $this; + } + + /** + * @param Route $route + * @param int $total + * @param int|null $pos + * @param int|null $limit + * @param array|null $options + * @return void + */ + protected function initialize(Route $route, int $total, int $pos = null, int $limit = null, array $options = null) + { + $this->setRoute($route); + $this->setOptions($options); + $this->setTotal($total); + if ($this->getOptions()['type'] === 'start') { + $this->setStart($pos); + } else { + $this->setPage($pos); + } + $this->setLimit($limit); + $this->calculateLimits(); + } + + /** + * @return void + */ + protected function calculateLimits() + { + $limit = $this->limit; + $total = $this->total; + + if (!$limit || $limit > $total) { + // All records fit into a single page. + $this->start = 0; + $this->page = 1; + $this->pages = 1; + + return; + } + + if (null === $this->start) { + // If we are using page, convert it to start. + $this->start = (int)(($this->page - 1) * $limit); + } + + if ($this->start > $total - $limit) { + // If start is greater than total count (i.e. we are asked to display records that don't exist) + // then set start to display the last natural page of results. + $this->start = (int)max(0, (ceil($total / $limit) - 1) * $limit); + } + + // Set the total pages and current page values. + $this->page = (int)ceil(($this->start + 1) / $limit); + $this->pages = (int)ceil($total / $limit); + } + + /** + * @return void + */ + protected function calculateRange() + { + $options = $this->getOptions(); + $displayed = $options['display']; + $opening = $options['opening']; + $ending = $options['ending']; + + // Set the pagination iteration loop values. + $this->pagesStart = $this->page - (int)($displayed / 2); + if ($this->pagesStart < 1 + $opening) { + $this->pagesStart = 1 + $opening; + } + if ($this->pagesStart + $displayed - $opening > $this->pages) { + $this->pagesStop = $this->pages; + if ($this->pages < $displayed) { + $this->pagesStart = 1 + $opening; + } else { + $this->pagesStart = $this->pages - $displayed + 1 + $opening; + } + } else { + $this->pagesStop = (int)max(1, $this->pagesStart + $displayed - 1 - $ending); + } + } +} diff --git a/system/src/Grav/Framework/Pagination/AbstractPaginationPage.php b/system/src/Grav/Framework/Pagination/AbstractPaginationPage.php new file mode 100644 index 0000000..9a61060 --- /dev/null +++ b/system/src/Grav/Framework/Pagination/AbstractPaginationPage.php @@ -0,0 +1,78 @@ +options['active'] ?? false; + } + + /** + * @return bool + */ + public function isEnabled(): bool + { + return $this->options['enabled'] ?? false; + } + + /** + * @return array + */ + public function getOptions(): array + { + return $this->options; + } + + /** + * @return int|null + */ + public function getNumber(): ?int + { + return $this->options['number'] ?? null; + } + + /** + * @return string + */ + public function getLabel(): string + { + return $this->options['label'] ?? (string)$this->getNumber(); + } + + /** + * @return string|null + */ + public function getUrl(): ?string + { + return $this->options['route'] ? (string)$this->options['route']->getUri() : null; + } + + /** + * @param array $options + */ + protected function setOptions(array $options): void + { + $this->options = $options; + } +} diff --git a/system/src/Grav/Framework/Pagination/Interfaces/PaginationInterface.php b/system/src/Grav/Framework/Pagination/Interfaces/PaginationInterface.php new file mode 100644 index 0000000..b329c53 --- /dev/null +++ b/system/src/Grav/Framework/Pagination/Interfaces/PaginationInterface.php @@ -0,0 +1,104 @@ + + */ +interface PaginationInterface extends Countable, IteratorAggregate +{ + /** + * @return int + */ + public function getTotalPages(): int; + + /** + * @return int + */ + public function getPageNumber(): int; + + /** + * @param int $count + * @return int|null + */ + public function getPrevNumber(int $count = 1): ?int; + + /** + * @param int $count + * @return int|null + */ + public function getNextNumber(int $count = 1): ?int; + + /** + * @return int + */ + public function getStart(): int; + + /** + * @return int + */ + public function getLimit(): int; + + /** + * @return int + */ + public function getTotal(): int; + + /** + * @return int + */ + public function count(): int; + + /** + * @return array + */ + public function getOptions(): array; + + /** + * @param int $page + * @param string|null $label + * @return PaginationPage|null + */ + public function getPage(int $page, string $label = null): ?PaginationPage; + + /** + * @param string|null $label + * @param int $count + * @return PaginationPage|null + */ + public function getFirstPage(string $label = null, int $count = 0): ?PaginationPage; + + /** + * @param string|null $label + * @param int $count + * @return PaginationPage|null + */ + public function getPrevPage(string $label = null, int $count = 1): ?PaginationPage; + + /** + * @param string|null $label + * @param int $count + * @return PaginationPage|null + */ + public function getNextPage(string $label = null, int $count = 1): ?PaginationPage; + + /** + * @param string|null $label + * @param int $count + * @return PaginationPage|null + */ + public function getLastPage(string $label = null, int $count = 0): ?PaginationPage; +} diff --git a/system/src/Grav/Framework/Pagination/Interfaces/PaginationPageInterface.php b/system/src/Grav/Framework/Pagination/Interfaces/PaginationPageInterface.php new file mode 100644 index 0000000..082f292 --- /dev/null +++ b/system/src/Grav/Framework/Pagination/Interfaces/PaginationPageInterface.php @@ -0,0 +1,47 @@ +initialize($route, $total, $pos, $limit, $options); + } +} diff --git a/system/src/Grav/Framework/Pagination/PaginationPage.php b/system/src/Grav/Framework/Pagination/PaginationPage.php new file mode 100644 index 0000000..0a04b6a --- /dev/null +++ b/system/src/Grav/Framework/Pagination/PaginationPage.php @@ -0,0 +1,26 @@ +setOptions($options); + } +} diff --git a/system/src/Grav/Framework/Psr7/AbstractUri.php b/system/src/Grav/Framework/Psr7/AbstractUri.php new file mode 100644 index 0000000..f009135 --- /dev/null +++ b/system/src/Grav/Framework/Psr7/AbstractUri.php @@ -0,0 +1,412 @@ + 80, + 'https' => 443 + ]; + + /** @var string Uri scheme. */ + private $scheme = ''; + /** @var string Uri user. */ + private $user = ''; + /** @var string Uri password. */ + private $password = ''; + /** @var string Uri host. */ + private $host = ''; + /** @var int|null Uri port. */ + private $port; + /** @var string Uri path. */ + private $path = ''; + /** @var string Uri query string (without ?). */ + private $query = ''; + /** @var string Uri fragment (without #). */ + private $fragment = ''; + + /** + * Please define constructor which calls $this->init(). + */ + abstract public function __construct(); + + /** + * @inheritdoc + */ + public function getScheme() + { + return $this->scheme; + } + + /** + * @inheritdoc + */ + public function getAuthority() + { + $authority = $this->host; + + $userInfo = $this->getUserInfo(); + if ($userInfo !== '') { + $authority = $userInfo . '@' . $authority; + } + + if ($this->port !== null) { + $authority .= ':' . $this->port; + } + + return $authority; + } + + /** + * @inheritdoc + */ + public function getUserInfo() + { + $userInfo = $this->user; + + if ($this->password !== '') { + $userInfo .= ':' . $this->password; + } + + return $userInfo; + } + + /** + * @inheritdoc + */ + public function getHost() + { + return $this->host; + } + + /** + * @inheritdoc + */ + public function getPort() + { + return $this->port; + } + + /** + * @inheritdoc + */ + public function getPath() + { + return $this->path; + } + + /** + * @inheritdoc + */ + public function getQuery() + { + return $this->query; + } + + /** + * @inheritdoc + */ + public function getFragment() + { + return $this->fragment; + } + + /** + * @inheritdoc + */ + public function withScheme($scheme) + { + $scheme = UriPartsFilter::filterScheme($scheme); + + if ($this->scheme === $scheme) { + return $this; + } + + $new = clone $this; + $new->scheme = $scheme; + $new->unsetDefaultPort(); + $new->validate(); + + return $new; + } + + /** + * @inheritdoc + * @throws InvalidArgumentException + */ + public function withUserInfo($user, $password = null) + { + $user = UriPartsFilter::filterUserInfo($user); + $password = UriPartsFilter::filterUserInfo($password ?? ''); + + if ($this->user === $user && $this->password === $password) { + return $this; + } + + $new = clone $this; + $new->user = $user; + $new->password = $user !== '' ? $password : ''; + $new->validate(); + + return $new; + } + + /** + * @inheritdoc + */ + public function withHost($host) + { + $host = UriPartsFilter::filterHost($host); + + if ($this->host === $host) { + return $this; + } + + $new = clone $this; + $new->host = $host; + $new->validate(); + + return $new; + } + + /** + * @inheritdoc + */ + public function withPort($port) + { + $port = UriPartsFilter::filterPort($port); + + if ($this->port === $port) { + return $this; + } + + $new = clone $this; + $new->port = $port; + $new->unsetDefaultPort(); + $new->validate(); + + return $new; + } + + /** + * @inheritdoc + */ + public function withPath($path) + { + $path = UriPartsFilter::filterPath($path); + + if ($this->path === $path) { + return $this; + } + + $new = clone $this; + $new->path = $path; + $new->validate(); + + return $new; + } + + /** + * @inheritdoc + */ + public function withQuery($query) + { + $query = UriPartsFilter::filterQueryOrFragment($query); + + if ($this->query === $query) { + return $this; + } + + $new = clone $this; + $new->query = $query; + + return $new; + } + + /** + * @inheritdoc + * @throws InvalidArgumentException + */ + public function withFragment($fragment) + { + $fragment = UriPartsFilter::filterQueryOrFragment($fragment); + + if ($this->fragment === $fragment) { + return $this; + } + + $new = clone $this; + $new->fragment = $fragment; + + return $new; + } + + /** + * @return string + */ + #[\ReturnTypeWillChange] + public function __toString() + { + return $this->getUrl(); + } + + /** + * @return array + */ + protected function getParts() + { + return [ + 'scheme' => $this->scheme, + 'host' => $this->host, + 'port' => $this->port, + 'user' => $this->user, + 'pass' => $this->password, + 'path' => $this->path, + 'query' => $this->query, + 'fragment' => $this->fragment + ]; + } + + /** + * Return the fully qualified base URL ( like http://getgrav.org ). + * + * Note that this method never includes a trailing / + * + * @return string + */ + protected function getBaseUrl() + { + $uri = ''; + + $scheme = $this->getScheme(); + if ($scheme !== '') { + $uri .= $scheme . ':'; + } + + $authority = $this->getAuthority(); + if ($authority !== '' || $scheme === 'file') { + $uri .= '//' . $authority; + } + + return $uri; + } + + /** + * @return string + */ + protected function getUrl() + { + $uri = $this->getBaseUrl() . $this->getPath(); + + $query = $this->getQuery(); + if ($query !== '') { + $uri .= '?' . $query; + } + + $fragment = $this->getFragment(); + if ($fragment !== '') { + $uri .= '#' . $fragment; + } + + return $uri; + } + + /** + * @return string + */ + protected function getUser() + { + return $this->user; + } + + /** + * @return string + */ + protected function getPassword() + { + return $this->password; + } + + /** + * @param array $parts + * @return void + * @throws InvalidArgumentException + */ + protected function initParts(array $parts) + { + $this->scheme = isset($parts['scheme']) ? UriPartsFilter::filterScheme($parts['scheme']) : ''; + $this->user = isset($parts['user']) ? UriPartsFilter::filterUserInfo($parts['user']) : ''; + $this->password = isset($parts['pass']) ? UriPartsFilter::filterUserInfo($parts['pass']) : ''; + $this->host = isset($parts['host']) ? UriPartsFilter::filterHost($parts['host']) : ''; + $this->port = isset($parts['port']) ? UriPartsFilter::filterPort((int)$parts['port']) : null; + $this->path = isset($parts['path']) ? UriPartsFilter::filterPath($parts['path']) : ''; + $this->query = isset($parts['query']) ? UriPartsFilter::filterQueryOrFragment($parts['query']) : ''; + $this->fragment = isset($parts['fragment']) ? UriPartsFilter::filterQueryOrFragment($parts['fragment']) : ''; + + $this->unsetDefaultPort(); + $this->validate(); + } + + /** + * @return void + * @throws InvalidArgumentException + */ + private function validate() + { + if ($this->host === '' && ($this->scheme === 'http' || $this->scheme === 'https')) { + throw new InvalidArgumentException('Uri with a scheme must have a host'); + } + + if ($this->getAuthority() === '') { + if (0 === strpos($this->path, '//')) { + throw new InvalidArgumentException('The path of a URI without an authority must not start with two slashes \'//\''); + } + if ($this->scheme === '' && false !== strpos(explode('/', $this->path, 2)[0], ':')) { + throw new InvalidArgumentException('A relative URI must not have a path beginning with a segment containing a colon'); + } + } elseif (isset($this->path[0]) && $this->path[0] !== '/') { + throw new InvalidArgumentException('The path of a URI with an authority must start with a slash \'/\' or be empty'); + } + } + + /** + * @return bool + */ + protected function isDefaultPort() + { + $scheme = $this->scheme; + $port = $this->port; + + return $this->port === null + || (isset(static::$defaultPorts[$scheme]) && $port === static::$defaultPorts[$scheme]); + } + + /** + * @return void + */ + private function unsetDefaultPort() + { + if ($this->isDefaultPort()) { + $this->port = null; + } + } +} diff --git a/system/src/Grav/Framework/Psr7/Request.php b/system/src/Grav/Framework/Psr7/Request.php new file mode 100644 index 0000000..ced441f --- /dev/null +++ b/system/src/Grav/Framework/Psr7/Request.php @@ -0,0 +1,34 @@ +message = new \Nyholm\Psr7\Request($method, $uri, $headers, $body, $version); + } +} diff --git a/system/src/Grav/Framework/Psr7/Response.php b/system/src/Grav/Framework/Psr7/Response.php new file mode 100644 index 0000000..4126ff8 --- /dev/null +++ b/system/src/Grav/Framework/Psr7/Response.php @@ -0,0 +1,265 @@ +message = new \Nyholm\Psr7\Response($status, $headers, $body, $version, $reason); + } + + /** + * Json. + * + * Note: This method is not part of the PSR-7 standard. + * + * This method prepares the response object to return an HTTP Json + * response to the client. + * + * @param mixed $data The data + * @param int|null $status The HTTP status code. + * @param int $options Json encoding options + * @param int $depth Json encoding max depth + * @return static + * @phpstan-param positive-int $depth + */ + public function withJson($data, int $status = null, int $options = 0, int $depth = 512): ResponseInterface + { + $json = (string) json_encode($data, $options, $depth); + + if (json_last_error() !== JSON_ERROR_NONE) { + throw new RuntimeException(json_last_error_msg(), json_last_error()); + } + + $response = $this->getResponse() + ->withHeader('Content-Type', 'application/json;charset=utf-8') + ->withBody(new Stream($json)); + + if ($status !== null) { + $response = $response->withStatus($status); + } + + $new = clone $this; + $new->message = $response; + + return $new; + } + + /** + * Redirect. + * + * Note: This method is not part of the PSR-7 standard. + * + * This method prepares the response object to return an HTTP Redirect + * response to the client. + * + * @param string $url The redirect destination. + * @param int|null $status The redirect HTTP status code. + * @return static + */ + public function withRedirect(string $url, $status = null): ResponseInterface + { + $response = $this->getResponse()->withHeader('Location', $url); + + if ($status === null) { + $status = 302; + } + + $new = clone $this; + $new->message = $response->withStatus($status); + + return $new; + } + + /** + * Is this response empty? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isEmpty(): bool + { + return in_array($this->getResponse()->getStatusCode(), [204, 205, 304], true); + } + + + /** + * Is this response OK? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isOk(): bool + { + return $this->getResponse()->getStatusCode() === 200; + } + + /** + * Is this response a redirect? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isRedirect(): bool + { + return in_array($this->getResponse()->getStatusCode(), [301, 302, 303, 307, 308], true); + } + + /** + * Is this response forbidden? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + * @api + */ + public function isForbidden(): bool + { + return $this->getResponse()->getStatusCode() === 403; + } + + /** + * Is this response not Found? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isNotFound(): bool + { + return $this->getResponse()->getStatusCode() === 404; + } + + /** + * Is this response informational? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isInformational(): bool + { + $response = $this->getResponse(); + + return $response->getStatusCode() >= 100 && $response->getStatusCode() < 200; + } + + /** + * Is this response successful? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isSuccessful(): bool + { + $response = $this->getResponse(); + + return $response->getStatusCode() >= 200 && $response->getStatusCode() < 300; + } + + /** + * Is this response a redirection? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isRedirection(): bool + { + $response = $this->getResponse(); + + return $response->getStatusCode() >= 300 && $response->getStatusCode() < 400; + } + + /** + * Is this response a client error? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isClientError(): bool + { + $response = $this->getResponse(); + + return $response->getStatusCode() >= 400 && $response->getStatusCode() < 500; + } + + /** + * Is this response a server error? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isServerError(): bool + { + $response = $this->getResponse(); + + return $response->getStatusCode() >= 500 && $response->getStatusCode() < 600; + } + + /** + * Convert response to string. + * + * Note: This method is not part of the PSR-7 standard. + * + * @return string + */ + public function __toString(): string + { + $response = $this->getResponse(); + $output = sprintf( + 'HTTP/%s %s %s%s', + $response->getProtocolVersion(), + $response->getStatusCode(), + $response->getReasonPhrase(), + self::EOL + ); + + foreach ($response->getHeaders() as $name => $values) { + $output .= sprintf('%s: %s', $name, $response->getHeaderLine($name)) . self::EOL; + } + + $output .= self::EOL; + $output .= $response->getBody(); + + return $output; + } +} diff --git a/system/src/Grav/Framework/Psr7/ServerRequest.php b/system/src/Grav/Framework/Psr7/ServerRequest.php new file mode 100644 index 0000000..79f273b --- /dev/null +++ b/system/src/Grav/Framework/Psr7/ServerRequest.php @@ -0,0 +1,364 @@ +message = new \Nyholm\Psr7\ServerRequest($method, $uri, $headers, $body, $version, $serverParams); + } + + /** + * Get serverRequest content character set, if known. + * + * Note: This method is not part of the PSR-7 standard. + * + * @return string|null + */ + public function getContentCharset(): ?string + { + $mediaTypeParams = $this->getMediaTypeParams(); + + if (isset($mediaTypeParams['charset'])) { + return $mediaTypeParams['charset']; + } + + return null; + } + + /** + * Get serverRequest content type. + * + * Note: This method is not part of the PSR-7 standard. + * + * @return string|null The serverRequest content type, if known + */ + public function getContentType(): ?string + { + $result = $this->getRequest()->getHeader('Content-Type'); + + return $result ? $result[0] : null; + } + + /** + * Get serverRequest content length, if known. + * + * Note: This method is not part of the PSR-7 standard. + * + * @return int|null + */ + public function getContentLength(): ?int + { + $result = $this->getRequest()->getHeader('Content-Length'); + + return $result ? (int) $result[0] : null; + } + + /** + * Fetch cookie value from cookies sent by the client to the server. + * + * Note: This method is not part of the PSR-7 standard. + * + * @param string $key The attribute name. + * @param mixed $default Default value to return if the attribute does not exist. + * + * @return mixed + */ + public function getCookieParam($key, $default = null) + { + $cookies = $this->getRequest()->getCookieParams(); + + return $cookies[$key] ?? $default; + } + + /** + * Get serverRequest media type, if known. + * + * Note: This method is not part of the PSR-7 standard. + * + * @return string|null The serverRequest media type, minus content-type params + */ + public function getMediaType(): ?string + { + $contentType = $this->getContentType(); + + if ($contentType) { + $contentTypeParts = preg_split('/\s*[;,]\s*/', $contentType); + if ($contentTypeParts === false) { + return null; + } + return strtolower($contentTypeParts[0]); + } + + return null; + } + + /** + * Get serverRequest media type params, if known. + * + * Note: This method is not part of the PSR-7 standard. + * + * @return mixed[] + */ + public function getMediaTypeParams(): array + { + $contentType = $this->getContentType(); + $contentTypeParams = []; + + if ($contentType) { + $contentTypeParts = preg_split('/\s*[;,]\s*/', $contentType); + if ($contentTypeParts !== false) { + $contentTypePartsLength = count($contentTypeParts); + for ($i = 1; $i < $contentTypePartsLength; $i++) { + $paramParts = explode('=', $contentTypeParts[$i]); + $contentTypeParams[strtolower($paramParts[0])] = $paramParts[1]; + } + } + } + + return $contentTypeParams; + } + + /** + * Fetch serverRequest parameter value from body or query string (in that order). + * + * Note: This method is not part of the PSR-7 standard. + * + * @param string $key The parameter key. + * @param string|null $default The default value. + * + * @return mixed The parameter value. + */ + public function getParam($key, $default = null) + { + $postParams = $this->getParsedBody(); + $getParams = $this->getQueryParams(); + $result = $default; + + if (is_array($postParams) && isset($postParams[$key])) { + $result = $postParams[$key]; + } elseif (is_object($postParams) && property_exists($postParams, $key)) { + $result = $postParams->$key; + } elseif (isset($getParams[$key])) { + $result = $getParams[$key]; + } + + return $result; + } + + /** + * Fetch associative array of body and query string parameters. + * + * Note: This method is not part of the PSR-7 standard. + * + * @return mixed[] + */ + public function getParams(): array + { + $params = $this->getQueryParams(); + $postParams = $this->getParsedBody(); + + if ($postParams) { + $params = array_merge($params, (array)$postParams); + } + + return $params; + } + + /** + * Fetch parameter value from serverRequest body. + * + * Note: This method is not part of the PSR-7 standard. + * + * @param string $key + * @param mixed $default + * + * @return mixed + */ + public function getParsedBodyParam($key, $default = null) + { + $postParams = $this->getParsedBody(); + $result = $default; + + if (is_array($postParams) && isset($postParams[$key])) { + $result = $postParams[$key]; + } elseif (is_object($postParams) && property_exists($postParams, $key)) { + $result = $postParams->{$key}; + } + + return $result; + } + + /** + * Fetch parameter value from query string. + * + * Note: This method is not part of the PSR-7 standard. + * + * @param string $key + * @param mixed $default + * + * @return mixed + */ + public function getQueryParam($key, $default = null) + { + $getParams = $this->getQueryParams(); + + return $getParams[$key] ?? $default; + } + + /** + * Retrieve a server parameter. + * + * Note: This method is not part of the PSR-7 standard. + * + * @param string $key + * @param mixed $default + * @return mixed + */ + public function getServerParam($key, $default = null) + { + $serverParams = $this->getRequest()->getServerParams(); + + return $serverParams[$key] ?? $default; + } + + /** + * Does this serverRequest use a given method? + * + * Note: This method is not part of the PSR-7 standard. + * + * @param string $method HTTP method + * @return bool + */ + public function isMethod($method): bool + { + return $this->getRequest()->getMethod() === $method; + } + + /** + * Is this a DELETE serverRequest? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isDelete(): bool + { + return $this->isMethod('DELETE'); + } + + /** + * Is this a GET serverRequest? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isGet(): bool + { + return $this->isMethod('GET'); + } + + /** + * Is this a HEAD serverRequest? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isHead(): bool + { + return $this->isMethod('HEAD'); + } + + /** + * Is this a OPTIONS serverRequest? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isOptions(): bool + { + return $this->isMethod('OPTIONS'); + } + + /** + * Is this a PATCH serverRequest? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isPatch(): bool + { + return $this->isMethod('PATCH'); + } + + /** + * Is this a POST serverRequest? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isPost(): bool + { + return $this->isMethod('POST'); + } + + /** + * Is this a PUT serverRequest? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isPut(): bool + { + return $this->isMethod('PUT'); + } + + /** + * Is this an XHR serverRequest? + * + * Note: This method is not part of the PSR-7 standard. + * + * @return bool + */ + public function isXhr(): bool + { + return $this->getRequest()->getHeaderLine('X-Requested-With') === 'XMLHttpRequest'; + } +} diff --git a/system/src/Grav/Framework/Psr7/Stream.php b/system/src/Grav/Framework/Psr7/Stream.php new file mode 100644 index 0000000..abed632 --- /dev/null +++ b/system/src/Grav/Framework/Psr7/Stream.php @@ -0,0 +1,43 @@ +stream = \Nyholm\Psr7\Stream::create($body); + } +} diff --git a/system/src/Grav/Framework/Psr7/Traits/MessageDecoratorTrait.php b/system/src/Grav/Framework/Psr7/Traits/MessageDecoratorTrait.php new file mode 100644 index 0000000..1eb1d2e --- /dev/null +++ b/system/src/Grav/Framework/Psr7/Traits/MessageDecoratorTrait.php @@ -0,0 +1,140 @@ + + */ +trait MessageDecoratorTrait +{ + /** @var MessageInterface */ + private $message; + + /** + * Returns the decorated message. + * + * Since the underlying Message is immutable as well + * exposing it is not an issue, because it's state cannot be altered + * + * @return MessageInterface + */ + public function getMessage(): MessageInterface + { + return $this->message; + } + + /** + * {@inheritdoc} + */ + public function getProtocolVersion(): string + { + return $this->message->getProtocolVersion(); + } + + /** + * {@inheritdoc} + */ + public function withProtocolVersion($version): self + { + $new = clone $this; + $new->message = $this->message->withProtocolVersion($version); + + return $new; + } + + /** + * {@inheritdoc} + */ + public function getHeaders(): array + { + return $this->message->getHeaders(); + } + + /** + * {@inheritdoc} + */ + public function hasHeader($header): bool + { + return $this->message->hasHeader($header); + } + + /** + * {@inheritdoc} + */ + public function getHeader($header): array + { + return $this->message->getHeader($header); + } + + /** + * {@inheritdoc} + */ + public function getHeaderLine($header): string + { + return $this->message->getHeaderLine($header); + } + + /** + * {@inheritdoc} + */ + public function getBody(): StreamInterface + { + return $this->message->getBody(); + } + + /** + * {@inheritdoc} + */ + public function withHeader($header, $value): self + { + $new = clone $this; + $new->message = $this->message->withHeader($header, $value); + + return $new; + } + + /** + * {@inheritdoc} + */ + public function withAddedHeader($header, $value): self + { + $new = clone $this; + $new->message = $this->message->withAddedHeader($header, $value); + + return $new; + } + + /** + * {@inheritdoc} + */ + public function withoutHeader($header): self + { + $new = clone $this; + $new->message = $this->message->withoutHeader($header); + + return $new; + } + + /** + * {@inheritdoc} + */ + public function withBody(StreamInterface $body): self + { + $new = clone $this; + $new->message = $this->message->withBody($body); + + return $new; + } +} diff --git a/system/src/Grav/Framework/Psr7/Traits/RequestDecoratorTrait.php b/system/src/Grav/Framework/Psr7/Traits/RequestDecoratorTrait.php new file mode 100644 index 0000000..8f97065 --- /dev/null +++ b/system/src/Grav/Framework/Psr7/Traits/RequestDecoratorTrait.php @@ -0,0 +1,112 @@ + + */ +trait RequestDecoratorTrait +{ + use MessageDecoratorTrait { + getMessage as private; + } + + /** + * Returns the decorated request. + * + * Since the underlying Request is immutable as well + * exposing it is not an issue, because it's state cannot be altered + * + * @return RequestInterface + */ + public function getRequest(): RequestInterface + { + /** @var RequestInterface $message */ + $message = $this->getMessage(); + + return $message; + } + + /** + * Exchanges the underlying request with another. + * + * @param RequestInterface $request + * @return self + */ + public function withRequest(RequestInterface $request): self + { + $new = clone $this; + $new->message = $request; + + return $new; + } + + /** + * {@inheritdoc} + */ + public function getRequestTarget(): string + { + return $this->getRequest()->getRequestTarget(); + } + + /** + * {@inheritdoc} + */ + public function withRequestTarget($requestTarget): self + { + $new = clone $this; + $new->message = $this->getRequest()->withRequestTarget($requestTarget); + + return $new; + } + + /** + * {@inheritdoc} + */ + public function getMethod(): string + { + return $this->getRequest()->getMethod(); + } + + /** + * {@inheritdoc} + */ + public function withMethod($method): self + { + $new = clone $this; + $new->message = $this->getRequest()->withMethod($method); + + return $new; + } + + /** + * {@inheritdoc} + */ + public function getUri(): UriInterface + { + return $this->getRequest()->getUri(); + } + + /** + * {@inheritdoc} + */ + public function withUri(UriInterface $uri, $preserveHost = false): self + { + $new = clone $this; + $new->message = $this->getRequest()->withUri($uri, $preserveHost); + + return $new; + } +} diff --git a/system/src/Grav/Framework/Psr7/Traits/ResponseDecoratorTrait.php b/system/src/Grav/Framework/Psr7/Traits/ResponseDecoratorTrait.php new file mode 100644 index 0000000..cb8ec98 --- /dev/null +++ b/system/src/Grav/Framework/Psr7/Traits/ResponseDecoratorTrait.php @@ -0,0 +1,82 @@ + + */ +trait ResponseDecoratorTrait +{ + use MessageDecoratorTrait { + getMessage as private; + } + + /** + * Returns the decorated response. + * + * Since the underlying Response is immutable as well + * exposing it is not an issue, because it's state cannot be altered + * + * @return ResponseInterface + */ + public function getResponse(): ResponseInterface + { + /** @var ResponseInterface $message */ + $message = $this->getMessage(); + + return $message; + } + + /** + * Exchanges the underlying response with another. + * + * @param ResponseInterface $response + * + * @return self + */ + public function withResponse(ResponseInterface $response): self + { + $new = clone $this; + $new->message = $response; + + return $new; + } + + /** + * {@inheritdoc} + */ + public function getStatusCode(): int + { + return $this->getResponse()->getStatusCode(); + } + + /** + * {@inheritdoc} + */ + public function withStatus($code, $reasonPhrase = ''): self + { + $new = clone $this; + $new->message = $this->getResponse()->withStatus($code, $reasonPhrase); + + return $new; + } + + /** + * {@inheritdoc} + */ + public function getReasonPhrase(): string + { + return $this->getResponse()->getReasonPhrase(); + } +} diff --git a/system/src/Grav/Framework/Psr7/Traits/ServerRequestDecoratorTrait.php b/system/src/Grav/Framework/Psr7/Traits/ServerRequestDecoratorTrait.php new file mode 100644 index 0000000..82acc68 --- /dev/null +++ b/system/src/Grav/Framework/Psr7/Traits/ServerRequestDecoratorTrait.php @@ -0,0 +1,176 @@ +getMessage(); + + return $message; + } + + /** + * @inheritdoc + */ + public function getAttribute($name, $default = null) + { + return $this->getRequest()->getAttribute($name, $default); + } + + /** + * @inheritdoc + */ + public function getAttributes() + { + return $this->getRequest()->getAttributes(); + } + + + /** + * @inheritdoc + */ + public function getCookieParams() + { + return $this->getRequest()->getCookieParams(); + } + + /** + * @inheritdoc + */ + public function getParsedBody() + { + return $this->getRequest()->getParsedBody(); + } + + /** + * @inheritdoc + */ + public function getQueryParams() + { + return $this->getRequest()->getQueryParams(); + } + + /** + * @inheritdoc + */ + public function getServerParams() + { + return $this->getRequest()->getServerParams(); + } + + /** + * @inheritdoc + */ + public function getUploadedFiles() + { + return $this->getRequest()->getUploadedFiles(); + } + + /** + * @inheritdoc + */ + public function withAttribute($name, $value) + { + $new = clone $this; + $new->message = $this->getRequest()->withAttribute($name, $value); + + return $new; + } + + /** + * @param array $attributes + * @return ServerRequestInterface + */ + public function withAttributes(array $attributes) + { + $new = clone $this; + foreach ($attributes as $attribute => $value) { + $new->message = $new->withAttribute($attribute, $value); + } + + return $new; + } + + /** + * @inheritdoc + */ + public function withoutAttribute($name) + { + $new = clone $this; + $new->message = $this->getRequest()->withoutAttribute($name); + + return $new; + } + + /** + * @inheritdoc + */ + public function withCookieParams(array $cookies) + { + $new = clone $this; + $new->message = $this->getRequest()->withCookieParams($cookies); + + return $new; + } + + /** + * @inheritdoc + */ + public function withParsedBody($data) + { + $new = clone $this; + $new->message = $this->getRequest()->withParsedBody($data); + + return $new; + } + + /** + * @inheritdoc + */ + public function withQueryParams(array $query) + { + $new = clone $this; + $new->message = $this->getRequest()->withQueryParams($query); + + return $new; + } + + /** + * @inheritdoc + */ + public function withUploadedFiles(array $uploadedFiles) + { + $new = clone $this; + $new->message = $this->getRequest()->withUploadedFiles($uploadedFiles); + + return $new; + } +} diff --git a/system/src/Grav/Framework/Psr7/Traits/StreamDecoratorTrait.php b/system/src/Grav/Framework/Psr7/Traits/StreamDecoratorTrait.php new file mode 100644 index 0000000..a093732 --- /dev/null +++ b/system/src/Grav/Framework/Psr7/Traits/StreamDecoratorTrait.php @@ -0,0 +1,153 @@ +stream->__toString(); + } + + /** + * @return void + */ + #[\ReturnTypeWillChange] + public function __destruct() + { + $this->stream->close(); + } + + /** + * {@inheritdoc} + */ + public function close(): void + { + $this->stream->close(); + } + + /** + * {@inheritdoc} + */ + public function detach() + { + return $this->stream->detach(); + } + + /** + * {@inheritdoc} + */ + public function getSize(): ?int + { + return $this->stream->getSize(); + } + + /** + * {@inheritdoc} + */ + public function tell(): int + { + return $this->stream->tell(); + } + + /** + * {@inheritdoc} + */ + public function eof(): bool + { + return $this->stream->eof(); + } + + /** + * {@inheritdoc} + */ + public function isSeekable(): bool + { + return $this->stream->isSeekable(); + } + + /** + * {@inheritdoc} + */ + public function seek($offset, $whence = \SEEK_SET): void + { + $this->stream->seek($offset, $whence); + } + + /** + * {@inheritdoc} + */ + public function rewind(): void + { + $this->stream->rewind(); + } + + /** + * {@inheritdoc} + */ + public function isWritable(): bool + { + return $this->stream->isWritable(); + } + + /** + * {@inheritdoc} + */ + public function write($string): int + { + return $this->stream->write($string); + } + + /** + * {@inheritdoc} + */ + public function isReadable(): bool + { + return $this->stream->isReadable(); + } + + /** + * {@inheritdoc} + */ + public function read($length): string + { + return $this->stream->read($length); + } + + /** + * {@inheritdoc} + */ + public function getContents(): string + { + return $this->stream->getContents(); + } + + /** + * {@inheritdoc} + */ + public function getMetadata($key = null) + { + return $this->stream->getMetadata($key); + } +} diff --git a/system/src/Grav/Framework/Psr7/Traits/UploadedFileDecoratorTrait.php b/system/src/Grav/Framework/Psr7/Traits/UploadedFileDecoratorTrait.php new file mode 100644 index 0000000..0bd835d --- /dev/null +++ b/system/src/Grav/Framework/Psr7/Traits/UploadedFileDecoratorTrait.php @@ -0,0 +1,73 @@ +uploadedFile->getStream(); + } + + /** + * @param string $targetPath + */ + public function moveTo($targetPath): void + { + $this->uploadedFile->moveTo($targetPath); + } + + /** + * @return int|null + */ + public function getSize(): ?int + { + return $this->uploadedFile->getSize(); + } + + /** + * @return int + */ + public function getError(): int + { + return $this->uploadedFile->getError(); + } + + /** + * @return string|null + */ + public function getClientFilename(): ?string + { + return $this->uploadedFile->getClientFilename(); + } + + /** + * @return string|null + */ + public function getClientMediaType(): ?string + { + return $this->uploadedFile->getClientMediaType(); + } +} diff --git a/system/src/Grav/Framework/Psr7/Traits/UriDecorationTrait.php b/system/src/Grav/Framework/Psr7/Traits/UriDecorationTrait.php new file mode 100644 index 0000000..5e43942 --- /dev/null +++ b/system/src/Grav/Framework/Psr7/Traits/UriDecorationTrait.php @@ -0,0 +1,188 @@ +uri->__toString(); + } + + /** + * @return string + */ + public function getScheme(): string + { + return $this->uri->getScheme(); + } + + /** + * @return string + */ + public function getAuthority(): string + { + return $this->uri->getAuthority(); + } + + /** + * @return string + */ + public function getUserInfo(): string + { + return $this->uri->getUserInfo(); + } + + /** + * @return string + */ + public function getHost(): string + { + return $this->uri->getHost(); + } + + /** + * @return int|null + */ + public function getPort(): ?int + { + return $this->uri->getPort(); + } + + /** + * @return string + */ + public function getPath(): string + { + return $this->uri->getPath(); + } + + /** + * @return string + */ + public function getQuery(): string + { + return $this->uri->getQuery(); + } + + /** + * @return string + */ + public function getFragment(): string + { + return $this->uri->getFragment(); + } + + /** + * @param string $scheme + * @return UriInterface + */ + public function withScheme($scheme): UriInterface + { + $new = clone $this; + $new->uri = $this->uri->withScheme($scheme); + + /** @var UriInterface $new */ + return $new; + } + + /** + * @param string $user + * @param string|null $password + * @return UriInterface + */ + public function withUserInfo($user, $password = null): UriInterface + { + $new = clone $this; + $new->uri = $this->uri->withUserInfo($user, $password); + + /** @var UriInterface $new */ + return $new; + } + + /** + * @param string $host + * @return UriInterface + */ + public function withHost($host): UriInterface + { + $new = clone $this; + $new->uri = $this->uri->withHost($host); + + /** @var UriInterface $new */ + return $new; + } + + /** + * @param int|null $port + * @return UriInterface + */ + public function withPort($port): UriInterface + { + $new = clone $this; + $new->uri = $this->uri->withPort($port); + + /** @var UriInterface $new */ + return $new; + } + + /** + * @param string $path + * @return UriInterface + */ + public function withPath($path): UriInterface + { + $new = clone $this; + $new->uri = $this->uri->withPath($path); + + /** @var UriInterface $new */ + return $new; + } + + /** + * @param string $query + * @return UriInterface + */ + public function withQuery($query): UriInterface + { + $new = clone $this; + $new->uri = $this->uri->withQuery($query); + + /** @var UriInterface $new */ + return $new; + } + + /** + * @param string $fragment + * @return UriInterface + */ + public function withFragment($fragment): UriInterface + { + $new = clone $this; + $new->uri = $this->uri->withFragment($fragment); + + /** @var UriInterface $new */ + return $new; + } +} diff --git a/system/src/Grav/Framework/Psr7/UploadedFile.php b/system/src/Grav/Framework/Psr7/UploadedFile.php new file mode 100644 index 0000000..f7b5fef --- /dev/null +++ b/system/src/Grav/Framework/Psr7/UploadedFile.php @@ -0,0 +1,70 @@ +uploadedFile = new \Nyholm\Psr7\UploadedFile($streamOrFile, $size, $errorStatus, $clientFilename, $clientMediaType); + } + + /** + * @param array $meta + * @return $this + */ + public function setMeta(array $meta) + { + $this->meta = $meta; + + return $this; + } + + /** + * @param array $meta + * @return $this + */ + public function addMeta(array $meta) + { + $this->meta = array_merge($this->meta, $meta); + + return $this; + } + + /** + * @return array + */ + public function getMeta(): array + { + return $this->meta; + } +} diff --git a/system/src/Grav/Framework/Psr7/Uri.php b/system/src/Grav/Framework/Psr7/Uri.php new file mode 100644 index 0000000..2638876 --- /dev/null +++ b/system/src/Grav/Framework/Psr7/Uri.php @@ -0,0 +1,135 @@ +uri = new \Nyholm\Psr7\Uri($uri); + } + + /** + * @return array + */ + public function getQueryParams(): array + { + return UriFactory::parseQuery($this->getQuery()); + } + + /** + * @param array $params + * @return UriInterface + */ + public function withQueryParams(array $params): UriInterface + { + $query = UriFactory::buildQuery($params); + + return $this->withQuery($query); + } + + /** + * Whether the URI has the default port of the current scheme. + * + * `$uri->getPort()` may return the standard port. This method can be used for some non-http/https Uri. + * + * @return bool + */ + public function isDefaultPort(): bool + { + return $this->getPort() === null || GuzzleUri::isDefaultPort($this); + } + + /** + * Whether the URI is absolute, i.e. it has a scheme. + * + * An instance of UriInterface can either be an absolute URI or a relative reference. This method returns true + * if it is the former. An absolute URI has a scheme. A relative reference is used to express a URI relative + * to another URI, the base URI. Relative references can be divided into several forms: + * - network-path references, e.g. '//example.com/path' + * - absolute-path references, e.g. '/path' + * - relative-path references, e.g. 'subpath' + * + * @return bool + * @link https://tools.ietf.org/html/rfc3986#section-4 + */ + public function isAbsolute(): bool + { + return GuzzleUri::isAbsolute($this); + } + + /** + * Whether the URI is a network-path reference. + * + * A relative reference that begins with two slash characters is termed an network-path reference. + * + * @return bool + * @link https://tools.ietf.org/html/rfc3986#section-4.2 + */ + public function isNetworkPathReference(): bool + { + return GuzzleUri::isNetworkPathReference($this); + } + + /** + * Whether the URI is a absolute-path reference. + * + * A relative reference that begins with a single slash character is termed an absolute-path reference. + * + * @return bool + * @link https://tools.ietf.org/html/rfc3986#section-4.2 + */ + public function isAbsolutePathReference(): bool + { + return GuzzleUri::isAbsolutePathReference($this); + } + + /** + * Whether the URI is a relative-path reference. + * + * A relative reference that does not begin with a slash character is termed a relative-path reference. + * + * @return bool + * @link https://tools.ietf.org/html/rfc3986#section-4.2 + */ + public function isRelativePathReference(): bool + { + return GuzzleUri::isRelativePathReference($this); + } + + /** + * Whether the URI is a same-document reference. + * + * A same-document reference refers to a URI that is, aside from its fragment + * component, identical to the base URI. When no base URI is given, only an empty + * URI reference (apart from its fragment) is considered a same-document reference. + * + * @param UriInterface|null $base An optional base URI to compare against + * @return bool + * @link https://tools.ietf.org/html/rfc3986#section-4.4 + */ + public function isSameDocumentReference(UriInterface $base = null): bool + { + return GuzzleUri::isSameDocumentReference($this, $base); + } +} diff --git a/system/src/Grav/Framework/Relationships/Relationships.php b/system/src/Grav/Framework/Relationships/Relationships.php new file mode 100644 index 0000000..6485682 --- /dev/null +++ b/system/src/Grav/Framework/Relationships/Relationships.php @@ -0,0 +1,217 @@ + + */ +class Relationships implements RelationshipsInterface +{ + /** @var P */ + protected $parent; + /** @var array */ + protected $options; + + /** @var RelationshipInterface[] */ + protected $relationships; + + /** + * Relationships constructor. + * @param P $parent + * @param array $options + */ + public function __construct(IdentifierInterface $parent, array $options) + { + $this->parent = $parent; + $this->options = $options; + $this->relationships = []; + } + + /** + * @return bool + * @phpstan-pure + */ + public function isModified(): bool + { + return !empty($this->getModified()); + } + + /** + * @return RelationshipInterface[] + * @phpstan-pure + */ + public function getModified(): array + { + $list = []; + foreach ($this->relationships as $name => $relationship) { + if ($relationship->isModified()) { + $list[$name] = $relationship; + } + } + + return $list; + } + + /** + * @return int + * @phpstan-pure + */ + public function count(): int + { + return count($this->options); + } + + /** + * @param string $offset + * @return bool + * @phpstan-pure + */ + public function offsetExists($offset): bool + { + return isset($this->options[$offset]); + } + + /** + * @param string $offset + * @return RelationshipInterface|null + */ + public function offsetGet($offset): ?RelationshipInterface + { + if (!isset($this->relationships[$offset])) { + $options = $this->options[$offset] ?? null; + if (null === $options) { + return null; + } + + $this->relationships[$offset] = $this->createRelationship($offset, $options); + } + + return $this->relationships[$offset]; + } + + /** + * @param string $offset + * @param mixed $value + * @return never-return + */ + public function offsetSet($offset, $value) + { + throw new RuntimeException('Setting relationship is not supported', 500); + } + + /** + * @param string $offset + * @return never-return + */ + public function offsetUnset($offset) + { + throw new RuntimeException('Removing relationship is not allowed', 500); + } + + /** + * @return RelationshipInterface|null + */ + public function current(): ?RelationshipInterface + { + $name = key($this->options); + if ($name === null) { + return null; + } + + return $this->offsetGet($name); + } + + /** + * @return string + * @phpstan-pure + */ + public function key(): string + { + return key($this->options); + } + + /** + * @return void + * @phpstan-pure + */ + public function next(): void + { + next($this->options); + } + + /** + * @return void + * @phpstan-pure + */ + public function rewind(): void + { + reset($this->options); + } + + /** + * @return bool + * @phpstan-pure + */ + public function valid(): bool + { + return key($this->options) !== null; + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + $list = []; + foreach ($this as $name => $relationship) { + $list[$name] = $relationship->jsonSerialize(); + } + + return $list; + } + + /** + * @param string $name + * @param array $options + * @return ToOneRelationship|ToManyRelationship + */ + private function createRelationship(string $name, array $options): RelationshipInterface + { + $data = null; + + $parent = $this->parent; + if ($parent instanceof FlexIdentifier) { + $object = $parent->getObject(); + if (!method_exists($object, 'initRelationship')) { + throw new RuntimeException(sprintf('Bad relationship %s', $name), 500); + } + + $data = $object->initRelationship($name); + } + + $cardinality = $options['cardinality'] ?? ''; + switch ($cardinality) { + case 'to-one': + $relationship = new ToOneRelationship($parent, $name, $options, $data); + break; + case 'to-many': + $relationship = new ToManyRelationship($parent, $name, $options, $data ?? []); + break; + default: + throw new RuntimeException(sprintf('Bad relationship cardinality %s', $cardinality), 500); + } + + return $relationship; + } +} diff --git a/system/src/Grav/Framework/Relationships/ToManyRelationship.php b/system/src/Grav/Framework/Relationships/ToManyRelationship.php new file mode 100644 index 0000000..3ea501b --- /dev/null +++ b/system/src/Grav/Framework/Relationships/ToManyRelationship.php @@ -0,0 +1,259 @@ + + */ +class ToManyRelationship implements ToManyRelationshipInterface +{ + /** @template-use RelationshipTrait */ + use RelationshipTrait; + use Serializable; + + /** @var IdentifierInterface[] */ + protected $identifiers = []; + + /** + * ToManyRelationship constructor. + * @param string $name + * @param IdentifierInterface $parent + * @param iterable $identifiers + */ + public function __construct(IdentifierInterface $parent, string $name, array $options, iterable $identifiers = []) + { + $this->parent = $parent; + $this->name = $name; + + $this->parseOptions($options); + $this->addIdentifiers($identifiers); + + $this->modified = false; + } + + /** + * @return string + * @phpstan-pure + */ + public function getCardinality(): string + { + return 'to-many'; + } + + /** + * @return int + * @phpstan-pure + */ + public function count(): int + { + return count($this->identifiers); + } + + /** + * @return array + */ + public function fetch(): array + { + $list = []; + foreach ($this->identifiers as $identifier) { + if (is_callable([$identifier, 'getObject'])) { + $identifier = $identifier->getObject(); + } + $list[] = $identifier; + } + + return $list; + } + + /** + * @param string $id + * @param string|null $type + * @return bool + * @phpstan-pure + */ + public function has(string $id, string $type = null): bool + { + return $this->getIdentifier($id, $type) !== null; + } + + /** + * @param positive-int $pos + * @return IdentifierInterface|null + */ + public function getNthIdentifier(int $pos): ?IdentifierInterface + { + $items = array_keys($this->identifiers); + $key = $items[$pos - 1] ?? null; + if (null === $key) { + return null; + } + + return $this->identifiers[$key] ?? null; + } + + /** + * @param string $id + * @param string|null $type + * @return IdentifierInterface|null + * @phpstan-pure + */ + public function getIdentifier(string $id, string $type = null): ?IdentifierInterface + { + if (null === $type) { + $type = $this->getType(); + } + + if ($type === 'media' && !str_contains($id, '/')) { + $name = $this->name; + $id = $this->parent->getType() . '/' . $this->parent->getId() . '/'. $name . '/' . $id; + } + + $key = "{$type}/{$id}"; + + return $this->identifiers[$key] ?? null; + } + + /** + * @param string $id + * @param string|null $type + * @return T|null + */ + public function getObject(string $id, string $type = null): ?object + { + $identifier = $this->getIdentifier($id, $type); + if ($identifier && is_callable([$identifier, 'getObject'])) { + $identifier = $identifier->getObject(); + } + + return $identifier; + } + + /** + * @param IdentifierInterface $identifier + * @return bool + */ + public function addIdentifier(IdentifierInterface $identifier): bool + { + return $this->addIdentifiers([$identifier]); + } + + /** + * @param IdentifierInterface|null $identifier + * @return bool + */ + public function removeIdentifier(IdentifierInterface $identifier = null): bool + { + return !$identifier || $this->removeIdentifiers([$identifier]); + } + + /** + * @param iterable $identifiers + * @return bool + */ + public function addIdentifiers(iterable $identifiers): bool + { + foreach ($identifiers as $identifier) { + $type = $identifier->getType(); + $id = $identifier->getId(); + $key = "{$type}/{$id}"; + + $this->identifiers[$key] = $this->checkIdentifier($identifier); + $this->modified = true; + } + + return true; + } + + /** + * @param iterable $identifiers + * @return bool + */ + public function replaceIdentifiers(iterable $identifiers): bool + { + $this->identifiers = []; + $this->modified = true; + + return $this->addIdentifiers($identifiers); + } + + /** + * @param iterable $identifiers + * @return bool + */ + public function removeIdentifiers(iterable $identifiers): bool + { + foreach ($identifiers as $identifier) { + $type = $identifier->getType(); + $id = $identifier->getId(); + $key = "{$type}/{$id}"; + + unset($this->identifiers[$key]); + $this->modified = true; + } + + return true; + } + + /** + * @return iterable + * @phpstan-pure + */ + public function getIterator(): iterable + { + return new ArrayIterator($this->identifiers); + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + $list = []; + foreach ($this->getIterator() as $item) { + $list[] = $item->jsonSerialize(); + } + + return $list; + } + + /** + * @return array + */ + public function __serialize(): array + { + return [ + 'parent' => $this->parent, + 'name' => $this->name, + 'type' => $this->type, + 'options' => $this->options, + 'modified' => $this->modified, + 'identifiers' => $this->identifiers, + ]; + } + + /** + * @param array $data + * @return void + */ + public function __unserialize(array $data): void + { + $this->parent = $data['parent']; + $this->name = $data['name']; + $this->type = $data['type']; + $this->options = $data['options']; + $this->modified = $data['modified']; + $this->identifiers = $data['identifiers']; + } +} diff --git a/system/src/Grav/Framework/Relationships/ToOneRelationship.php b/system/src/Grav/Framework/Relationships/ToOneRelationship.php new file mode 100644 index 0000000..9b09651 --- /dev/null +++ b/system/src/Grav/Framework/Relationships/ToOneRelationship.php @@ -0,0 +1,207 @@ + + */ +class ToOneRelationship implements ToOneRelationshipInterface +{ + /** @template-use RelationshipTrait */ + use RelationshipTrait; + use Serializable; + + /** @var IdentifierInterface|null */ + protected $identifier = null; + + public function __construct(IdentifierInterface $parent, string $name, array $options, IdentifierInterface $identifier = null) + { + $this->parent = $parent; + $this->name = $name; + + $this->parseOptions($options); + $this->replaceIdentifier($identifier); + + $this->modified = false; + } + + /** + * @return string + * @phpstan-pure + */ + public function getCardinality(): string + { + return 'to-one'; + } + + /** + * @return int + * @phpstan-pure + */ + public function count(): int + { + return $this->identifier ? 1 : 0; + } + + /** + * @return object|null + */ + public function fetch(): ?object + { + $identifier = $this->identifier; + if (is_callable([$identifier, 'getObject'])) { + $identifier = $identifier->getObject(); + } + + return $identifier; + } + + + /** + * @param string|null $id + * @param string|null $type + * @return bool + * @phpstan-pure + */ + public function has(string $id = null, string $type = null): bool + { + return $this->getIdentifier($id, $type) !== null; + } + + /** + * @param string|null $id + * @param string|null $type + * @return IdentifierInterface|null + * @phpstan-pure + */ + public function getIdentifier(string $id = null, string $type = null): ?IdentifierInterface + { + if ($id && $this->getType() === 'media' && !str_contains($id, '/')) { + $name = $this->name; + $id = $this->parent->getType() . '/' . $this->parent->getId() . '/'. $name . '/' . $id; + } + + $identifier = $this->identifier ?? null; + if (null === $identifier || ($type && $type !== $identifier->getType()) || ($id && $id !== $identifier->getId())) { + return null; + } + + return $identifier; + } + + /** + * @param string|null $id + * @param string|null $type + * @return T|null + */ + public function getObject(string $id = null, string $type = null): ?object + { + $identifier = $this->getIdentifier($id, $type); + if ($identifier && is_callable([$identifier, 'getObject'])) { + $identifier = $identifier->getObject(); + } + + return $identifier; + } + + /** + * @param IdentifierInterface $identifier + * @return bool + */ + public function addIdentifier(IdentifierInterface $identifier): bool + { + $this->identifier = $this->checkIdentifier($identifier); + $this->modified = true; + + return true; + } + + /** + * @param IdentifierInterface|null $identifier + * @return bool + */ + public function replaceIdentifier(IdentifierInterface $identifier = null): bool + { + if ($identifier === null) { + $this->identifier = null; + $this->modified = true; + + return true; + } + + return $this->addIdentifier($identifier); + } + + /** + * @param IdentifierInterface|null $identifier + * @return bool + */ + public function removeIdentifier(IdentifierInterface $identifier = null): bool + { + if (null === $identifier || $this->has($identifier->getId(), $identifier->getType())) { + $this->identifier = null; + $this->modified = true; + + return true; + } + + return false; + } + + /** + * @return iterable + * @phpstan-pure + */ + public function getIterator(): iterable + { + return new ArrayIterator((array)$this->identifier); + } + + /** + * @return array|null + */ + public function jsonSerialize(): ?array + { + return $this->identifier ? $this->identifier->jsonSerialize() : null; + } + + /** + * @return array + */ + public function __serialize(): array + { + return [ + 'parent' => $this->parent, + 'name' => $this->name, + 'type' => $this->type, + 'options' => $this->options, + 'modified' => $this->modified, + 'identifier' => $this->identifier, + ]; + } + + /** + * @param array $data + * @return void + */ + public function __unserialize(array $data): void + { + $this->parent = $data['parent']; + $this->name = $data['name']; + $this->type = $data['type']; + $this->options = $data['options']; + $this->modified = $data['modified']; + $this->identifier = $data['identifier']; + } +} diff --git a/system/src/Grav/Framework/Relationships/Traits/RelationshipTrait.php b/system/src/Grav/Framework/Relationships/Traits/RelationshipTrait.php new file mode 100644 index 0000000..dbe146f --- /dev/null +++ b/system/src/Grav/Framework/Relationships/Traits/RelationshipTrait.php @@ -0,0 +1,128 @@ +name; + } + + /** + * @return string + * @phpstan-pure + */ + public function getType(): string + { + return $this->type; + } + + /** + * @return bool + * @phpstan-pure + */ + public function isModified(): bool + { + return $this->modified; + } + + /** + * @return IdentifierInterface + * @phpstan-pure + */ + public function getParent(): IdentifierInterface + { + return $this->parent; + } + + /** + * @param IdentifierInterface $identifier + * @return bool + * @phpstan-pure + */ + public function hasIdentifier(IdentifierInterface $identifier): bool + { + return $this->getIdentifier($identifier->getId(), $identifier->getType()) !== null; + } + + /** + * @return int + * @phpstan-pure + */ + abstract public function count(): int; + + /** + * @return void + * @phpstan-pure + */ + public function check(): void + { + $min = $this->options['min'] ?? 0; + $max = $this->options['max'] ?? 0; + + if ($min || $max) { + $count = $this->count(); + if ($min && $count < $min) { + throw new RuntimeException(sprintf('%s relationship has too few objects in it', $this->name)); + } + if ($max && $count > $max) { + throw new RuntimeException(sprintf('%s relationship has too many objects in it', $this->name)); + } + } + } + + /** + * @param IdentifierInterface $identifier + * @return IdentifierInterface + */ + private function checkIdentifier(IdentifierInterface $identifier): IdentifierInterface + { + if ($this->type !== $identifier->getType()) { + throw new RuntimeException(sprintf('Bad identifier type %s', $identifier->getType())); + } + + if (get_class($identifier) !== Identifier::class) { + return $identifier; + } + + if ($this->type === 'media') { + return new MediaIdentifier($identifier->getId()); + } + + return new FlexIdentifier($identifier->getId(), $identifier->getType()); + } + + private function parseOptions(array $options): void + { + $this->type = $options['type']; + $this->options = $options; + } +} diff --git a/system/src/Grav/Framework/RequestHandler/Exception/InvalidArgumentException.php b/system/src/Grav/Framework/RequestHandler/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..e6d084b --- /dev/null +++ b/system/src/Grav/Framework/RequestHandler/Exception/InvalidArgumentException.php @@ -0,0 +1,49 @@ +invalidMiddleware = $invalidMiddleware; + } + + /** + * Return the invalid middleware + * + * @return mixed|null + */ + public function getInvalidMiddleware() + { + return $this->invalidMiddleware; + } +} diff --git a/system/src/Grav/Framework/RequestHandler/Exception/NotFoundException.php b/system/src/Grav/Framework/RequestHandler/Exception/NotFoundException.php new file mode 100644 index 0000000..9d6a55a --- /dev/null +++ b/system/src/Grav/Framework/RequestHandler/Exception/NotFoundException.php @@ -0,0 +1,37 @@ +getMethod()), ['PUT', 'PATCH', 'DELETE'])) { + parent::__construct($request, 'Method Not Allowed', 405, $previous); + } else { + parent::__construct($request, 'Not Found', 404, $previous); + } + } +} diff --git a/system/src/Grav/Framework/RequestHandler/Exception/NotHandledException.php b/system/src/Grav/Framework/RequestHandler/Exception/NotHandledException.php new file mode 100644 index 0000000..9183638 --- /dev/null +++ b/system/src/Grav/Framework/RequestHandler/Exception/NotHandledException.php @@ -0,0 +1,20 @@ + 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Time-out', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Large', + 415 => 'Unsupported Media Type', + 416 => 'Requested range not satisfiable', + 417 => 'Expectation Failed', + 418 => 'I\'m a teapot', + 419 => 'Page Expired', + 422 => 'Unprocessable Entity', + 423 => 'Locked', + 424 => 'Failed Dependency', + 425 => 'Unordered Collection', + 426 => 'Upgrade Required', + 428 => 'Precondition Required', + 429 => 'Too Many Requests', + 431 => 'Request Header Fields Too Large', + 451 => 'Unavailable For Legal Reasons', + + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Time-out', + 505 => 'HTTP Version not supported', + 506 => 'Variant Also Negotiates', + 507 => 'Insufficient Storage', + 508 => 'Loop Detected', + 511 => 'Network Authentication Required', + ]; + + /** @var ServerRequestInterface */ + private $request; + + /** + * @param ServerRequestInterface $request + * @param string $message + * @param int $code + * @param Throwable|null $previous + */ + public function __construct(ServerRequestInterface $request, string $message, int $code = 500, Throwable $previous = null) + { + $this->request = $request; + + parent::__construct($message, $code, $previous); + } + + /** + * @return ServerRequestInterface + */ + public function getRequest(): ServerRequestInterface + { + return $this->request; + } + + public function getHttpCode(): int + { + $code = $this->getCode(); + + return isset(self::$phrases[$code]) ? $code : 500; + } + + public function getHttpReason(): ?string + { + return self::$phrases[$this->getCode()] ?? self::$phrases[500]; + } +} diff --git a/system/src/Grav/Framework/RequestHandler/Middlewares/Exceptions.php b/system/src/Grav/Framework/RequestHandler/Middlewares/Exceptions.php new file mode 100644 index 0000000..80deef0 --- /dev/null +++ b/system/src/Grav/Framework/RequestHandler/Middlewares/Exceptions.php @@ -0,0 +1,78 @@ +handle($request); + } catch (Throwable $exception) { + $code = $exception->getCode(); + if ($exception instanceof ValidationException) { + $message = $exception->getMessage(); + } else { + $message = htmlspecialchars($exception->getMessage(), ENT_QUOTES | ENT_HTML5, 'UTF-8'); + } + + $extra = $exception instanceof JsonSerializable ? $exception->jsonSerialize() : []; + + $response = [ + 'code' => $code, + 'status' => 'error', + 'message' => $message, + 'error' => [ + 'code' => $code, + 'message' => $message, + ] + $extra + ]; + + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + if ($debugger->enabled()) { + $response['error'] += [ + 'type' => get_class($exception), + 'file' => $exception->getFile(), + 'line' => $exception->getLine(), + 'trace' => explode("\n", $exception->getTraceAsString()), + ]; + } + + /** @var string $json */ + $json = json_encode($response, JSON_THROW_ON_ERROR); + + return new Response($code ?: 500, ['Content-Type' => 'application/json'], $json); + } + } +} diff --git a/system/src/Grav/Framework/RequestHandler/Middlewares/MultipartRequestSupport.php b/system/src/Grav/Framework/RequestHandler/Middlewares/MultipartRequestSupport.php new file mode 100644 index 0000000..6e36e8f --- /dev/null +++ b/system/src/Grav/Framework/RequestHandler/Middlewares/MultipartRequestSupport.php @@ -0,0 +1,123 @@ +getHeaderLine('content-type'); + $method = $request->getMethod(); + if (!str_starts_with($contentType, 'multipart/form-data') || !in_array($method, ['PUT', 'PATH'], true)) { + return $handler->handle($request); + } + + $boundary = explode('; boundary=', $contentType, 2)[1] ?? ''; + $parts = explode("--{$boundary}", $request->getBody()->getContents()); + $parts = array_slice($parts, 1, count($parts) - 2); + + $params = []; + $files = []; + foreach ($parts as $part) { + $this->processPart($params, $files, $part); + } + + return $handler->handle($request->withParsedBody($params)->withUploadedFiles($files)); + } + + /** + * @param array $params + * @param array $files + * @param string $part + * @return void + */ + protected function processPart(array &$params, array &$files, string $part): void + { + $part = ltrim($part, "\r\n"); + [$rawHeaders, $body] = explode("\r\n\r\n", $part, 2); + + // Parse headers. + $rawHeaders = explode("\r\n", $rawHeaders); + $headers = array_reduce( + $rawHeaders, + static function (array $headers, $header) { + [$name, $value] = explode(':', $header); + $headers[strtolower($name)] = ltrim($value, ' '); + + return $headers; + }, + [] + ); + + if (!isset($headers['content-disposition'])) { + return; + } + + // Parse content disposition header. + $contentDisposition = $headers['content-disposition']; + preg_match('/^(.+); *name="([^"]+)"(; *filename="([^"]+)")?/', $contentDisposition, $matches); + $name = $matches[2]; + $filename = $matches[4] ?? null; + + if ($filename !== null) { + $stream = Stream::create($body); + $this->addFile($files, $name, new UploadedFile($stream, strlen($body), UPLOAD_ERR_OK, $filename, $headers['content-type'] ?? null)); + } elseif (strpos($contentDisposition, 'filename') !== false) { + // Not uploaded file. + $stream = Stream::create(''); + $this->addFile($files, $name, new UploadedFile($stream, 0, UPLOAD_ERR_NO_FILE)); + } else { + // Regular field. + $params[$name] = substr($body, 0, -2); + } + } + + /** + * @param array $files + * @param string $name + * @param UploadedFileInterface $file + * @return void + */ + protected function addFile(array &$files, string $name, UploadedFileInterface $file): void + { + if (strpos($name, '[]') === strlen($name) - 2) { + $name = substr($name, 0, -2); + + if (isset($files[$name]) && is_array($files[$name])) { + $files[$name][] = $file; + } else { + $files[$name] = [$file]; + } + } else { + $files[$name] = $file; + } + } +} diff --git a/system/src/Grav/Framework/RequestHandler/RequestHandler.php b/system/src/Grav/Framework/RequestHandler/RequestHandler.php new file mode 100644 index 0000000..44fb7f9 --- /dev/null +++ b/system/src/Grav/Framework/RequestHandler/RequestHandler.php @@ -0,0 +1,80 @@ +middleware = $middleware; + $this->handler = $default; + $this->container = $container; + } + + /** + * Add callable initializing Middleware that will be executed as soon as possible. + * + * @param string $name + * @param callable $callable + * @return $this + */ + public function addCallable(string $name, callable $callable): self + { + if (null !== $this->container) { + assert($this->container instanceof Container); + $this->container[$name] = $callable; + } + + array_unshift($this->middleware, $name); + + return $this; + } + + /** + * Add Middleware that will be executed as soon as possible. + * + * @param string $name + * @param MiddlewareInterface $middleware + * @return $this + */ + public function addMiddleware(string $name, MiddlewareInterface $middleware): self + { + if (null !== $this->container) { + assert($this->container instanceof Container); + $this->container[$name] = $middleware; + } + + array_unshift($this->middleware, $name); + + return $this; + } +} diff --git a/system/src/Grav/Framework/RequestHandler/Traits/RequestHandlerTrait.php b/system/src/Grav/Framework/RequestHandler/Traits/RequestHandlerTrait.php new file mode 100644 index 0000000..b9d1cba --- /dev/null +++ b/system/src/Grav/Framework/RequestHandler/Traits/RequestHandlerTrait.php @@ -0,0 +1,64 @@ + */ + protected $middleware; + + /** @var callable */ + protected $handler; + + /** @var ContainerInterface|null */ + protected $container; + + /** + * {@inheritdoc} + * @throws InvalidArgumentException + */ + public function handle(ServerRequestInterface $request): ResponseInterface + { + $middleware = array_shift($this->middleware); + + // Use default callable if there is no middleware. + if ($middleware === null) { + return call_user_func($this->handler, $request); + } + + if ($middleware instanceof MiddlewareInterface) { + return $middleware->process($request, clone $this); + } + + if (null === $this->container || !$this->container->has($middleware)) { + throw new InvalidArgumentException( + sprintf('The middleware is not a valid %s and is not passed in the Container', MiddlewareInterface::class), + $middleware + ); + } + + array_unshift($this->middleware, $this->container->get($middleware)); + + return $this->handle($request); + } +} diff --git a/system/src/Grav/Framework/Route/Route.php b/system/src/Grav/Framework/Route/Route.php new file mode 100644 index 0000000..c65a827 --- /dev/null +++ b/system/src/Grav/Framework/Route/Route.php @@ -0,0 +1,452 @@ +initParts($parts); + } + + /** + * @return array + */ + public function getParts() + { + return [ + 'path' => $this->getUriPath(true), + 'query' => $this->getUriQuery(), + 'grav' => [ + 'root' => $this->root, + 'language' => $this->language, + 'route' => $this->route, + 'extension' => $this->extension, + 'grav_params' => $this->gravParams, + 'query_params' => $this->queryParams, + ], + ]; + } + + /** + * @return string + */ + public function getRootPrefix() + { + return $this->root; + } + + /** + * @return string + */ + public function getLanguage() + { + return $this->language; + } + + /** + * @return string + */ + public function getLanguagePrefix() + { + return $this->language !== '' ? '/' . $this->language : ''; + } + + /** + * @param string|null $language + * @return string + */ + public function getBase(string $language = null): string + { + $parts = [$this->root]; + + if (null === $language) { + $language = $this->language; + } + + if ($language !== '') { + $parts[] = $language; + } + + return implode('/', $parts); + } + + /** + * @param int $offset + * @param int|null $length + * @return string + */ + public function getRoute($offset = 0, $length = null) + { + if ($offset !== 0 || $length !== null) { + return ($offset === 0 ? '/' : '') . implode('/', $this->getRouteParts($offset, $length)); + } + + return '/' . $this->route; + } + + /** + * @return string + */ + public function getExtension() + { + return $this->extension; + } + + /** + * @param int $offset + * @param int|null $length + * @return array + */ + public function getRouteParts($offset = 0, $length = null) + { + $parts = explode('/', $this->route); + + if ($offset !== 0 || $length !== null) { + $parts = array_slice($parts, $offset, $length); + } + + return $parts; + } + + /** + * Return array of both query and Grav parameters. + * + * If a parameter exists in both, prefer Grav parameter. + * + * @return array + */ + public function getParams() + { + return $this->gravParams + $this->queryParams; + } + + /** + * @return array + */ + public function getGravParams() + { + return $this->gravParams; + } + + /** + * @return array + */ + public function getQueryParams() + { + return $this->queryParams; + } + + /** + * Return value of the parameter, looking into both Grav parameters and query parameters. + * + * If the parameter exists in both, return Grav parameter. + * + * @param string $param + * @return string|array|null + */ + public function getParam($param) + { + return $this->getGravParam($param) ?? $this->getQueryParam($param); + } + + /** + * @param string $param + * @return string|null + */ + public function getGravParam($param) + { + return $this->gravParams[$param] ?? null; + } + + /** + * @param string $param + * @return string|array|null + */ + public function getQueryParam($param) + { + return $this->queryParams[$param] ?? null; + } + + /** + * Allow the ability to set the route to something else + * + * @param string $route + * @return Route + */ + public function withRoute($route) + { + $new = $this->copy(); + $new->route = $route; + + return $new; + } + + /** + * Allow the ability to set the root to something else + * + * @param string $root + * @return Route + */ + public function withRoot($root) + { + $new = $this->copy(); + $new->root = $root; + + return $new; + } + + /** + * @param string|null $language + * @return Route + */ + public function withLanguage($language) + { + $new = $this->copy(); + $new->language = $language ?? ''; + + return $new; + } + + /** + * @param string $path + * @return Route + */ + public function withAddedPath($path) + { + $new = $this->copy(); + $new->route .= '/' . ltrim($path, '/'); + + return $new; + } + + /** + * @param string $extension + * @return Route + */ + public function withExtension($extension) + { + $new = $this->copy(); + $new->extension = $extension; + + return $new; + } + + /** + * @param string $param + * @param mixed $value + * @return Route + */ + public function withGravParam($param, $value) + { + return $this->withParam('gravParams', $param, null !== $value ? (string)$value : null); + } + + /** + * @param string $param + * @param mixed $value + * @return Route + */ + public function withQueryParam($param, $value) + { + return $this->withParam('queryParams', $param, $value); + } + + /** + * @return Route + */ + public function withoutParams() + { + return $this->withoutGravParams()->withoutQueryParams(); + } + + /** + * @return Route + */ + public function withoutGravParams() + { + $new = $this->copy(); + $new->gravParams = []; + + return $new; + } + + /** + * @return Route + */ + public function withoutQueryParams() + { + $new = $this->copy(); + $new->queryParams = []; + + return $new; + } + + /** + * @return Uri + */ + public function getUri() + { + return UriFactory::createFromParts($this->getParts()); + } + + /** + * @param bool $includeRoot + * @return string + */ + public function toString(bool $includeRoot = false) + { + $url = $this->getUriPath($includeRoot); + + if ($this->queryParams) { + $url .= '?' . $this->getUriQuery(); + } + + return rtrim($url,'/'); + } + + /** + * @return string + * @deprecated 1.6 Use ->toString(true) or ->getUri() instead. + */ + #[\ReturnTypeWillChange] + public function __toString() + { + user_error(__CLASS__ . '::' . __FUNCTION__ . '() will change in the future to return route, not relative url: use ->toString(true) or ->getUri() instead.', E_USER_DEPRECATED); + + return $this->toString(true); + } + + /** + * @param string $type + * @param string $param + * @param mixed $value + * @return Route + */ + protected function withParam($type, $param, $value) + { + $values = $this->{$type} ?? []; + $oldValue = $values[$param] ?? null; + + if ($oldValue === $value) { + return $this; + } + + $new = $this->copy(); + if ($value === null) { + unset($values[$param]); + } else { + $values[$param] = $value; + } + + $new->{$type} = $values; + + return $new; + } + + /** + * @return Route + */ + protected function copy() + { + return clone $this; + } + + /** + * @param bool $includeRoot + * @return string + */ + protected function getUriPath($includeRoot = false) + { + $parts = $includeRoot ? [$this->root] : ['']; + + if ($this->language !== '') { + $parts[] = $this->language; + } + + $parts[] = $this->extension ? $this->route . '.' . $this->extension : $this->route; + + + if ($this->gravParams) { + $parts[] = RouteFactory::buildParams($this->gravParams); + } + + return implode('/', $parts); + } + + /** + * @return string + */ + protected function getUriQuery() + { + return UriFactory::buildQuery($this->queryParams); + } + + /** + * @param array $parts + * @return void + */ + protected function initParts(array $parts) + { + if (isset($parts['grav'])) { + $gravParts = $parts['grav']; + $this->root = $gravParts['root']; + $this->language = $gravParts['language']; + $this->route = $gravParts['route']; + $this->extension = $gravParts['extension'] ?? ''; + $this->gravParams = $gravParts['params'] ?? []; + $this->queryParams = $parts['query_params'] ?? []; + } else { + $this->root = RouteFactory::getRoot(); + $this->language = RouteFactory::getLanguage(); + + $path = $parts['path'] ?? '/'; + if (isset($parts['params'])) { + $this->route = trim(rawurldecode($path), '/'); + $this->gravParams = $parts['params']; + } else { + $this->route = trim(RouteFactory::stripParams($path, true), '/'); + $this->gravParams = RouteFactory::getParams($path); + } + if (isset($parts['query'])) { + $this->queryParams = UriFactory::parseQuery($parts['query']); + } + } + } +} diff --git a/system/src/Grav/Framework/Route/RouteFactory.php b/system/src/Grav/Framework/Route/RouteFactory.php new file mode 100644 index 0000000..6844e48 --- /dev/null +++ b/system/src/Grav/Framework/Route/RouteFactory.php @@ -0,0 +1,236 @@ +toArray(); + $parts += [ + 'grav' => [] + ]; + $path = $parts['path'] ?? ''; + $parts['grav'] += [ + 'root' => self::$root, + 'language' => self::$language, + 'route' => trim($path, '/'), + 'params' => $parts['params'] ?? [], + ]; + + return static::createFromParts($parts); + } + + /** + * @param string $path + * @return Route + */ + public static function createFromString(string $path): Route + { + $path = ltrim($path, '/'); + if (self::$language && mb_strpos($path, self::$language) === 0) { + $path = ltrim(mb_substr($path, mb_strlen(self::$language)), '/'); + } + + $parts = [ + 'path' => $path, + 'query' => '', + 'query_params' => [], + 'grav' => [ + 'root' => self::$root, + 'language' => self::$language, + 'route' => static::trimParams($path), + 'params' => static::getParams($path) + ], + ]; + + return new Route($parts); + } + + /** + * @return string + */ + public static function getRoot(): string + { + return self::$root; + } + + /** + * @param string $root + */ + public static function setRoot($root): void + { + self::$root = rtrim($root, '/'); + } + + /** + * @return string + */ + public static function getLanguage(): string + { + return self::$language; + } + + /** + * @param string $language + */ + public static function setLanguage(string $language): void + { + self::$language = trim($language, '/'); + } + + /** + * @return string + */ + public static function getParamValueDelimiter(): string + { + return self::$delimiter; + } + + /** + * @param string $delimiter + */ + public static function setParamValueDelimiter(string $delimiter): void + { + self::$delimiter = $delimiter ?: ':'; + } + + /** + * @param array $params + * @return string + */ + public static function buildParams(array $params): string + { + if (!$params) { + return ''; + } + + $delimiter = self::$delimiter; + + $output = []; + foreach ($params as $key => $value) { + $output[] = "{$key}{$delimiter}{$value}"; + } + + return implode('/', $output); + } + + /** + * @param string $path + * @param bool $decode + * @return string + */ + public static function stripParams(string $path, bool $decode = false): string + { + $pos = strpos($path, self::$delimiter); + + if ($pos === false) { + return $path; + } + + $path = dirname(substr($path, 0, $pos)); + if ($path === '.') { + return ''; + } + + return $decode ? rawurldecode($path) : $path; + } + + /** + * @param string $path + * @return array + */ + public static function getParams(string $path): array + { + $params = ltrim(substr($path, strlen(static::stripParams($path))), '/'); + + return $params !== '' ? static::parseParams($params) : []; + } + + /** + * @param string $str + * @return string + */ + public static function trimParams(string $str): string + { + if ($str === '') { + return $str; + } + + $delimiter = self::$delimiter; + + /** @var array $params */ + $params = explode('/', $str); + $list = []; + foreach ($params as $param) { + if (mb_strpos($param, $delimiter) === false) { + $list[] = $param; + } + } + + return implode('/', $list); + } + + /** + * @param string $str + * @return array + */ + public static function parseParams(string $str): array + { + if ($str === '') { + return []; + } + + $delimiter = self::$delimiter; + + /** @var array $params */ + $params = explode('/', $str); + $list = []; + foreach ($params as &$param) { + /** @var array $parts */ + $parts = explode($delimiter, $param, 2); + if (isset($parts[1])) { + $var = rawurldecode($parts[0]); + $val = rawurldecode($parts[1]); + $list[$var] = $val; + } + } + + return $list; + } +} diff --git a/system/src/Grav/Framework/Session/Exceptions/SessionException.php b/system/src/Grav/Framework/Session/Exceptions/SessionException.php new file mode 100644 index 0000000..7bcb97f --- /dev/null +++ b/system/src/Grav/Framework/Session/Exceptions/SessionException.php @@ -0,0 +1,20 @@ + $message, 'scope' => $scope]; + + // don't add duplicates + if (!array_key_exists($key, $this->messages)) { + $this->messages[$key] = $item; + } + + return $this; + } + + /** + * Clear message queue. + * + * @param string|null $scope + * @return $this + */ + public function clear(string $scope = null): Messages + { + if ($scope === null) { + if ($this->messages !== []) { + $this->isCleared = true; + $this->messages = []; + } + } else { + foreach ($this->messages as $key => $message) { + if ($message['scope'] === $scope) { + $this->isCleared = true; + unset($this->messages[$key]); + } + } + } + + return $this; + } + + /** + * @return bool + */ + public function isCleared(): bool + { + return $this->isCleared; + } + + /** + * Fetch all messages. + * + * @param string|null $scope + * @return array + */ + public function all(string $scope = null): array + { + if ($scope === null) { + return array_values($this->messages); + } + + $messages = []; + foreach ($this->messages as $message) { + if ($message['scope'] === $scope) { + $messages[] = $message; + } + } + + return $messages; + } + + /** + * Fetch and clear message queue. + * + * @param string|null $scope + * @return array + */ + public function fetch(string $scope = null): array + { + $messages = $this->all($scope); + $this->clear($scope); + + return $messages; + } + + /** + * @return array + */ + public function __serialize(): array + { + return [ + 'messages' => $this->messages + ]; + } + + /** + * @param array $data + * @return void + */ + public function __unserialize(array $data): void + { + $this->messages = $data['messages']; + } +} diff --git a/system/src/Grav/Framework/Session/Session.php b/system/src/Grav/Framework/Session/Session.php new file mode 100644 index 0000000..e30b03b --- /dev/null +++ b/system/src/Grav/Framework/Session/Session.php @@ -0,0 +1,562 @@ +isSessionStarted()) { + session_unset(); + session_destroy(); + } + + // Set default options. + $options += [ + 'cache_limiter' => 'nocache', + 'use_trans_sid' => 0, + 'use_cookies' => 1, + 'lazy_write' => 1, + 'use_strict_mode' => 1 + ]; + + $this->setOptions($options); + + session_register_shutdown(); + + self::$instance = $this; + } + + /** + * @inheritdoc + */ + public function getId() + { + return session_id() ?: null; + } + + /** + * @inheritdoc + */ + public function setId($id) + { + session_id($id); + + return $this; + } + + /** + * @inheritdoc + */ + public function getName() + { + return session_name() ?: null; + } + + /** + * @inheritdoc + */ + public function setName($name) + { + session_name($name); + + return $this; + } + + /** + * @inheritdoc + */ + public function setOptions(array $options) + { + if (headers_sent() || \PHP_SESSION_ACTIVE === session_status()) { + return; + } + + $allowedOptions = [ + 'save_path' => true, + 'name' => true, + 'save_handler' => true, + 'gc_probability' => true, + 'gc_divisor' => true, + 'gc_maxlifetime' => true, + 'serialize_handler' => true, + 'cookie_lifetime' => true, + 'cookie_path' => true, + 'cookie_domain' => true, + 'cookie_secure' => true, + 'cookie_httponly' => true, + 'use_strict_mode' => true, + 'use_cookies' => true, + 'use_only_cookies' => true, + 'cookie_samesite' => true, + 'referer_check' => true, + 'cache_limiter' => true, + 'cache_expire' => true, + 'use_trans_sid' => true, + 'trans_sid_tags' => true, + 'trans_sid_hosts' => true, + 'sid_length' => true, + 'sid_bits_per_character' => true, + 'upload_progress.enabled' => true, + 'upload_progress.cleanup' => true, + 'upload_progress.prefix' => true, + 'upload_progress.name' => true, + 'upload_progress.freq' => true, + 'upload_progress.min-freq' => true, + 'lazy_write' => true + ]; + + foreach ($options as $key => $value) { + if (is_array($value)) { + // Allow nested options. + foreach ($value as $key2 => $value2) { + $ckey = "{$key}.{$key2}"; + if (isset($value2, $allowedOptions[$ckey])) { + $this->setOption($ckey, $value2); + } + } + } elseif (isset($value, $allowedOptions[$key])) { + $this->setOption($key, $value); + } + } + } + + /** + * @inheritdoc + */ + public function start($readonly = false) + { + if (\PHP_SAPI === 'cli') { + return $this; + } + + $sessionName = $this->getName(); + if (null === $sessionName) { + return $this; + } + + $sessionExists = isset($_COOKIE[$sessionName]); + + // Protection against invalid session cookie names throwing exception: http://php.net/manual/en/function.session-id.php#116836 + if ($sessionExists && !preg_match('/^[-,a-zA-Z0-9]{1,128}$/', $_COOKIE[$sessionName])) { + unset($_COOKIE[$sessionName]); + $sessionExists = false; + } + + $options = $this->options; + if ($readonly) { + $options['read_and_close'] = '1'; + } + + try { + $success = @session_start($options); + if (!$success) { + $last = error_get_last(); + $error = $last ? $last['message'] : 'Unknown error'; + + throw new RuntimeException($error); + } + + // Handle changing session id. + if ($this->__isset('session_destroyed')) { + $newId = $this->__get('session_new_id'); + if (!$newId || $this->__get('session_destroyed') < time() - 300) { + // Should not happen usually. This could be attack or due to unstable network. Destroy this session. + $this->invalidate(); + + throw new RuntimeException('Obsolete session access.', 500); + } + + // Not fully expired yet. Could be lost cookie by unstable network. Start session with new session id. + session_write_close(); + + // Start session with new session id. + $useStrictMode = $options['use_strict_mode'] ?? 0; + if ($useStrictMode) { + ini_set('session.use_strict_mode', '0'); + } + session_id($newId); + if ($useStrictMode) { + ini_set('session.use_strict_mode', '1'); + } + + $success = @session_start($options); + if (!$success) { + $last = error_get_last(); + $error = $last ? $last['message'] : 'Unknown error'; + + throw new RuntimeException($error); + } + } + } catch (Exception $e) { + throw new SessionException('Failed to start session: ' . $e->getMessage(), 500); + } + + $this->started = true; + $this->onSessionStart(); + + try { + $user = $this->__get('user'); + if ($user && (!$user instanceof UserInterface || (method_exists($user, 'isValid') && !$user->isValid()))) { + throw new RuntimeException('Bad user'); + } + } catch (Throwable $e) { + $this->invalidate(); + throw new SessionException('Invalid User object, session destroyed.', 500); + } + + + // Extend the lifetime of the session. + if ($sessionExists) { + $this->setCookie(); + } + + return $this; + } + + /** + * Regenerate session id but keep the current session information. + * + * Session id must be regenerated on login, logout or after long time has been passed. + * + * @return $this + * @since 1.7 + */ + public function regenerateId() + { + if (!$this->isSessionStarted()) { + return $this; + } + + // TODO: session_create_id() segfaults in PHP 7.3 (PHP bug #73461), remove phpstan rule when removing this one. + if (PHP_VERSION_ID < 70400) { + $newId = 0; + } else { + // Session id creation may fail with some session storages. + $newId = @session_create_id() ?: 0; + } + + // Set destroyed timestamp for the old session as well as pointer to the new id. + $this->__set('session_destroyed', time()); + $this->__set('session_new_id', $newId); + + // Keep the old session alive to avoid lost sessions by unstable network. + if (!$newId) { + /** @var Debugger $debugger */ + $debugger = Grav::instance()['debugger']; + $debugger->addMessage('Session fixation lost session detection is turned of due to server limitations.', 'warning'); + + session_regenerate_id(false); + } else { + session_write_close(); + + // Start session with new session id. + $useStrictMode = $this->options['use_strict_mode'] ?? 0; + if ($useStrictMode) { + ini_set('session.use_strict_mode', '0'); + } + session_id($newId); + if ($useStrictMode) { + ini_set('session.use_strict_mode', '1'); + } + + $this->removeCookie(); + + $this->onBeforeSessionStart(); + + $success = @session_start($this->options); + if (!$success) { + $last = error_get_last(); + $error = $last ? $last['message'] : 'Unknown error'; + + throw new RuntimeException($error); + } + + $this->onSessionStart(); + } + + // New session does not have these. + $this->__unset('session_destroyed'); + $this->__unset('session_new_id'); + + return $this; + } + + /** + * @inheritdoc + */ + public function invalidate() + { + $name = $this->getName(); + if (null !== $name) { + $this->removeCookie(); + + setcookie( + $name, + '', + $this->getCookieOptions(-42000) + ); + } + + if ($this->isSessionStarted()) { + session_unset(); + session_destroy(); + } + + $this->started = false; + + return $this; + } + + /** + * @inheritdoc + */ + public function close() + { + if ($this->started) { + session_write_close(); + } + + $this->started = false; + + return $this; + } + + /** + * @inheritdoc + */ + public function clear() + { + session_unset(); + + return $this; + } + + /** + * @inheritdoc + */ + public function getAll() + { + return $_SESSION; + } + + /** + * @inheritdoc + */ + #[\ReturnTypeWillChange] + public function getIterator() + { + return new ArrayIterator($_SESSION); + } + + /** + * @inheritdoc + */ + public function isStarted() + { + return $this->started; + } + + /** + * @inheritdoc + */ + #[\ReturnTypeWillChange] + public function __isset($name) + { + return isset($_SESSION[$name]); + } + + /** + * @inheritdoc + */ + #[\ReturnTypeWillChange] + public function __get($name) + { + return $_SESSION[$name] ?? null; + } + + /** + * @inheritdoc + */ + #[\ReturnTypeWillChange] + public function __set($name, $value) + { + $_SESSION[$name] = $value; + } + + /** + * @inheritdoc + */ + #[\ReturnTypeWillChange] + public function __unset($name) + { + unset($_SESSION[$name]); + } + + /** + * http://php.net/manual/en/function.session-status.php#113468 + * Check if session is started nicely. + * @return bool + */ + protected function isSessionStarted() + { + return \PHP_SAPI !== 'cli' ? \PHP_SESSION_ACTIVE === session_status() : false; + } + + protected function onBeforeSessionStart(): void + { + } + + protected function onSessionStart(): void + { + } + + /** + * Store something in cookie temporarily. + * + * @param int|null $lifetime + * @return array + */ + public function getCookieOptions(int $lifetime = null): array + { + $params = session_get_cookie_params(); + + return [ + 'expires' => time() + ($lifetime ?? $params['lifetime']), + 'path' => $params['path'], + 'domain' => $params['domain'], + 'secure' => $params['secure'], + 'httponly' => $params['httponly'], + 'samesite' => $params['samesite'] + ]; + } + + /** + * @return void + */ + protected function setCookie(): void + { + $this->removeCookie(); + + $sessionName = $this->getName(); + $sessionId = $this->getId(); + if (null === $sessionName || null === $sessionId) { + return; + } + + setcookie( + $sessionName, + $sessionId, + $this->getCookieOptions() + ); + } + + protected function removeCookie(): void + { + $search = " {$this->getName()}="; + $cookies = []; + $found = false; + + foreach (headers_list() as $header) { + // Identify cookie headers + if (strpos($header, 'Set-Cookie:') === 0) { + // Add all but session cookie(s). + if (!str_contains($header, $search)) { + $cookies[] = $header; + } else { + $found = true; + } + } + } + + // Nothing to do. + if (false === $found) { + return; + } + + // Remove all cookies and put back all but session cookie. + header_remove('Set-Cookie'); + foreach($cookies as $cookie) { + header($cookie, false); + } + } + + /** + * @param string $key + * @param mixed $value + * @return void + */ + protected function setOption($key, $value) + { + if (!is_string($value)) { + if (is_bool($value)) { + $value = $value ? '1' : '0'; + } else { + $value = (string)$value; + } + } + + $this->options[$key] = $value; + ini_set("session.{$key}", $value); + } +} diff --git a/system/src/Grav/Framework/Session/SessionInterface.php b/system/src/Grav/Framework/Session/SessionInterface.php new file mode 100644 index 0000000..f160b10 --- /dev/null +++ b/system/src/Grav/Framework/Session/SessionInterface.php @@ -0,0 +1,159 @@ + + */ +interface SessionInterface extends IteratorAggregate +{ + /** + * Get current session instance. + * + * @return Session + * @throws RuntimeException + */ + public static function getInstance(); + + /** + * Get session ID + * + * @return string|null Session ID + */ + public function getId(); + + /** + * Set session ID + * + * @param string $id Session ID + * @return $this + */ + public function setId($id); + + /** + * Get session name + * + * @return string|null + */ + public function getName(); + + /** + * Set session name + * + * @param string $name + * @return $this + */ + public function setName($name); + + /** + * Sets session.* ini variables. + * + * @param array $options + * @return void + * @see http://php.net/session.configuration + */ + public function setOptions(array $options); + + /** + * Starts the session storage + * + * @param bool $readonly + * @return $this + * @throws RuntimeException + */ + public function start($readonly = false); + + /** + * Invalidates the current session. + * + * @return $this + */ + public function invalidate(); + + /** + * Force the session to be saved and closed + * + * @return $this + */ + public function close(); + + /** + * Free all session variables. + * + * @return $this + */ + public function clear(); + + /** + * Returns all session variables. + * + * @return array + */ + public function getAll(); + + /** + * Retrieve an external iterator + * + * @return ArrayIterator Return an ArrayIterator of $_SESSION + * @phpstan-return ArrayIterator + */ + #[\ReturnTypeWillChange] + public function getIterator(); + + /** + * Checks if the session was started. + * + * @return bool + */ + public function isStarted(); + + /** + * Checks if session variable is defined. + * + * @param string $name + * @return bool + */ + #[\ReturnTypeWillChange] + public function __isset($name); + + /** + * Returns session variable. + * + * @param string $name + * @return mixed + */ + #[\ReturnTypeWillChange] + public function __get($name); + + /** + * Sets session variable. + * + * @param string $name + * @param mixed $value + * @return void + */ + #[\ReturnTypeWillChange] + public function __set($name, $value); + + /** + * Removes session variable. + * + * @param string $name + * @return void + */ + #[\ReturnTypeWillChange] + public function __unset($name); +} diff --git a/system/src/Grav/Framework/Uri/Uri.php b/system/src/Grav/Framework/Uri/Uri.php new file mode 100644 index 0000000..d31937c --- /dev/null +++ b/system/src/Grav/Framework/Uri/Uri.php @@ -0,0 +1,216 @@ +initParts($parts); + } + + /** + * @return string + */ + public function getUser() + { + return parent::getUser(); + } + + /** + * @return string + */ + public function getPassword() + { + return parent::getPassword(); + } + + /** + * @return array + */ + public function getParts() + { + return parent::getParts(); + } + + /** + * @return string + */ + public function getUrl() + { + return parent::getUrl(); + } + + /** + * @return string + */ + public function getBaseUrl() + { + return parent::getBaseUrl(); + } + + /** + * @param string $key + * @return string|null + */ + public function getQueryParam($key) + { + $queryParams = $this->getQueryParams(); + + return $queryParams[$key] ?? null; + } + + /** + * @param string $key + * @return UriInterface + */ + public function withoutQueryParam($key) + { + return GuzzleUri::withoutQueryValue($this, $key); + } + + /** + * @param string $key + * @param string|null $value + * @return UriInterface + */ + public function withQueryParam($key, $value) + { + return GuzzleUri::withQueryValue($this, $key, $value); + } + + /** + * @return array + */ + public function getQueryParams() + { + if ($this->queryParams === null) { + $this->queryParams = UriFactory::parseQuery($this->getQuery()); + } + + return $this->queryParams; + } + + /** + * @param array $params + * @return UriInterface + */ + public function withQueryParams(array $params) + { + $query = UriFactory::buildQuery($params); + + return $this->withQuery($query); + } + + /** + * Whether the URI has the default port of the current scheme. + * + * `$uri->getPort()` may return the standard port. This method can be used for some non-http/https Uri. + * + * @return bool + */ + public function isDefaultPort() + { + return $this->getPort() === null || GuzzleUri::isDefaultPort($this); + } + + /** + * Whether the URI is absolute, i.e. it has a scheme. + * + * An instance of UriInterface can either be an absolute URI or a relative reference. This method returns true + * if it is the former. An absolute URI has a scheme. A relative reference is used to express a URI relative + * to another URI, the base URI. Relative references can be divided into several forms: + * - network-path references, e.g. '//example.com/path' + * - absolute-path references, e.g. '/path' + * - relative-path references, e.g. 'subpath' + * + * @return bool + * @link https://tools.ietf.org/html/rfc3986#section-4 + */ + public function isAbsolute() + { + return GuzzleUri::isAbsolute($this); + } + + /** + * Whether the URI is a network-path reference. + * + * A relative reference that begins with two slash characters is termed an network-path reference. + * + * @return bool + * @link https://tools.ietf.org/html/rfc3986#section-4.2 + */ + public function isNetworkPathReference() + { + return GuzzleUri::isNetworkPathReference($this); + } + + /** + * Whether the URI is a absolute-path reference. + * + * A relative reference that begins with a single slash character is termed an absolute-path reference. + * + * @return bool + * @link https://tools.ietf.org/html/rfc3986#section-4.2 + */ + public function isAbsolutePathReference() + { + return GuzzleUri::isAbsolutePathReference($this); + } + + /** + * Whether the URI is a relative-path reference. + * + * A relative reference that does not begin with a slash character is termed a relative-path reference. + * + * @return bool + * @link https://tools.ietf.org/html/rfc3986#section-4.2 + */ + public function isRelativePathReference() + { + return GuzzleUri::isRelativePathReference($this); + } + + /** + * Whether the URI is a same-document reference. + * + * A same-document reference refers to a URI that is, aside from its fragment + * component, identical to the base URI. When no base URI is given, only an empty + * URI reference (apart from its fragment) is considered a same-document reference. + * + * @param UriInterface|null $base An optional base URI to compare against + * @return bool + * @link https://tools.ietf.org/html/rfc3986#section-4.4 + */ + public function isSameDocumentReference(UriInterface $base = null) + { + return GuzzleUri::isSameDocumentReference($this, $base); + } +} diff --git a/system/src/Grav/Framework/Uri/UriFactory.php b/system/src/Grav/Framework/Uri/UriFactory.php new file mode 100644 index 0000000..cb917ed --- /dev/null +++ b/system/src/Grav/Framework/Uri/UriFactory.php @@ -0,0 +1,171 @@ + $scheme, + 'user' => $user, + 'pass' => $pass, + 'host' => $host, + 'port' => $port, + 'path' => $path, + 'query' => $query + ]; + } + + /** + * UTF-8 aware parse_url() implementation. + * + * @param string $url + * @return array + * @throws InvalidArgumentException + */ + public static function parseUrl($url) + { + if (!is_string($url)) { + throw new InvalidArgumentException('URL must be a string'); + } + + $encodedUrl = preg_replace_callback( + '%[^:/@?&=#]+%u', + static function ($matches) { + return rawurlencode($matches[0]); + }, + $url + ); + + $parts = is_string($encodedUrl) ? parse_url($encodedUrl) : false; + if ($parts === false) { + throw new InvalidArgumentException("Malformed URL: {$url}"); + } + + return $parts; + } + + /** + * Parse query string and return it as an array. + * + * @param string $query + * @return mixed + */ + public static function parseQuery($query) + { + parse_str($query, $params); + + return $params; + } + + /** + * Build query string from variables. + * + * @param array $params + * @return string + */ + public static function buildQuery(array $params) + { + if (!$params) { + return ''; + } + + $separator = ini_get('arg_separator.output') ?: '&'; + + return http_build_query($params, '', $separator, PHP_QUERY_RFC3986); + } +} diff --git a/system/src/Grav/Framework/Uri/UriPartsFilter.php b/system/src/Grav/Framework/Uri/UriPartsFilter.php new file mode 100644 index 0000000..27b72ac --- /dev/null +++ b/system/src/Grav/Framework/Uri/UriPartsFilter.php @@ -0,0 +1,145 @@ += 0 && $port <= 65535))) { + return $port; + } + + throw new InvalidArgumentException('Uri port must be null or an integer between 0 and 65535'); + } + + /** + * Filter Uri path. + * + * This method percent-encodes all reserved characters in the provided path string. This method + * will NOT double-encode characters that are already percent-encoded. + * + * @param string $path The raw uri path. + * @return string The RFC 3986 percent-encoded uri path. + * @throws InvalidArgumentException If the path is invalid. + * @link http://www.faqs.org/rfcs/rfc3986.html + */ + public static function filterPath($path) + { + if (!is_string($path)) { + throw new InvalidArgumentException('Uri path must be a string'); + } + + return preg_replace_callback( + '/(?:[^a-zA-Z0-9_\-\.~:@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/u', + function ($match) { + return rawurlencode($match[0]); + }, + $path + ) ?? ''; + } + + /** + * Filters the query string or fragment of a URI. + * + * @param string $query The raw uri query string. + * @return string The percent-encoded query string. + * @throws InvalidArgumentException If the query is invalid. + */ + public static function filterQueryOrFragment($query) + { + if (!is_string($query)) { + throw new InvalidArgumentException('Uri query string and fragment must be a string'); + } + + return preg_replace_callback( + '/(?:[^a-zA-Z0-9_\-\.~!\$&\'\(\)\*\+,;=%:@\/\?]+|%(?![A-Fa-f0-9]{2}))/u', + function ($match) { + return rawurlencode($match[0]); + }, + $query + ) ?? ''; + } +} diff --git a/system/src/Grav/Installer/Install.php b/system/src/Grav/Installer/Install.php new file mode 100644 index 0000000..3229100 --- /dev/null +++ b/system/src/Grav/Installer/Install.php @@ -0,0 +1,400 @@ + [ + 'name' => 'PHP', + 'versions' => [ + '8.1' => '8.1.0', + '8.0' => '8.0.0', + '7.4' => '7.4.1', + '7.3' => '7.3.6', + '' => '8.0.13' + ] + ], + 'grav' => [ + 'name' => 'Grav', + 'versions' => [ + '1.6' => '1.6.0', + '' => '1.6.28' + ] + ], + 'plugins' => [ + 'admin' => [ + 'name' => 'Admin', + 'optional' => true, + 'versions' => [ + '1.9' => '1.9.0', + '' => '1.9.13' + ] + ], + 'email' => [ + 'name' => 'Email', + 'optional' => true, + 'versions' => [ + '3.0' => '3.0.0', + '' => '3.0.10' + ] + ], + 'form' => [ + 'name' => 'Form', + 'optional' => true, + 'versions' => [ + '4.1' => '4.1.0', + '4.0' => '4.0.0', + '3.0' => '3.0.0', + '' => '4.1.2' + ] + ], + 'login' => [ + 'name' => 'Login', + 'optional' => true, + 'versions' => [ + '3.3' => '3.3.0', + '3.0' => '3.0.0', + '' => '3.3.6' + ] + ], + ] + ]; + + /** @var array */ + public $ignores = [ + 'backup', + 'cache', + 'images', + 'logs', + 'tmp', + 'user', + '.htaccess', + 'robots.txt' + ]; + + /** @var array */ + private $classMap = [ + InstallException::class => __DIR__ . '/InstallException.php', + Versions::class => __DIR__ . '/Versions.php', + VersionUpdate::class => __DIR__ . '/VersionUpdate.php', + VersionUpdater::class => __DIR__ . '/VersionUpdater.php', + YamlUpdater::class => __DIR__ . '/YamlUpdater.php', + ]; + + /** @var string|null */ + private $zip; + + /** @var string|null */ + private $location; + + /** @var VersionUpdater|null */ + private $updater; + + /** @var static */ + private static $instance; + + /** + * @return static + */ + public static function instance() + { + if (null === self::$instance) { + self::$instance = new static(); + } + + return self::$instance; + } + + private function __construct() + { + } + + /** + * @param string|null $zip + * @return $this + */ + public function setZip(?string $zip) + { + $this->zip = $zip; + + return $this; + } + + /** + * @param string|null $zip + * @return void + */ + #[\ReturnTypeWillChange] + public function __invoke(?string $zip) + { + $this->zip = $zip; + + $failedRequirements = $this->checkRequirements(); + if ($failedRequirements) { + $error = ['Following requirements have failed:']; + + foreach ($failedRequirements as $name => $req) { + $error[] = "{$req['title']} >= v{$req['minimum']} required, you have v{$req['installed']}"; + } + + $errors = implode("
    \n", $error); + if (\defined('GRAV_CLI') && GRAV_CLI) { + $errors = "\n\n" . strip_tags($errors) . "\n\n"; + $errors .= <<prepare(); + $this->install(); + $this->finalize(); + } + + /** + * NOTE: This method can only be called after $grav['plugins']->init(). + * + * @return array List of failed requirements. If the list is empty, installation can go on. + */ + public function checkRequirements(): array + { + $results = []; + + $this->checkVersion($results, 'php', 'php', $this->requires['php'], PHP_VERSION); + $this->checkVersion($results, 'grav', 'grav', $this->requires['grav'], GRAV_VERSION); + $this->checkPlugins($results, $this->requires['plugins']); + + return $results; + } + + /** + * @return void + * @throws RuntimeException + */ + public function prepare(): void + { + // Locate the new Grav update and the target site from the filesystem. + $location = realpath(__DIR__); + $target = realpath(GRAV_ROOT . '/index.php'); + + if (!$location) { + throw new RuntimeException('Internal Error', 500); + } + + if ($target && dirname($location, 4) === dirname($target)) { + // We cannot copy files into themselves, abort! + throw new RuntimeException('Grav has already been installed here!', 400); + } + + // Load the installer classes. + foreach ($this->classMap as $class_name => $path) { + // Make sure that none of the Grav\Installer classes have been loaded, otherwise installation may fail! + if (class_exists($class_name, false)) { + throw new RuntimeException(sprintf('Cannot update Grav, class %s has already been loaded!', $class_name), 500); + } + + require $path; + } + + $this->legacySupport(); + + $this->location = dirname($location, 4); + + $versions = Versions::instance(USER_DIR . 'config/versions.yaml'); + $this->updater = new VersionUpdater('core/grav', __DIR__ . '/updates', $this->getVersion(), $versions); + + $this->updater->preflight(); + } + + /** + * @return void + * @throws RuntimeException + */ + public function install(): void + { + if (!$this->location) { + throw new RuntimeException('Oops, installer was run without prepare()!', 500); + } + + try { + if (null === $this->updater) { + $versions = Versions::instance(USER_DIR . 'config/versions.yaml'); + $this->updater = new VersionUpdater('core/grav', __DIR__ . '/updates', $this->getVersion(), $versions); + } + + // Update user/config/version.yaml before copying the files to avoid frontend from setting the version schema. + $this->updater->install(); + + Installer::install( + $this->zip ?? '', + GRAV_ROOT, + ['sophisticated' => true, 'overwrite' => true, 'ignore_symlinks' => true, 'ignores' => $this->ignores], + $this->location, + !($this->zip && is_file($this->zip)) + ); + } catch (Exception $e) { + Installer::setError($e->getMessage()); + } + + $errorCode = Installer::lastErrorCode(); + + $success = !(is_string($errorCode) || ($errorCode & (Installer::ZIP_OPEN_ERROR | Installer::ZIP_EXTRACT_ERROR))); + + if (!$success) { + throw new RuntimeException(Installer::lastErrorMsg()); + } + } + + /** + * @return void + * @throws RuntimeException + */ + public function finalize(): void + { + // Finalize can be run without installing Grav first. + if (null === $this->updater) { + $versions = Versions::instance(USER_DIR . 'config/versions.yaml'); + $this->updater = new VersionUpdater('core/grav', __DIR__ . '/updates', GRAV_VERSION, $versions); + $this->updater->install(); + } + + $this->updater->postflight(); + + Cache::clearCache('all'); + + clearstatcache(); + if (function_exists('opcache_reset')) { + @opcache_reset(); + } + } + + /** + * @param array $results + * @param string $type + * @param string $name + * @param array $check + * @param string|null $version + * @return void + */ + protected function checkVersion(array &$results, $type, $name, array $check, $version): void + { + if (null === $version && !empty($check['optional'])) { + return; + } + + $major = $minor = 0; + $versions = $check['versions'] ?? []; + foreach ($versions as $major => $minor) { + if (!$major || version_compare($version ?? '0', $major, '<')) { + continue; + } + + if (version_compare($version ?? '0', $minor, '>=')) { + return; + } + + break; + } + + if (!$major) { + $minor = reset($versions); + } + + $recommended = end($versions); + + if (version_compare($recommended, $minor, '<=')) { + $recommended = null; + } + + $results[$name] = [ + 'type' => $type, + 'name' => $name, + 'title' => $check['name'] ?? $name, + 'installed' => $version, + 'minimum' => $minor, + 'recommended' => $recommended + ]; + } + + /** + * @param array $results + * @param array $plugins + * @return void + */ + protected function checkPlugins(array &$results, array $plugins): void + { + if (!class_exists('Plugins')) { + return; + } + + foreach ($plugins as $name => $check) { + $plugin = Plugins::get($name); + if (!$plugin) { + $this->checkVersion($results, 'plugin', $name, $check, null); + continue; + } + + $blueprint = $plugin->blueprints(); + $version = (string)$blueprint->get('version'); + $check['name'] = ($blueprint->get('name') ?? $check['name'] ?? $name) . ' Plugin'; + $this->checkVersion($results, 'plugin', $name, $check, $version); + } + } + + /** + * @return string + */ + protected function getVersion(): string + { + $definesFile = "{$this->location}/system/defines.php"; + $content = file_get_contents($definesFile); + if (false === $content) { + return ''; + } + + preg_match("/define\('GRAV_VERSION', '([^']+)'\);/mu", $content, $matches); + + return $matches[1] ?? ''; + } + + protected function legacySupport(): void + { + // Support install for Grav 1.6.0 - 1.6.20 by loading the original class from the older version of Grav. + class_exists(\Grav\Console\Cli\CacheCommand::class, true); + } +} diff --git a/system/src/Grav/Installer/InstallException.php b/system/src/Grav/Installer/InstallException.php new file mode 100644 index 0000000..6565355 --- /dev/null +++ b/system/src/Grav/Installer/InstallException.php @@ -0,0 +1,29 @@ +getCode(), $previous); + } +} diff --git a/system/src/Grav/Installer/VersionUpdate.php b/system/src/Grav/Installer/VersionUpdate.php new file mode 100644 index 0000000..1fde783 --- /dev/null +++ b/system/src/Grav/Installer/VersionUpdate.php @@ -0,0 +1,83 @@ +revision = $name; + [$this->version, $this->date, $this->patch] = explode('_', $name); + $this->updater = $updater; + $this->methods = require $file; + } + + public function getRevision(): string + { + return $this->revision; + } + + public function getVersion(): string + { + return $this->version; + } + + public function getDate(): string + { + return $this->date; + } + + public function getPatch(): string + { + return $this->patch; + } + + public function getUpdater(): VersionUpdater + { + return $this->updater; + } + + /** + * Run right before installation. + */ + public function preflight(VersionUpdater $updater): void + { + $method = $this->methods['preflight'] ?? null; + if ($method instanceof Closure) { + $method->call($this); + } + } + + /** + * Runs right after installation. + */ + public function postflight(VersionUpdater $updater): void + { + $method = $this->methods['postflight'] ?? null; + if ($method instanceof Closure) { + $method->call($this); + } + } +} diff --git a/system/src/Grav/Installer/VersionUpdater.php b/system/src/Grav/Installer/VersionUpdater.php new file mode 100644 index 0000000..75a3b04 --- /dev/null +++ b/system/src/Grav/Installer/VersionUpdater.php @@ -0,0 +1,133 @@ +name = $name; + $this->path = $path; + $this->version = $version; + $this->versions = $versions; + + $this->loadUpdates(); + } + + /** + * Pre-installation method. + */ + public function preflight(): void + { + foreach ($this->updates as $revision => $update) { + $update->preflight($this); + } + } + + /** + * Install method. + */ + public function install(): void + { + $versions = $this->getVersions(); + $versions->updateVersion($this->name, $this->version); + $versions->save(); + } + + /** + * Post-installation method. + */ + public function postflight(): void + { + $versions = $this->getVersions(); + + foreach ($this->updates as $revision => $update) { + $update->postflight($this); + + $versions->setSchema($this->name, $revision); + $versions->save(); + } + } + + /** + * @return Versions + */ + public function getVersions(): Versions + { + return $this->versions; + } + + /** + * @param string|null $name + * @return string|null + */ + public function getExtensionVersion(string $name = null): ?string + { + return $this->versions->getVersion($name ?? $this->name); + } + + /** + * @param string|null $name + * @return string|null + */ + public function getExtensionSchema(string $name = null): ?string + { + return $this->versions->getSchema($name ?? $this->name); + } + + /** + * @param string|null $name + * @return array + */ + public function getExtensionHistory(string $name = null): array + { + return $this->versions->getHistory($name ?? $this->name); + } + + protected function loadUpdates(): void + { + $this->updates = []; + + $schema = $this->getExtensionSchema(); + $iterator = new DirectoryIterator($this->path); + foreach ($iterator as $item) { + if (!$item->isFile() || $item->getExtension() !== 'php') { + continue; + } + + $revision = $item->getBasename('.php'); + if (!$schema || version_compare($revision, $schema, '>')) { + $realPath = $item->getRealPath(); + if ($realPath) { + $this->updates[$revision] = new VersionUpdate($realPath, $this); + } + } + } + + uksort($this->updates, 'version_compare'); + } +} diff --git a/system/src/Grav/Installer/Versions.php b/system/src/Grav/Installer/Versions.php new file mode 100644 index 0000000..201b9e8 --- /dev/null +++ b/system/src/Grav/Installer/Versions.php @@ -0,0 +1,329 @@ +updated) { + return false; + } + + file_put_contents($this->filename, Yaml::dump($this->items, 4, 2)); + + $this->updated = false; + + return true; + } + + /** + * @return array + */ + public function getAll(): array + { + return $this->items; + } + + /** + * @return array|null + */ + public function getGrav(): ?array + { + return $this->get('core/grav'); + } + + /** + * @return array + */ + public function getPlugins(): array + { + return $this->get('plugins', []); + } + + /** + * @param string $name + * @return array|null + */ + public function getPlugin(string $name): ?array + { + return $this->get("plugins/{$name}"); + } + + /** + * @return array + */ + public function getThemes(): array + { + return $this->get('themes', []); + } + + /** + * @param string $name + * @return array|null + */ + public function getTheme(string $name): ?array + { + return $this->get("themes/{$name}"); + } + + /** + * @param string $extension + * @return array|null + */ + public function getExtension(string $extension): ?array + { + return $this->get($extension); + } + + /** + * @param string $extension + * @param array|null $value + */ + public function setExtension(string $extension, ?array $value): void + { + if (null !== $value) { + $this->set($extension, $value); + } else { + $this->undef($extension); + } + } + + /** + * @param string $extension + * @return string|null + */ + public function getVersion(string $extension): ?string + { + $version = $this->get("{$extension}/version", null); + + return is_string($version) ? $version : null; + } + + /** + * @param string $extension + * @param string|null $version + */ + public function setVersion(string $extension, ?string $version): void + { + $this->updateHistory($extension, $version); + } + + /** + * NOTE: Updates also history. + * + * @param string $extension + * @param string|null $version + */ + public function updateVersion(string $extension, ?string $version): void + { + $this->set("{$extension}/version", $version); + $this->updateHistory($extension, $version); + } + + /** + * @param string $extension + * @return string|null + */ + public function getSchema(string $extension): ?string + { + $version = $this->get("{$extension}/schema", null); + + return is_string($version) ? $version : null; + } + + /** + * @param string $extension + * @param string|null $schema + */ + public function setSchema(string $extension, ?string $schema): void + { + if (null !== $schema) { + $this->set("{$extension}/schema", $schema); + } else { + $this->undef("{$extension}/schema"); + } + } + + /** + * @param string $extension + * @return array + */ + public function getHistory(string $extension): array + { + $name = "{$extension}/history"; + $history = $this->get($name, []); + + // Fix for broken Grav 1.6 history + if ($extension === 'grav') { + $history = $this->fixHistory($history); + } + + return $history; + } + + /** + * @param string $extension + * @param string|null $version + */ + public function updateHistory(string $extension, ?string $version): void + { + $name = "{$extension}/history"; + $history = $this->getHistory($extension); + $history[] = ['version' => $version, 'date' => gmdate('Y-m-d H:i:s')]; + $this->set($name, $history); + } + + /** + * Clears extension history. Useful when creating skeletons. + * + * @param string $extension + */ + public function removeHistory(string $extension): void + { + $this->undef("{$extension}/history"); + } + + /** + * @param array $history + * @return array + */ + private function fixHistory(array $history): array + { + if (isset($history['version'], $history['date'])) { + $fix = [['version' => $history['version'], 'date' => $history['date']]]; + unset($history['version'], $history['date']); + $history = array_merge($fix, $history); + } + + return $history; + } + + /** + * Get value by using dot notation for nested arrays/objects. + * + * @param string $name Slash separated path to the requested value. + * @param mixed $default Default value (or null). + * @return mixed Value. + */ + private function get(string $name, $default = null) + { + $path = explode('/', $name); + $current = $this->items; + + foreach ($path as $field) { + if (is_array($current) && isset($current[$field])) { + $current = $current[$field]; + } else { + return $default; + } + } + + return $current; + } + + /** + * Set value by using dot notation for nested arrays/objects. + * + * @param string $name Slash separated path to the requested value. + * @param mixed $value New value. + */ + private function set(string $name, $value): void + { + $path = explode('/', $name); + $current = &$this->items; + + foreach ($path as $field) { + // Handle arrays and scalars. + if (!is_array($current)) { + $current = [$field => []]; + } elseif (!isset($current[$field])) { + $current[$field] = []; + } + $current = &$current[$field]; + } + + $current = $value; + $this->updated = true; + } + + /** + * Unset value by using dot notation for nested arrays/objects. + * + * @param string $name Dot separated path to the requested value. + */ + private function undef(string $name): void + { + $path = $name !== '' ? explode('/', $name) : []; + if (!$path) { + return; + } + + $var = array_pop($path); + $current = &$this->items; + + foreach ($path as $field) { + if (!is_array($current) || !isset($current[$field])) { + return; + } + $current = &$current[$field]; + } + + unset($current[$var]); + $this->updated = true; + } + + private function __construct(string $filename) + { + $this->filename = $filename; + $content = is_file($filename) ? file_get_contents($filename) : null; + if (false === $content) { + throw new \RuntimeException('Versions file cannot be read'); + } + $this->items = $content ? Yaml::parse($content) : []; + } +} diff --git a/system/src/Grav/Installer/YamlUpdater.php b/system/src/Grav/Installer/YamlUpdater.php new file mode 100644 index 0000000..b8aa078 --- /dev/null +++ b/system/src/Grav/Installer/YamlUpdater.php @@ -0,0 +1,431 @@ +updated) { + return false; + } + + try { + if (!$this->isHandWritten()) { + $yaml = Yaml::dump($this->items, 5, 2); + } else { + $yaml = implode("\n", $this->lines); + + $items = Yaml::parse($yaml); + if ($items !== $this->items) { + throw new \RuntimeException('Failed saving the content'); + } + } + + file_put_contents($this->filename, $yaml); + + } catch (\Exception $e) { + throw new \RuntimeException('Failed to update ' . basename($this->filename) . ': ' . $e->getMessage()); + } + + return true; + } + + /** + * @return bool + */ + public function isHandWritten(): bool + { + return !empty($this->comments); + } + + /** + * @return array + */ + public function getComments(): array + { + $comments = []; + foreach ($this->lines as $i => $line) { + if ($this->isLineEmpty($line)) { + $comments[$i+1] = $line; + } elseif ($comment = $this->getInlineComment($line)) { + $comments[$i+1] = $comment; + } + } + + return $comments; + } + + /** + * @param string $variable + * @param mixed $value + */ + public function define(string $variable, $value): void + { + // If variable has already value, we're good. + if ($this->get($variable) !== null) { + return; + } + + // If one of the parents isn't array, we're good, too. + if (!$this->canDefine($variable)) { + return; + } + + $this->set($variable, $value); + if (!$this->isHandWritten()) { + return; + } + + $parts = explode('.', $variable); + + $lineNos = $this->findPath($this->lines, $parts); + $count = count($lineNos); + $last = array_key_last($lineNos); + + $value = explode("\n", trim(Yaml::dump([$last => $this->get(implode('.', array_keys($lineNos)))], max(0, 5-$count), 2))); + $currentLine = array_pop($lineNos) ?: 0; + $parentLine = array_pop($lineNos); + + if ($parentLine !== null) { + $c = $this->getLineIndentation($this->lines[$parentLine] ?? ''); + $n = $this->getLineIndentation($this->lines[$parentLine+1] ?? $this->lines[$parentLine] ?? ''); + $indent = $n > $c ? $n : $c + 2; + } else { + $indent = 0; + array_unshift($value, ''); + } + $spaces = str_repeat(' ', $indent); + foreach ($value as &$line) { + $line = $spaces . $line; + } + unset($line); + + array_splice($this->lines, abs($currentLine)+1, 0, $value); + } + + public function undefine(string $variable): void + { + // If variable does not have value, we're good. + if ($this->get($variable) === null) { + return; + } + + // If one of the parents isn't array, we're good, too. + if (!$this->canDefine($variable)) { + return; + } + + $this->undef($variable); + if (!$this->isHandWritten()) { + return; + } + + // TODO: support also removing property from handwritten configuration file. + } + + private function __construct(string $filename) + { + $content = is_file($filename) ? (string)file_get_contents($filename) : ''; + $content = rtrim(str_replace(["\r\n", "\r"], "\n", $content)); + + $this->filename = $filename; + $this->lines = explode("\n", $content); + $this->comments = $this->getComments(); + $this->items = $content ? Yaml::parse($content) : []; + } + + /** + * Return array of offsets for the parent nodes. Negative value means position, but not found. + * + * @param array $lines + * @param array $parts + * @return int[] + */ + private function findPath(array $lines, array $parts) + { + $test = true; + $indent = -1; + $current = array_shift($parts); + + $j = 1; + $found = []; + $space = ''; + foreach ($lines as $i => $line) { + if ($this->isLineEmpty($line)) { + if ($this->isLineComment($line) && $this->getLineIndentation($line) > $indent) { + $j = $i; + } + continue; + } + + if ($test === true) { + $test = false; + $spaces = strlen($line) - strlen(ltrim($line, ' ')); + if ($spaces <= $indent) { + $found[$current] = -$j; + + return $found; + } + + $indent = $spaces; + $space = $indent ? str_repeat(' ', $indent) : ''; + } + + + if (0 === \strncmp($line, $space, strlen($space))) { + $pattern = "/^{$space}(['\"]?){$current}\\1\:/"; + + if (preg_match($pattern, $line)) { + $found[$current] = $i; + $current = array_shift($parts); + if ($current === null) { + return $found; + } + $test = true; + } + } else { + $found[$current] = -$j; + + return $found; + } + + $j = $i; + } + + $found[$current] = -$j; + + return $found; + } + + /** + * Returns true if the current line is blank or if it is a comment line. + * + * @param string $line Contents of the line + * @return bool Returns true if the current line is empty or if it is a comment line, false otherwise + */ + private function isLineEmpty(string $line): bool + { + return $this->isLineBlank($line) || $this->isLineComment($line); + } + + /** + * Returns true if the current line is blank. + * + * @param string $line Contents of the line + * @return bool Returns true if the current line is blank, false otherwise + */ + private function isLineBlank(string $line): bool + { + return '' === trim($line, ' '); + } + + /** + * Returns true if the current line is a comment line. + * + * @param string $line Contents of the line + * @return bool Returns true if the current line is a comment line, false otherwise + */ + private function isLineComment(string $line): bool + { + //checking explicitly the first char of the trim is faster than loops or strpos + $ltrimmedLine = ltrim($line, ' '); + + return '' !== $ltrimmedLine && '#' === $ltrimmedLine[0]; + } + + /** + * @param string $line + * @return bool + */ + private function isInlineComment(string $line): bool + { + return $this->getInlineComment($line) !== null; + } + + /** + * @param string $line + * @return string|null + */ + private function getInlineComment(string $line): ?string + { + $pos = strpos($line, ' #'); + if (false === $pos) { + return null; + } + + $parts = explode(' #', $line); + $part = ''; + while ($part .= array_shift($parts)) { + // Remove quoted values. + $part = preg_replace('/(([\'"])[^\2]*\2)/', '', $part); + assert(null !== $part); + $part = preg_split('/[\'"]/', $part, 2); + assert(false !== $part); + if (!isset($part[1])) { + $part = $part[0]; + array_unshift($parts, str_repeat(' ', strlen($part) - strlen(trim($part, ' ')))); + break; + } + $part = $part[1]; + } + + + return implode(' #', $parts); + } + + /** + * Returns the current line indentation. + * + * @param string $line + * @return int The current line indentation + */ + private function getLineIndentation(string $line): int + { + return \strlen($line) - \strlen(ltrim($line, ' ')); + } + + /** + * Get value by using dot notation for nested arrays/objects. + * + * @param string $name Dot separated path to the requested value. + * @param mixed $default Default value (or null). + * @return mixed Value. + */ + private function get(string $name, $default = null) + { + $path = explode('.', $name); + $current = $this->items; + + foreach ($path as $field) { + if (is_array($current) && isset($current[$field])) { + $current = $current[$field]; + } else { + return $default; + } + } + + return $current; + } + + /** + * Set value by using dot notation for nested arrays/objects. + * + * @param string $name Dot separated path to the requested value. + * @param mixed $value New value. + */ + private function set(string $name, $value): void + { + $path = explode('.', $name); + $current = &$this->items; + + foreach ($path as $field) { + // Handle arrays and scalars. + if (!is_array($current)) { + $current = [$field => []]; + } elseif (!isset($current[$field])) { + $current[$field] = []; + } + $current = &$current[$field]; + } + + $current = $value; + $this->updated = true; + } + + /** + * Unset value by using dot notation for nested arrays/objects. + * + * @param string $name Dot separated path to the requested value. + */ + private function undef(string $name): void + { + $path = $name !== '' ? explode('.', $name) : []; + if (!$path) { + return; + } + + $var = array_pop($path); + $current = &$this->items; + + foreach ($path as $field) { + if (!is_array($current) || !isset($current[$field])) { + return; + } + $current = &$current[$field]; + } + + unset($current[$var]); + $this->updated = true; + } + + /** + * Get value by using dot notation for nested arrays/objects. + * + * @param string $name Dot separated path to the requested value. + * @return bool + */ + private function canDefine(string $name): bool + { + $path = explode('.', $name); + $current = $this->items; + + foreach ($path as $field) { + if (is_array($current)) { + if (!isset($current[$field])) { + return true; + } + $current = $current[$field]; + } else { + return false; + } + } + + return true; + } +} diff --git a/system/src/Grav/Installer/updates/1.7.0_2020-11-20_1.php b/system/src/Grav/Installer/updates/1.7.0_2020-11-20_1.php new file mode 100644 index 0000000..6120665 --- /dev/null +++ b/system/src/Grav/Installer/updates/1.7.0_2020-11-20_1.php @@ -0,0 +1,24 @@ + null, + 'postflight' => + function () { + /** @var VersionUpdate $this */ + try { + // Keep old defaults for backwards compatibility. + $yaml = YamlUpdater::instance(GRAV_ROOT . '/user/config/system.yaml'); + $yaml->define('twig.autoescape', false); + $yaml->define('strict_mode.yaml_compat', true); + $yaml->define('strict_mode.twig_compat', true); + $yaml->define('strict_mode.blueprint_compat', true); + $yaml->save(); + } catch (\Exception $e) { + throw new InstallException('Could not update system configuration to maintain backwards compatibility', $e); + } + } +]; diff --git a/system/src/Twig/DeferredExtension/DeferredBlockNode.php b/system/src/Twig/DeferredExtension/DeferredBlockNode.php new file mode 100644 index 0000000..6ae974f --- /dev/null +++ b/system/src/Twig/DeferredExtension/DeferredBlockNode.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Twig\DeferredExtension; + +use Twig\Compiler; +use Twig\Node\BlockNode; + +final class DeferredBlockNode extends BlockNode +{ + public function compile(Compiler $compiler) : void + { + $name = $this->getAttribute('name'); + + $compiler + ->write("public function block_$name(\$context, array \$blocks = [])\n", "{\n") + ->indent() + ->write("\$this->deferred->defer(\$this, '$name');\n") + ->outdent() + ->write("}\n\n") + ; + + $compiler + ->addDebugInfo($this) + ->write("public function block_{$name}_deferred(\$context, array \$blocks = [])\n", "{\n") + ->indent() + ->subcompile($this->getNode('body')) + ->write("\$this->deferred->resolve(\$this, \$context, \$blocks);\n") + ->outdent() + ->write("}\n\n") + ; + } +} diff --git a/system/src/Twig/DeferredExtension/DeferredDeclareNode.php b/system/src/Twig/DeferredExtension/DeferredDeclareNode.php new file mode 100644 index 0000000..ba05121 --- /dev/null +++ b/system/src/Twig/DeferredExtension/DeferredDeclareNode.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Twig\DeferredExtension; + +use Twig\Compiler; +use Twig\Node\Node; + +final class DeferredDeclareNode extends Node +{ + public function compile(Compiler $compiler) : void + { + $compiler + ->write("private \$deferred;\n") + ; + } +} \ No newline at end of file diff --git a/system/src/Twig/DeferredExtension/DeferredExtension.php b/system/src/Twig/DeferredExtension/DeferredExtension.php new file mode 100644 index 0000000..f27c2a3 --- /dev/null +++ b/system/src/Twig/DeferredExtension/DeferredExtension.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Twig\DeferredExtension; + +use Twig\Environment; +use Twig\Extension\AbstractExtension; +use Twig\Template; + +final class DeferredExtension extends AbstractExtension +{ + private $blocks = []; + + public function getTokenParsers() : array + { + return [new DeferredTokenParser()]; + } + + public function getNodeVisitors() : array + { + if (Environment::VERSION_ID < 20000) { + // Twig 1.x support + return [new DeferredNodeVisitorCompat()]; + } + + return [new DeferredNodeVisitor()]; + } + + public function defer(Template $template, string $blockName) : void + { + $templateName = $template->getTemplateName(); + $this->blocks[$templateName][] = $blockName; + $index = \count($this->blocks[$templateName]) - 1; + + \ob_start(function (string $buffer) use ($index, $templateName) { + unset($this->blocks[$templateName][$index]); + + return $buffer; + }); + } + + public function resolve(Template $template, array $context, array $blocks) : void + { + $templateName = $template->getTemplateName(); + if (empty($this->blocks[$templateName])) { + return; + } + + while ($blockName = \array_pop($this->blocks[$templateName])) { + $buffer = \ob_get_clean(); + + $blocks[$blockName] = [$template, 'block_'.$blockName.'_deferred']; + $template->displayBlock($blockName, $context, $blocks); + + echo $buffer; + } + + if ($parent = $template->getParent($context)) { + $this->resolve($parent, $context, $blocks); + } + } +} diff --git a/system/src/Twig/DeferredExtension/DeferredInitializeNode.php b/system/src/Twig/DeferredExtension/DeferredInitializeNode.php new file mode 100644 index 0000000..0653f5c --- /dev/null +++ b/system/src/Twig/DeferredExtension/DeferredInitializeNode.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Twig\DeferredExtension; + +use Twig\Compiler; +use Twig\Node\Node; + +final class DeferredInitializeNode extends Node +{ + public function compile(Compiler $compiler) : void + { + $compiler + ->write("\$this->deferred = \$this->env->getExtension('".DeferredExtension::class."');\n") + ; + } +} diff --git a/system/src/Twig/DeferredExtension/DeferredNode.php b/system/src/Twig/DeferredExtension/DeferredNode.php new file mode 100644 index 0000000..2ac73bd --- /dev/null +++ b/system/src/Twig/DeferredExtension/DeferredNode.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Twig\DeferredExtension; + +use Twig\Compiler; +use Twig\Node\Node; + +final class DeferredNode extends Node +{ + public function compile(Compiler $compiler) : void + { + $compiler + ->write("\$this->deferred->resolve(\$this, \$context, \$blocks);\n") + ; + } +} diff --git a/system/src/Twig/DeferredExtension/DeferredNodeVisitor.php b/system/src/Twig/DeferredExtension/DeferredNodeVisitor.php new file mode 100644 index 0000000..6f61487 --- /dev/null +++ b/system/src/Twig/DeferredExtension/DeferredNodeVisitor.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Twig\DeferredExtension; + +use Twig\Environment; +use Twig\Node\ModuleNode; +use Twig\Node\Node; +use Twig\NodeVisitor\NodeVisitorInterface; + +final class DeferredNodeVisitor implements NodeVisitorInterface +{ + private $hasDeferred = false; + + public function enterNode(Node $node, Environment $env) : Node + { + if (!$this->hasDeferred && $node instanceof DeferredBlockNode) { + $this->hasDeferred = true; + } + + return $node; + } + + public function leaveNode(Node $node, Environment $env) : ?Node + { + if ($this->hasDeferred && $node instanceof ModuleNode) { + $node->getNode('constructor_end')->setNode('deferred_initialize', new DeferredInitializeNode()); + $node->getNode('display_end')->setNode('deferred_resolve', new DeferredResolveNode()); + $node->getNode('class_end')->setNode('deferred_declare', new DeferredDeclareNode()); + $this->hasDeferred = false; + } + + return $node; + } + + public function getPriority() : int + { + return 0; + } +} diff --git a/system/src/Twig/DeferredExtension/DeferredNodeVisitorCompat.php b/system/src/Twig/DeferredExtension/DeferredNodeVisitorCompat.php new file mode 100644 index 0000000..aa61b72 --- /dev/null +++ b/system/src/Twig/DeferredExtension/DeferredNodeVisitorCompat.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Twig\DeferredExtension; + +use Twig\Environment; +use Twig\Node\ModuleNode; +use Twig\Node\Node; +use Twig\NodeVisitor\NodeVisitorInterface; + +final class DeferredNodeVisitorCompat implements NodeVisitorInterface +{ + private $hasDeferred = false; + + /** + * @param \Twig_NodeInterface $node + * @param Environment $env + * @return Node + */ + public function enterNode(\Twig_NodeInterface $node, Environment $env): Node + { + if (!$this->hasDeferred && $node instanceof DeferredBlockNode) { + $this->hasDeferred = true; + } + + \assert($node instanceof Node); + + return $node; + } + + /** + * @param \Twig_NodeInterface $node + * @param Environment $env + * @return Node|null + */ + public function leaveNode(\Twig_NodeInterface $node, Environment $env): ?Node + { + if ($this->hasDeferred && $node instanceof ModuleNode) { + $node->getNode('constructor_end')->setNode('deferred_initialize', new DeferredInitializeNode()); + $node->getNode('display_end')->setNode('deferred_resolve', new DeferredResolveNode()); + $node->getNode('class_end')->setNode('deferred_declare', new DeferredDeclareNode()); + $this->hasDeferred = false; + } + + \assert($node instanceof Node); + + return $node; + } + + /** + * @return int + */ + public function getPriority() : int + { + return 0; + } +} diff --git a/system/src/Twig/DeferredExtension/DeferredResolveNode.php b/system/src/Twig/DeferredExtension/DeferredResolveNode.php new file mode 100644 index 0000000..72e0e29 --- /dev/null +++ b/system/src/Twig/DeferredExtension/DeferredResolveNode.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Twig\DeferredExtension; + +use Twig\Compiler; +use Twig\Node\Node; + +final class DeferredResolveNode extends Node +{ + public function compile(Compiler $compiler) : void + { + $compiler + ->write("\$this->deferred->resolve(\$this, \$context, \$blocks);\n") + ; + } +} diff --git a/system/src/Twig/DeferredExtension/DeferredTokenParser.php b/system/src/Twig/DeferredExtension/DeferredTokenParser.php new file mode 100644 index 0000000..1870ae0 --- /dev/null +++ b/system/src/Twig/DeferredExtension/DeferredTokenParser.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Twig\DeferredExtension; + +use Twig\Node\BlockNode; +use Twig\Node\Node; +use Twig\Parser; +use Twig\Token; +use Twig\TokenParser\AbstractTokenParser; +use Twig\TokenParser\BlockTokenParser; + +final class DeferredTokenParser extends AbstractTokenParser +{ + private $blockTokenParser; + + public function setParser(Parser $parser) : void + { + parent::setParser($parser); + + $this->blockTokenParser = new BlockTokenParser(); + $this->blockTokenParser->setParser($parser); + } + + public function parse(Token $token) : Node + { + $stream = $this->parser->getStream(); + $nameToken = $stream->next(); + $deferredToken = $stream->nextIf(Token::NAME_TYPE, 'deferred'); + $stream->injectTokens([$nameToken]); + + $node = $this->blockTokenParser->parse($token); + + if ($deferredToken) { + $this->replaceBlockNode($nameToken->getValue()); + } + + return $node; + } + + public function getTag() : string + { + return 'block'; + } + + private function replaceBlockNode(string $name) : void + { + $block = $this->parser->getBlock($name)->getNode('0'); + $this->parser->setBlock($name, $this->createDeferredBlockNode($block)); + } + + private function createDeferredBlockNode(BlockNode $block) : DeferredBlockNode + { + $name = $block->getAttribute('name'); + $deferredBlock = new DeferredBlockNode($name, new Node([]), $block->getTemplateLine()); + + foreach ($block as $nodeName => $node) { + $deferredBlock->setNode($nodeName, $node); + } + + if ($sourceContext = $block->getSourceContext()) { + $deferredBlock->setSourceContext($sourceContext); + } + + return $deferredBlock; + } +} diff --git a/system/templates/default.html.twig b/system/templates/default.html.twig new file mode 100644 index 0000000..f18206b --- /dev/null +++ b/system/templates/default.html.twig @@ -0,0 +1,4 @@ +{# Default output if no theme #} +

    ERROR: {{ page.template() ~'.'~ page.templateFormat() ~".twig" }} template not found for page: {{ page.route() }}

    +

    {{ page.title() }}

    +{{ page.content()|raw }} diff --git a/system/templates/external.html.twig b/system/templates/external.html.twig new file mode 100644 index 0000000..3fa3508 --- /dev/null +++ b/system/templates/external.html.twig @@ -0,0 +1 @@ +{# Default external template #} diff --git a/system/templates/flex/404.html.twig b/system/templates/flex/404.html.twig new file mode 100644 index 0000000..adf4f65 --- /dev/null +++ b/system/templates/flex/404.html.twig @@ -0,0 +1,4 @@ +{% set item = collection ?? object %} +{% set type = collection ? 'collection' : 'object' %} + +ERROR: Layout '{{ layout }}' for flex {{ type }} '{{ item.flexType() }}' was not found. \ No newline at end of file diff --git a/system/templates/flex/_default/collection/debug.html.twig b/system/templates/flex/_default/collection/debug.html.twig new file mode 100644 index 0000000..5a37835 --- /dev/null +++ b/system/templates/flex/_default/collection/debug.html.twig @@ -0,0 +1,5 @@ +

    {{ directory.getTitle() }} debug dump

    + +{% for object in collection %} + {% render object layout: layout %} +{% endfor %} diff --git a/system/templates/flex/_default/object/debug.html.twig b/system/templates/flex/_default/object/debug.html.twig new file mode 100644 index 0000000..dc961cd --- /dev/null +++ b/system/templates/flex/_default/object/debug.html.twig @@ -0,0 +1,4 @@ +
    +

    {{ object.key }}

    +
    {{ object.jsonSerialize()|yaml_encode }}
    +
    \ No newline at end of file diff --git a/system/templates/modular/default.html.twig b/system/templates/modular/default.html.twig new file mode 100644 index 0000000..f18206b --- /dev/null +++ b/system/templates/modular/default.html.twig @@ -0,0 +1,4 @@ +{# Default output if no theme #} +

    ERROR: {{ page.template() ~'.'~ page.templateFormat() ~".twig" }} template not found for page: {{ page.route() }}

    +

    {{ page.title() }}

    +{{ page.content()|raw }} diff --git a/system/templates/partials/messages.html.twig b/system/templates/partials/messages.html.twig new file mode 100644 index 0000000..261b3fc --- /dev/null +++ b/system/templates/partials/messages.html.twig @@ -0,0 +1,14 @@ +{% set status_mapping = {'info':'green', 'error': 'red', 'warning': 'yellow'} %} + +{% if grav.messages.all %} +
    + {% for message in grav.messages.fetch %} + + {% set scope = message.scope|e %} + {% set color = status_mapping[scope] %} + +

    {{ message.message|raw }}

    + + {% endfor %} +
    +{% endif %} diff --git a/system/templates/partials/metadata.html.twig b/system/templates/partials/metadata.html.twig new file mode 100644 index 0000000..fcf1217 --- /dev/null +++ b/system/templates/partials/metadata.html.twig @@ -0,0 +1,3 @@ +{% for meta in page.metadata %} + +{% endfor %} diff --git a/tests/_bootstrap.php b/tests/_bootstrap.php new file mode 100644 index 0000000..1c0ffd9 --- /dev/null +++ b/tests/_bootstrap.php @@ -0,0 +1,35 @@ +init(); + + foreach (array_keys($grav['setup']->getStreams()) as $stream) { + @stream_wrapper_unregister($stream); + } + + $grav['streams']; + + $grav['uri']->init(); + $grav['debugger']->init(); + $grav['assets']->init(); + + $grav['config']->set('system.cache.enabled', false); + $grav['locator']->addPath('tests', '', 'tests', false); + + return $grav; +}; + +Fixtures::add('grav', $grav); + +$fake = Factory::create(); +Fixtures::add('fake', $fake); + diff --git a/tests/_support/AcceptanceTester.php b/tests/_support/AcceptanceTester.php new file mode 100644 index 0000000..4c7dcbb --- /dev/null +++ b/tests/_support/AcceptanceTester.php @@ -0,0 +1,26 @@ +t!fmROooqL-Tz8o|Tx<=pzP32bY^zA}n1m`*SZ zayH~~sh*$2f56|-lb6+ai;Tk!uM0i7lF_H0{5Zi`GEH@D+5JM9lSj1nKe)T&;m-;` z_diSd=LVjNxEHYH)e#|P({1W0Z@V{d{K+CJxk<%)f5U2*^1@Eu4L`D?f>!k1m^N>z z$H%+^=cVf}u-|r`eeuO5&XA|aU$*!&muD*Wsr@eOopdYsS7GFfT{%^Z_bbv2jV|)7 zpBi*{E6Yu+0_pvPdZ<#k#~Xw_4`vsh3VLn7h~tUHZ`TtSwkz_?3jAU7@a?opiQms8cudkC$rRsg7umFT zp>6NVpdI;LvqNOg#<43ZIh=ofz(-?G#k;)AyK*nEsWc}4E&N*MwLid{oujB&wp)>r zf#C)a2Y53wi83RC8d;8ufd>}w4oezAOyq#)fCqelH!B-RmJtYDfOIC%Tm}XJO6sxU literal 0 HcmV?d00001 diff --git a/tests/fake/nested-site/user/pages/01.item1/home-cache-image.jpg b/tests/fake/nested-site/user/pages/01.item1/home-cache-image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3170ac497409e7c7923d25e3eae4b9e4a920b211 GIT binary patch literal 156699 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�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

    xa_u8c)hsQoXBakm44Rj@Hu~WCdpmw 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�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

    xa_u8c)hsQoXBakm44Rj@Hu~WCdpmw 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�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

    xa_u8c)hsQoXBakm44Rj@Hu~WCdpmw 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 literal 0 HcmV?d00001 diff --git a/tests/fake/nested-site/user/pages/02.item2/02.item2-2/sample-image.jpg b/tests/fake/nested-site/user/pages/02.item2/02.item2-2/sample-image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3170ac497409e7c7923d25e3eae4b9e4a920b211 GIT binary patch literal 156699 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�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

    xa_u8c)hsQoXBakm44Rj@Hu~WCdpmw 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: animalgrav = Fixtures::get('grav'); + $this->directInstallCommand = new DirectInstallCommand(); + } + +} + +/** + * Why this test file is empty + * + * Wasn't able to call a symfony\console. Kept having $output problem. + * symfony console \NullOutput didn't cut it. + * + * We would also need to Mock tests since downloading packages would + * make tests slow and unreliable. But it's not worth the time ATM. + * + * Look at Gpm/InstallCommandTest.php + * + * For the full story: https://git.io/vSlI3 + */ diff --git a/tests/functional/_bootstrap.php b/tests/functional/_bootstrap.php new file mode 100644 index 0000000..8a88555 --- /dev/null +++ b/tests/functional/_bootstrap.php @@ -0,0 +1,2 @@ +grav = $grav(); + $this->assets = $this->grav['assets']; + } + + protected function _after() + { + } + + public function testAddingAssets() + { + //test add() + $this->assets->add('test.css'); + + $css = $this->assets->css(); + $this->assertSame('' . PHP_EOL, $css); + + $array = $this->assets->getCss(); + $this->assertSame([ + 'asset' => '/test.css', + 'remote' => false, + 'priority' => 10, + 'order' => 0, + 'pipeline' => true, + 'loading' => '', + 'group' => 'head', + 'modified' => false, + 'query' => '' + ], reset($array)); + + $this->assets->add('test.js'); + $js = $this->assets->js(); + $this->assertSame('' . PHP_EOL, $js); + + $array = $this->assets->getCss(); + $this->assertSame([ + 'asset' => '/test.css', + 'remote' => false, + 'priority' => 10, + 'order' => 0, + 'pipeline' => true, + 'loading' => '', + 'group' => 'head', + 'modified' => false, + 'query' => '' + ], reset($array)); + + //test addCss(). Test adding asset to a separate group + $this->assets->reset(); + $this->assets->addCSS('test.css'); + $css = $this->assets->css(); + $this->assertSame('' . PHP_EOL, $css); + + $array = $this->assets->getCss(); + $this->assertSame([ + 'asset' => '/test.css', + 'remote' => false, + 'priority' => 10, + 'order' => 0, + 'pipeline' => true, + 'loading' => '', + 'group' => 'head', + 'modified' => false, + 'query' => '' + ], reset($array)); + + //test addCss(). Testing with remote URL + $this->assets->reset(); + $this->assets->addCSS('http://www.somesite.com/test.css'); + $css = $this->assets->css(); + $this->assertSame('' . PHP_EOL, $css); + + $array = $this->assets->getCss(); + $this->assertSame([ + 'asset' => 'http://www.somesite.com/test.css', + 'remote' => true, + 'priority' => 10, + 'order' => 0, + 'pipeline' => true, + 'loading' => '', + 'group' => 'head', + 'modified' => false, + 'query' => '' + ], reset($array)); + + //test addCss() adding asset to a separate group, and with an alternate rel attribute + $this->assets->reset(); + $this->assets->addCSS('test.css', ['group' => 'alternate']); + $css = $this->assets->css('alternate', ['rel' => 'alternate']); + $this->assertSame('' . PHP_EOL, $css); + + //test addJs() + $this->assets->reset(); + $this->assets->addJs('test.js'); + $js = $this->assets->js(); + $this->assertSame('' . PHP_EOL, $js); + + $array = $this->assets->getJs(); + $this->assertSame([ + 'asset' => '/test.js', + 'remote' => false, + 'priority' => 10, + 'order' => 0, + 'pipeline' => true, + 'loading' => '', + 'group' => 'head', + 'modified' => false, + 'query' => '' + ], reset($array)); + + //Test CSS Groups + $this->assets->reset(); + $this->assets->addCSS('test.css', null, true, 'footer'); + $css = $this->assets->css(); + $this->assertEmpty($css); + $css = $this->assets->css('footer'); + $this->assertSame('' . PHP_EOL, $css); + + $array = $this->assets->getCss(); + $this->assertSame([ + 'asset' => '/test.css', + 'remote' => false, + 'priority' => 10, + 'order' => 0, + 'pipeline' => true, + 'loading' => '', + 'group' => 'footer', + 'modified' => false, + 'query' => '' + ], reset($array)); + + //Test JS Groups + $this->assets->reset(); + $this->assets->addJs('test.js', null, true, null, 'footer'); + $js = $this->assets->js(); + $this->assertEmpty($js); + $js = $this->assets->js('footer'); + $this->assertSame('' . PHP_EOL, $js); + + $array = $this->assets->getJs(); + $this->assertSame([ + 'asset' => '/test.js', + 'remote' => false, + 'priority' => 10, + 'order' => 0, + 'pipeline' => true, + 'loading' => '', + 'group' => 'footer', + 'modified' => false, + 'query' => '' + ], reset($array)); + + //Test async / defer + $this->assets->reset(); + $this->assets->addJs('test.js', null, true, 'async', null); + $js = $this->assets->js(); + $this->assertSame('' . PHP_EOL, $js); + + $array = $this->assets->getJs(); + $this->assertSame([ + 'asset' => '/test.js', + 'remote' => false, + 'priority' => 10, + 'order' => 0, + 'pipeline' => true, + 'loading' => 'async', + 'group' => 'head', + 'modified' => false, + 'query' => '' + ], reset($array)); + + $this->assets->reset(); + $this->assets->addJs('test.js', null, true, 'defer', null); + $js = $this->assets->js(); + $this->assertSame('' . PHP_EOL, $js); + + $array = $this->assets->getJs(); + $this->assertSame([ + 'asset' => '/test.js', + 'remote' => false, + 'priority' => 10, + 'order' => 0, + 'pipeline' => true, + 'loading' => 'defer', + 'group' => 'head', + 'modified' => false, + 'query' => '' + ], reset($array)); + + //Test inline + $this->assets->reset(); + $this->assets->addJs('/system/assets/jquery/jquery-2.x.min.js', null, true, 'inline', null); + $js = $this->assets->js(); + $this->assertContains('jQuery Foundation', $js); + + $this->assets->reset(); + $this->assets->addCss('/system/assets/debugger.css', null, true, null, 'inline'); + $css = $this->assets->css(); + $this->assertContains('div.phpdebugbar', $css); + + $this->assets->reset(); + $this->assets->addCss('https://fonts.googleapis.com/css?family=Roboto', null, true, null, 'inline'); + $css = $this->assets->css(); + $this->assertContains('font-family: \'Roboto\';', $css); + + //Test adding media queries + $this->assets->reset(); + $this->assets->add('test.css', ['media' => 'only screen and (min-width: 640px)']); + $css = $this->assets->css(); + $this->assertSame('' . PHP_EOL, $css); + } + + public function testAddingAssetPropertiesWithArray() + { + //Test adding assets with object to define properties + $this->assets->reset(); + $this->assets->addJs('test.js', ['loading' => 'async']); + $js = $this->assets->js(); + $this->assertSame('' . PHP_EOL, $js); + $this->assets->reset(); + + } + + public function testAddingJSAssetPropertiesWithArrayFromCollection() + { + //Test adding properties with array + $this->assets->reset(); + $this->assets->addJs('jquery', ['loading' => 'async']); + $js = $this->assets->js(); + $this->assertSame('' . PHP_EOL, $js); + + //Test priority too + $this->assets->reset(); + $this->assets->addJs('jquery', ['loading' => 'async', 'priority' => 1]); + $this->assets->addJs('test.js', ['loading' => 'async', 'priority' => 2]); + $js = $this->assets->js(); + $this->assertSame('' . PHP_EOL . + '' . PHP_EOL, $js); + + //Test multiple groups + $this->assets->reset(); + $this->assets->addJs('jquery', ['loading' => 'async', 'priority' => 1, 'group' => 'footer']); + $this->assets->addJs('test.js', ['loading' => 'async', 'priority' => 2]); + $js = $this->assets->js(); + $this->assertSame('' . PHP_EOL, $js); + $js = $this->assets->js('footer'); + $this->assertSame('' . PHP_EOL, $js); + + //Test adding array of assets + //Test priority too + $this->assets->reset(); + $this->assets->addJs(['jquery', 'test.js'], ['loading' => 'async']); + $js = $this->assets->js(); + + $this->assertSame('' . PHP_EOL . + '' . PHP_EOL, $js); + } + + public function testAddingCSSAssetPropertiesWithArrayFromCollection() + { + $this->assets->registerCollection('test', ['/system/assets/whoops.css']); + + //Test priority too + $this->assets->reset(); + $this->assets->addCss('test', ['priority' => 1]); + $this->assets->addCss('test.css', ['priority' => 2]); + $css = $this->assets->css(); + $this->assertSame('' . PHP_EOL . + '' . PHP_EOL, $css); + + //Test multiple groups + $this->assets->reset(); + $this->assets->addCss('test', ['priority' => 1, 'group' => 'footer']); + $this->assets->addCss('test.css', ['priority' => 2]); + $css = $this->assets->css(); + $this->assertSame('' . PHP_EOL, $css); + $css = $this->assets->css('footer'); + $this->assertSame('' . PHP_EOL, $css); + + //Test adding array of assets + //Test priority too + $this->assets->reset(); + $this->assets->addCss(['test', 'test.css'], ['loading' => 'async']); + $css = $this->assets->css(); + $this->assertSame('' . PHP_EOL . + '' . PHP_EOL, $css); + } + + public function testPriorityOfAssets() + { + $this->assets->reset(); + $this->assets->add('test.css'); + $this->assets->add('test-after.css'); + + $css = $this->assets->css(); + $this->assertSame('' . PHP_EOL . + '' . PHP_EOL, $css); + + //---------------- + $this->assets->reset(); + $this->assets->add('test-after.css', 1); + $this->assets->add('test.css', 2); + + $css = $this->assets->css(); + $this->assertSame('' . PHP_EOL . + '' . PHP_EOL, $css); + + //---------------- + $this->assets->reset(); + $this->assets->add('test-after.css', 1); + $this->assets->add('test.css', 2); + $this->assets->add('test-before.css', 3); + + $css = $this->assets->css(); + $this->assertSame('' . PHP_EOL . + '' . PHP_EOL . + '' . PHP_EOL, $css); + } + + public function testPipeline() + { + $this->assets->reset(); + + //File not existing. Pipeline searches for that file without reaching it. Output is empty. + $this->assets->add('test.css', null, true); + $this->assets->setCssPipeline(true); + $css = $this->assets->css(); + $this->assertSame('', $css); + + //Add a core Grav CSS file, which is found. Pipeline will now return a file + $this->assets->add('/system/assets/debugger.css', null, true); + $css = $this->assets->css(); + $this->assertContains('', $css); + } + + public function testPipelineWithTimestamp() + { + $this->assets->reset(); + $this->assets->setTimestamp('foo'); + + //Add a core Grav CSS file, which is found. Pipeline will now return a file + $this->assets->add('/system/assets/debugger.css', null, true); + $css = $this->assets->css(); + $this->assertContains('', $css); + $this->assertContains($this->assets->getTimestamp(), $css); + } + + public function testInlinePipeline() + { + $this->assets->reset(); + + //File not existing. Pipeline searches for that file without reaching it. Output is empty. + $this->assets->add('test.css', null, true); + $this->assets->setCssPipeline(true); + $css = $this->assets->css('head', ['loading' => 'inline']); + $this->assertSame('', $css); + + //Add a core Grav CSS file, which is found. Pipeline will now return its content. + $this->assets->addCss('https://fonts.googleapis.com/css?family=Roboto', null, true); + $this->assets->add('/system/assets/debugger.css', null, true); + $css = $this->assets->css('head', ['loading' => 'inline']); + $this->assertContains('font-family:\'Roboto\';', $css); + $this->assertContains('div.phpdebugbar', $css); + } + + public function testAddAsyncJs() + { + $this->assets->reset(); + $this->assets->addAsyncJs('jquery'); + $js = $this->assets->js(); + $this->assertSame('' . PHP_EOL, $js); + } + + public function testAddDeferJs() + { + $this->assets->reset(); + $this->assets->addDeferJs('jquery'); + $js = $this->assets->js(); + $this->assertSame('' . PHP_EOL, $js); + } + + public function testTimestamps() + { + // local CSS nothing extra + $this->assets->reset(); + $this->assets->setTimestamp('foo'); + $this->assets->addCSS('test.css'); + $css = $this->assets->css(); + $this->assertSame('' . PHP_EOL, $css); + + // local CSS already with param + $this->assets->reset(); + $this->assets->setTimestamp('foo'); + $this->assets->addCSS('test.css?bar'); + $css = $this->assets->css(); + $this->assertSame('' . PHP_EOL, $css); + + // external CSS already + $this->assets->reset(); + $this->assets->setTimestamp('foo'); + $this->assets->addCSS('http://somesite.com/test.css'); + $css = $this->assets->css(); + $this->assertSame('' . PHP_EOL, $css); + + // external CSS already with param + $this->assets->reset(); + $this->assets->setTimestamp('foo'); + $this->assets->addCSS('http://somesite.com/test.css?bar'); + $css = $this->assets->css(); + $this->assertSame('' . PHP_EOL, $css); + + // local JS nothing extra + $this->assets->reset(); + $this->assets->setTimestamp('foo'); + $this->assets->addJs('test.js'); + $css = $this->assets->js(); + $this->assertSame('' . PHP_EOL, $css); + + // local JS already with param + $this->assets->reset(); + $this->assets->setTimestamp('foo'); + $this->assets->addJs('test.js?bar'); + $css = $this->assets->js(); + $this->assertSame('' . PHP_EOL, $css); + + // external JS already + $this->assets->reset(); + $this->assets->setTimestamp('foo'); + $this->assets->addJs('http://somesite.com/test.js'); + $css = $this->assets->js(); + $this->assertSame('' . PHP_EOL, $css); + + // external JS already with param + $this->assets->reset(); + $this->assets->setTimestamp('foo'); + $this->assets->addJs('http://somesite.com/test.js?bar'); + $css = $this->assets->js(); + $this->assertSame('' . PHP_EOL, $css); + } + + public function testAddInlineCss() + { + $this->assets->reset(); + $this->assets->addInlineCss('body { color: black }'); + $css = $this->assets->css(); + $this->assertSame(PHP_EOL . '' . PHP_EOL, $css); + } + + public function testAddInlineJs() + { + $this->assets->reset(); + $this->assets->addInlineJs('alert("test")'); + $js = $this->assets->js(); + $this->assertSame(PHP_EOL . '' . PHP_EOL, $js); + } + + public function testGetCollections() + { + $this->assertInternalType('array', $this->assets->getCollections()); + $this->assertContains('jquery', array_keys($this->assets->getCollections())); + $this->assertContains('system://assets/jquery/jquery-2.x.min.js', $this->assets->getCollections()); + } + + public function testExists() + { + $this->assertTrue($this->assets->exists('jquery')); + $this->assertFalse($this->assets->exists('another-unexisting-library')); + } + + public function testRegisterCollection() + { + $this->assets->registerCollection('debugger', ['/system/assets/debugger.css']); + $this->assertTrue($this->assets->exists('debugger')); + $this->assertContains('debugger', array_keys($this->assets->getCollections())); + } + + public function testReset() + { + $this->assets->addInlineJs('alert("test")'); + $this->assets->reset(); + $this->assertCount(0, (array) $this->assets->js()); + + $this->assets->addAsyncJs('jquery'); + $this->assets->reset(); + + $this->assertCount(0, (array) $this->assets->js()); + + $this->assets->addInlineCss('body { color: black }'); + $this->assets->reset(); + + $this->assertCount(0, (array) $this->assets->css()); + + $this->assets->add('/system/assets/debugger.css', null, true); + $this->assets->reset(); + + $this->assertCount(0, (array) $this->assets->css()); + } + + public function testResetJs() + { + $this->assets->addInlineJs('alert("test")'); + $this->assets->resetJs(); + $this->assertCount(0, (array) $this->assets->js()); + + $this->assets->addAsyncJs('jquery'); + $this->assets->resetJs(); + + $this->assertCount(0, (array) $this->assets->js()); + } + + public function testResetCss() + { + $this->assertCount(0, (array) $this->assets->js()); + + $this->assets->addInlineCss('body { color: black }'); + $this->assets->resetCss(); + + $this->assertCount(0, (array) $this->assets->css()); + + $this->assets->add('/system/assets/debugger.css', null, true); + $this->assets->resetCss(); + + $this->assertCount(0, (array) $this->assets->css()); + } + + public function testAddDirCss() + { + $this->assets->addDirCss('/system'); + + $this->assertInternalType('array', $this->assets->getCss()); + $this->assertGreaterThan(0, (array) $this->assets->getCss()); + $this->assertInternalType('array', $this->assets->getJs()); + $this->assertCount(0, (array) $this->assets->getJs()); + + $this->assets->reset(); + $this->assets->addDirCss('/system/assets'); + + $this->assertInternalType('array', $this->assets->getCss()); + $this->assertGreaterThan(0, (array) $this->assets->getCss()); + $this->assertInternalType('array', $this->assets->getJs()); + $this->assertCount(0, (array) $this->assets->getJs()); + + $this->assets->reset(); + $this->assets->addDirJs('/system'); + + $this->assertInternalType('array', $this->assets->getCss()); + $this->assertCount(0, (array) $this->assets->getCss()); + $this->assertInternalType('array', $this->assets->getJs()); + $this->assertGreaterThan(0, (array) $this->assets->getJs()); + + $this->assets->reset(); + $this->assets->addDirJs('/system/assets'); + + $this->assertInternalType('array', $this->assets->getCss()); + $this->assertCount(0, (array) $this->assets->getCss()); + $this->assertInternalType('array', $this->assets->getJs()); + $this->assertGreaterThan(0, (array) $this->assets->getJs()); + + $this->assets->reset(); + $this->assets->addDir('/system/assets'); + + $this->assertInternalType('array', $this->assets->getCss()); + $this->assertGreaterThan(0, (array) $this->assets->getCss()); + $this->assertInternalType('array', $this->assets->getJs()); + $this->assertGreaterThan(0, (array) $this->assets->getJs()); + + //Use streams + $this->assets->reset(); + $this->assets->addDir('system://assets'); + + $this->assertInternalType('array', $this->assets->getCss()); + $this->assertGreaterThan(0, (array) $this->assets->getCss()); + $this->assertInternalType('array', $this->assets->getJs()); + $this->assertGreaterThan(0, (array) $this->assets->getJs()); + + } +} diff --git a/tests/unit/Grav/Common/BrowserTest.php b/tests/unit/Grav/Common/BrowserTest.php new file mode 100644 index 0000000..6e63738 --- /dev/null +++ b/tests/unit/Grav/Common/BrowserTest.php @@ -0,0 +1,48 @@ +grav = $grav(); + } + + protected function _after() + { + } + + public function testGetBrowser() + { /* Already covered by PhpUserAgent tests */ + } + + public function testGetPlatform() + { /* Already covered by PhpUserAgent tests */ + } + + public function testGetLongVersion() + { /* Already covered by PhpUserAgent tests */ + } + + public function testGetVersion() + { /* Already covered by PhpUserAgent tests */ + } + + public function testIsHuman() + { + //Already Partially covered by PhpUserAgent tests + + //Make sure it recognizes the test as not human + $this->assertFalse($this->grav['browser']->isHuman()); + } +} + diff --git a/tests/unit/Grav/Common/ComposerTest.php b/tests/unit/Grav/Common/ComposerTest.php new file mode 100644 index 0000000..243a888 --- /dev/null +++ b/tests/unit/Grav/Common/ComposerTest.php @@ -0,0 +1,32 @@ +assertInternalType('string', $composerLocation); + $this->assertSame('/', $composerLocation[0]); + } + + public function testGetComposerExecutor() + { + $composerExecutor = Composer::getComposerExecutor(); + $this->assertInternalType('string', $composerExecutor); + $this->assertSame('/', $composerExecutor[0]); + $this->assertNotNull(strstr($composerExecutor, 'php')); + $this->assertNotNull(strstr($composerExecutor, 'composer')); + } + +} diff --git a/tests/unit/Grav/Common/GPM/GPMTest.php b/tests/unit/Grav/Common/GPM/GPMTest.php new file mode 100644 index 0000000..7e1c03e --- /dev/null +++ b/tests/unit/Grav/Common/GPM/GPMTest.php @@ -0,0 +1,323 @@ +data[$packageName])) { + return $this->data[$packageName]; + } + + } + + public function findPackages($searches = []) + { + return $this->data; + } +} + +/** + * Class InstallCommandTest + */ +class GpmTest extends \Codeception\TestCase\Test +{ + /** @var Grav $grav */ + protected $grav; + + /** @var GpmStub */ + protected $gpm; + + protected function _before() + { + $this->grav = Fixtures::get('grav'); + $this->gpm = new GpmStub(); + } + + protected function _after() + { + } + + public function testCalculateMergedDependenciesOfPackages() + { + ////////////////////////////////////////////////////////////////////////////////////////// + // First working example + ////////////////////////////////////////////////////////////////////////////////////////// + $this->gpm->data = [ + 'admin' => (object)[ + 'dependencies' => [ + ["name" => "grav", "version" => ">=1.0.10"], + ["name" => "form", "version" => "~2.0"], + ["name" => "login", "version" => ">=2.0"], + ["name" => "errors", "version" => "*"], + ["name" => "problems"], + ] + ], + 'test' => (object)[ + 'dependencies' => [ + ["name" => "errors", "version" => ">=1.0"] + ] + ], + 'grav', + 'form' => (object)[ + 'dependencies' => [ + ["name" => "errors", "version" => ">=3.2"] + ] + ] + + + ]; + + $packages = ['admin', 'test']; + + $dependencies = $this->gpm->calculateMergedDependenciesOfPackages($packages); + + $this->assertInternalType('array', $dependencies); + $this->assertCount(5, $dependencies); + + $this->assertSame('>=1.0.10', $dependencies['grav']); + $this->assertArrayHasKey('errors', $dependencies); + $this->assertArrayHasKey('problems', $dependencies); + + ////////////////////////////////////////////////////////////////////////////////////////// + // Second working example + ////////////////////////////////////////////////////////////////////////////////////////// + $packages = ['admin', 'form']; + + $dependencies = $this->gpm->calculateMergedDependenciesOfPackages($packages); + $this->assertInternalType('array', $dependencies); + $this->assertCount(5, $dependencies); + $this->assertSame('>=3.2', $dependencies['errors']); + + ////////////////////////////////////////////////////////////////////////////////////////// + // Third working example + ////////////////////////////////////////////////////////////////////////////////////////// + $this->gpm->data = [ + + 'admin' => (object)[ + 'dependencies' => [ + ["name" => "errors", "version" => ">=4.0"], + ] + ], + 'test' => (object)[ + 'dependencies' => [ + ["name" => "errors", "version" => ">=1.0"] + ] + ], + 'another' => (object)[ + 'dependencies' => [ + ["name" => "errors", "version" => ">=3.2"] + ] + ] + + ]; + + $packages = ['admin', 'test', 'another']; + + + $dependencies = $this->gpm->calculateMergedDependenciesOfPackages($packages); + $this->assertInternalType('array', $dependencies); + $this->assertCount(1, $dependencies); + $this->assertSame('>=4.0', $dependencies['errors']); + + + + ////////////////////////////////////////////////////////////////////////////////////////// + // Test alpha / beta / rc + ////////////////////////////////////////////////////////////////////////////////////////// + $this->gpm->data = [ + 'admin' => (object)[ + 'dependencies' => [ + ["name" => "package1", "version" => ">=4.0.0-rc1"], + ["name" => "package4", "version" => ">=3.2.0"], + ] + ], + 'test' => (object)[ + 'dependencies' => [ + ["name" => "package1", "version" => ">=4.0.0-rc2"], + ["name" => "package2", "version" => ">=3.2.0-alpha"], + ["name" => "package3", "version" => ">=3.2.0-alpha.2"], + ["name" => "package4", "version" => ">=3.2.0-alpha"], + ] + ], + 'another' => (object)[ + 'dependencies' => [ + ["name" => "package2", "version" => ">=3.2.0-beta.11"], + ["name" => "package3", "version" => ">=3.2.0-alpha.1"], + ["name" => "package4", "version" => ">=3.2.0-beta"], + ] + ] + ]; + + $packages = ['admin', 'test', 'another']; + + + $dependencies = $this->gpm->calculateMergedDependenciesOfPackages($packages); + $this->assertSame('>=4.0.0-rc2', $dependencies['package1']); + $this->assertSame('>=3.2.0-beta.11', $dependencies['package2']); + $this->assertSame('>=3.2.0-alpha.2', $dependencies['package3']); + $this->assertSame('>=3.2.0', $dependencies['package4']); + + + ////////////////////////////////////////////////////////////////////////////////////////// + // Raise exception if no version is specified + ////////////////////////////////////////////////////////////////////////////////////////// + $this->gpm->data = [ + + 'admin' => (object)[ + 'dependencies' => [ + ["name" => "errors", "version" => ">=4.0"], + ] + ], + 'test' => (object)[ + 'dependencies' => [ + ["name" => "errors", "version" => ">="] + ] + ], + + ]; + + $packages = ['admin', 'test']; + + try { + $this->gpm->calculateMergedDependenciesOfPackages($packages); + $this->fail("Expected Exception not thrown"); + } catch (Exception $e) { + $this->assertEquals(EXCEPTION_BAD_FORMAT, $e->getCode()); + $this->assertStringStartsWith("Bad format for version of dependency", $e->getMessage()); + } + + ////////////////////////////////////////////////////////////////////////////////////////// + // Raise exception if incompatible versions are specified + ////////////////////////////////////////////////////////////////////////////////////////// + $this->gpm->data = [ + 'admin' => (object)[ + 'dependencies' => [ + ["name" => "errors", "version" => "~4.0"], + ] + ], + 'test' => (object)[ + 'dependencies' => [ + ["name" => "errors", "version" => "~3.0"] + ] + ], + ]; + + $packages = ['admin', 'test']; + + try { + $this->gpm->calculateMergedDependenciesOfPackages($packages); + $this->fail("Expected Exception not thrown"); + } catch (Exception $e) { + $this->assertEquals(EXCEPTION_INCOMPATIBLE_VERSIONS, $e->getCode()); + $this->assertStringEndsWith("required in two incompatible versions", $e->getMessage()); + } + + ////////////////////////////////////////////////////////////////////////////////////////// + // Test dependencies of dependencies + ////////////////////////////////////////////////////////////////////////////////////////// + $this->gpm->data = [ + 'admin' => (object)[ + 'dependencies' => [ + ["name" => "grav", "version" => ">=1.0.10"], + ["name" => "form", "version" => "~2.0"], + ["name" => "login", "version" => ">=2.0"], + ["name" => "errors", "version" => "*"], + ["name" => "problems"], + ] + ], + 'login' => (object)[ + 'dependencies' => [ + ["name" => "antimatter", "version" => ">=1.0"] + ] + ], + 'grav', + 'antimatter' => (object)[ + 'dependencies' => [ + ["name" => "something", "version" => ">=3.2"] + ] + ] + + + ]; + + $packages = ['admin']; + + $dependencies = $this->gpm->calculateMergedDependenciesOfPackages($packages); + + $this->assertInternalType('array', $dependencies); + $this->assertCount(7, $dependencies); + + $this->assertSame('>=1.0.10', $dependencies['grav']); + $this->assertArrayHasKey('errors', $dependencies); + $this->assertArrayHasKey('problems', $dependencies); + $this->assertArrayHasKey('antimatter', $dependencies); + $this->assertArrayHasKey('something', $dependencies); + $this->assertSame('>=3.2', $dependencies['something']); + } + + public function testVersionFormatIsNextSignificantRelease() + { + $this->assertFalse($this->gpm->versionFormatIsNextSignificantRelease('>=1.0')); + $this->assertFalse($this->gpm->versionFormatIsNextSignificantRelease('>=2.3.4')); + $this->assertFalse($this->gpm->versionFormatIsNextSignificantRelease('>=2.3.x')); + $this->assertFalse($this->gpm->versionFormatIsNextSignificantRelease('1.0')); + $this->assertTrue($this->gpm->versionFormatIsNextSignificantRelease('~2.3.x')); + $this->assertTrue($this->gpm->versionFormatIsNextSignificantRelease('~2.0')); + } + + public function testVersionFormatIsEqualOrHigher() + { + $this->assertTrue($this->gpm->versionFormatIsEqualOrHigher('>=1.0')); + $this->assertTrue($this->gpm->versionFormatIsEqualOrHigher('>=2.3.4')); + $this->assertTrue($this->gpm->versionFormatIsEqualOrHigher('>=2.3.x')); + $this->assertFalse($this->gpm->versionFormatIsEqualOrHigher('~2.3.x')); + $this->assertFalse($this->gpm->versionFormatIsEqualOrHigher('1.0')); + } + + public function testCheckNextSignificantReleasesAreCompatible() + { + /* + * ~1.0 is equivalent to >=1.0 < 2.0.0 + * ~1.2 is equivalent to >=1.2 <2.0.0 + * ~1.2.3 is equivalent to >=1.2.3 <1.3.0 + */ + $this->assertTrue($this->gpm->checkNextSignificantReleasesAreCompatible('1.0', '1.2')); + $this->assertTrue($this->gpm->checkNextSignificantReleasesAreCompatible('1.2', '1.0')); + $this->assertTrue($this->gpm->checkNextSignificantReleasesAreCompatible('1.0', '1.0.10')); + $this->assertTrue($this->gpm->checkNextSignificantReleasesAreCompatible('1.1', '1.1.10')); + $this->assertTrue($this->gpm->checkNextSignificantReleasesAreCompatible('30.0', '30.10')); + $this->assertTrue($this->gpm->checkNextSignificantReleasesAreCompatible('1.0', '1.1.10')); + $this->assertTrue($this->gpm->checkNextSignificantReleasesAreCompatible('1.0', '1.8')); + $this->assertTrue($this->gpm->checkNextSignificantReleasesAreCompatible('1.0.1', '1.1')); + $this->assertTrue($this->gpm->checkNextSignificantReleasesAreCompatible('2.0.0-beta', '2.0')); + $this->assertTrue($this->gpm->checkNextSignificantReleasesAreCompatible('2.0.0-rc.1', '2.0')); + $this->assertTrue($this->gpm->checkNextSignificantReleasesAreCompatible('2.0', '2.0.0-alpha')); + + $this->assertFalse($this->gpm->checkNextSignificantReleasesAreCompatible('1.0', '2.2')); + $this->assertFalse($this->gpm->checkNextSignificantReleasesAreCompatible('1.0.0-beta.1', '2.0')); + $this->assertFalse($this->gpm->checkNextSignificantReleasesAreCompatible('0.9.99', '1.0.0')); + $this->assertFalse($this->gpm->checkNextSignificantReleasesAreCompatible('0.9.99', '1.0.10')); + $this->assertFalse($this->gpm->checkNextSignificantReleasesAreCompatible('0.9.99', '1.0.10.2')); + } + + + public function testCalculateVersionNumberFromDependencyVersion() + { + $this->assertSame('2.0', $this->gpm->calculateVersionNumberFromDependencyVersion('>=2.0')); + $this->assertSame('2.0.2', $this->gpm->calculateVersionNumberFromDependencyVersion('>=2.0.2')); + $this->assertSame('2.0.2', $this->gpm->calculateVersionNumberFromDependencyVersion('~2.0.2')); + $this->assertSame('1', $this->gpm->calculateVersionNumberFromDependencyVersion('~1')); + $this->assertNull($this->gpm->calculateVersionNumberFromDependencyVersion('')); + $this->assertNull($this->gpm->calculateVersionNumberFromDependencyVersion('*')); + $this->assertSame('2.0.2', $this->gpm->calculateVersionNumberFromDependencyVersion('2.0.2')); + } +} diff --git a/tests/unit/Grav/Common/Helpers/ExcerptsTest.php b/tests/unit/Grav/Common/Helpers/ExcerptsTest.php new file mode 100644 index 0000000..0cc48a4 --- /dev/null +++ b/tests/unit/Grav/Common/Helpers/ExcerptsTest.php @@ -0,0 +1,85 @@ +grav = $grav(); + $this->pages = $this->grav['pages']; + $this->config = $this->grav['config']; + $this->uri = $this->grav['uri']; + $this->language = $this->grav['language']; + $this->old_home = $this->config->get('system.home.alias'); + $this->config->set('system.home.alias', '/item1'); + $this->config->set('system.absolute_urls', false); + $this->config->set('system.languages.supported', []); + + unset($this->grav['language']); + $this->grav['language'] = new Language($this->grav); + + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + $locator->addPath('page', '', 'tests/fake/nested-site/user/pages', false); + $this->pages->init(); + + $defaults = [ + 'extra' => false, + 'auto_line_breaks' => false, + 'auto_url_links' => false, + 'escape_markup' => false, + 'special_chars' => ['>' => 'gt', '<' => 'lt'], + ]; + $this->page = $this->pages->dispatch('/item2/item2-2'); + $this->uri->initializeWithURL('http://testing.dev/item2/item2-2')->init(); + } + + protected function _after() + { + $this->config->set('system.home.alias', $this->old_home); + } + + + public function testProcessImageHtml() + { + $this->assertRegexp('|Sample Image|', + Excerpts::processImageHtml('Sample Image', $this->page)); + $this->assertRegexp('|Sample Image|', + Excerpts::processImageHtml('Sample Image', $this->page)); + } + +} diff --git a/tests/unit/Grav/Common/InflectorTest.php b/tests/unit/Grav/Common/InflectorTest.php new file mode 100644 index 0000000..9caa3e8 --- /dev/null +++ b/tests/unit/Grav/Common/InflectorTest.php @@ -0,0 +1,147 @@ +grav = $grav(); + $this->inflector = $this->grav['inflector']; + } + + protected function _after() + { + } + + public function testPluralize() + { + $this->assertSame('words', $this->inflector->pluralize('word')); + $this->assertSame('kisses', $this->inflector->pluralize('kiss')); + $this->assertSame('volcanoes', $this->inflector->pluralize('volcanoe')); + $this->assertSame('cherries', $this->inflector->pluralize('cherry')); + $this->assertSame('days', $this->inflector->pluralize('day')); + $this->assertSame('knives', $this->inflector->pluralize('knife')); + } + + public function testSingularize() + { + $this->assertSame('word', $this->inflector->singularize('words')); + $this->assertSame('kiss', $this->inflector->singularize('kisses')); + $this->assertSame('volcanoe', $this->inflector->singularize('volcanoe')); + $this->assertSame('cherry', $this->inflector->singularize('cherries')); + $this->assertSame('day', $this->inflector->singularize('days')); + $this->assertSame('knife', $this->inflector->singularize('knives')); + } + + public function testTitleize() + { + $this->assertSame('This String Is Titleized', $this->inflector->titleize('ThisStringIsTitleized')); + $this->assertSame('This String Is Titleized', $this->inflector->titleize('this string is titleized')); + $this->assertSame('This String Is Titleized', $this->inflector->titleize('this_string_is_titleized')); + $this->assertSame('This String Is Titleized', $this->inflector->titleize('this-string-is-titleized')); + + $this->assertSame('This string is titleized', $this->inflector->titleize('ThisStringIsTitleized', 'first')); + $this->assertSame('This string is titleized', $this->inflector->titleize('this string is titleized', 'first')); + $this->assertSame('This string is titleized', $this->inflector->titleize('this_string_is_titleized', 'first')); + $this->assertSame('This string is titleized', $this->inflector->titleize('this-string-is-titleized', 'first')); + } + + public function testCamelize() + { + $this->assertSame('ThisStringIsCamelized', $this->inflector->camelize('This String Is Camelized')); + $this->assertSame('ThisStringIsCamelized', $this->inflector->camelize('thisStringIsCamelized')); + $this->assertSame('ThisStringIsCamelized', $this->inflector->camelize('This_String_Is_Camelized')); + $this->assertSame('ThisStringIsCamelized', $this->inflector->camelize('this string is camelized')); + $this->assertSame('GravSPrettyCoolMy1', $this->inflector->camelize("Grav's Pretty Cool. My #1!")); + } + + public function testUnderscorize() + { + $this->assertSame('this_string_is_underscorized', $this->inflector->underscorize('This String Is Underscorized')); + $this->assertSame('this_string_is_underscorized', $this->inflector->underscorize('ThisStringIsUnderscorized')); + $this->assertSame('this_string_is_underscorized', $this->inflector->underscorize('This_String_Is_Underscorized')); + $this->assertSame('this_string_is_underscorized', $this->inflector->underscorize('This-String-Is-Underscorized')); + } + + public function testHyphenize() + { + $this->assertSame('this-string-is-hyphenized', $this->inflector->hyphenize('This String Is Hyphenized')); + $this->assertSame('this-string-is-hyphenized', $this->inflector->hyphenize('ThisStringIsHyphenized')); + $this->assertSame('this-string-is-hyphenized', $this->inflector->hyphenize('This-String-Is-Hyphenized')); + $this->assertSame('this-string-is-hyphenized', $this->inflector->hyphenize('This_String_Is_Hyphenized')); + } + + public function testHumanize() + { + //$this->assertSame('This string is humanized', $this->inflector->humanize('ThisStringIsHumanized')); + $this->assertSame('This string is humanized', $this->inflector->humanize('this_string_is_humanized')); + //$this->assertSame('This string is humanized', $this->inflector->humanize('this-string-is-humanized')); + + $this->assertSame('This String Is Humanized', $this->inflector->humanize('this_string_is_humanized', 'all')); + //$this->assertSame('This String Is Humanized', $this->inflector->humanize('this-string-is-humanized'), 'all'); + } + + public function testVariablize() + { + $this->assertSame('thisStringIsVariablized', $this->inflector->variablize('This String Is Variablized')); + $this->assertSame('thisStringIsVariablized', $this->inflector->variablize('ThisStringIsVariablized')); + $this->assertSame('thisStringIsVariablized', $this->inflector->variablize('This_String_Is_Variablized')); + $this->assertSame('thisStringIsVariablized', $this->inflector->variablize('this string is variablized')); + $this->assertSame('gravSPrettyCoolMy1', $this->inflector->variablize("Grav's Pretty Cool. My #1!")); + } + + public function testTableize() + { + $this->assertSame('people', $this->inflector->tableize('Person')); + $this->assertSame('pages', $this->inflector->tableize('Page')); + $this->assertSame('blog_pages', $this->inflector->tableize('BlogPage')); + $this->assertSame('admin_dependencies', $this->inflector->tableize('adminDependency')); + $this->assertSame('admin_dependencies', $this->inflector->tableize('admin-dependency')); + $this->assertSame('admin_dependencies', $this->inflector->tableize('admin_dependency')); + } + + public function testClassify() + { + $this->assertSame('Person', $this->inflector->classify('people')); + $this->assertSame('Page', $this->inflector->classify('pages')); + $this->assertSame('BlogPage', $this->inflector->classify('blog_pages')); + $this->assertSame('AdminDependency', $this->inflector->classify('admin_dependencies')); + } + + public function testOrdinalize() + { + $this->assertSame('1st', $this->inflector->ordinalize(1)); + $this->assertSame('2nd', $this->inflector->ordinalize(2)); + $this->assertSame('3rd', $this->inflector->ordinalize(3)); + $this->assertSame('4th', $this->inflector->ordinalize(4)); + $this->assertSame('5th', $this->inflector->ordinalize(5)); + $this->assertSame('16th', $this->inflector->ordinalize(16)); + $this->assertSame('51st', $this->inflector->ordinalize(51)); + $this->assertSame('111th', $this->inflector->ordinalize(111)); + $this->assertSame('123rd', $this->inflector->ordinalize(123)); + } + + public function testMonthize() + { + $this->assertSame(0, $this->inflector->monthize(10)); + $this->assertSame(1, $this->inflector->monthize(33)); + $this->assertSame(1, $this->inflector->monthize(41)); + $this->assertSame(11, $this->inflector->monthize(364)); + } +} + + diff --git a/tests/unit/Grav/Common/Language/LanguageCodesTest.php b/tests/unit/Grav/Common/Language/LanguageCodesTest.php new file mode 100644 index 0000000..ef6cabc --- /dev/null +++ b/tests/unit/Grav/Common/Language/LanguageCodesTest.php @@ -0,0 +1,24 @@ +assertSame('ltr', + LanguageCodes::getOrientation('en')); + $this->assertSame('rtl', + LanguageCodes::getOrientation('ar')); + $this->assertSame('rtl', + LanguageCodes::getOrientation('he')); + $this->assertTrue(LanguageCodes::isRtl('ar')); + $this->assertFalse(LanguageCodes::isRtl('fr')); + + } + +} diff --git a/tests/unit/Grav/Common/Markdown/ParsedownTest.php b/tests/unit/Grav/Common/Markdown/ParsedownTest.php new file mode 100644 index 0000000..e73e11f --- /dev/null +++ b/tests/unit/Grav/Common/Markdown/ParsedownTest.php @@ -0,0 +1,744 @@ +grav = $grav(); + $this->pages = $this->grav['pages']; + $this->config = $this->grav['config']; + $this->uri = $this->grav['uri']; + $this->language = $this->grav['language']; + $this->old_home = $this->config->get('system.home.alias'); + $this->config->set('system.home.alias', '/item1'); + $this->config->set('system.absolute_urls', false); + $this->config->set('system.languages.supported', []); + + unset($this->grav['language']); + $this->grav['language'] = new Language($this->grav); + + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + $locator->addPath('page', '', 'tests/fake/nested-site/user/pages', false); + $this->pages->init(); + + $defaults = [ + 'extra' => false, + 'auto_line_breaks' => false, + 'auto_url_links' => false, + 'escape_markup' => false, + 'special_chars' => ['>' => 'gt', '<' => 'lt'], + ]; + $page = $this->pages->dispatch('/item2/item2-2'); + $this->parsedown = new Parsedown($page, $defaults); + } + + protected function _after() + { + $this->config->set('system.home.alias', $this->old_home); + } + + public function testImages() + { + $this->config->set('system.languages.supported', ['fr','en']); + unset($this->grav['language']); + $this->grav['language'] = new Language($this->grav); + $this->uri->initializeWithURL('http://testing.dev/fr/item2/item2-2')->init(); + + $this->assertSame('

    ', + $this->parsedown->text('![](sample-image.jpg)')); + $this->assertRegexp('|

    <\/p>|', + $this->parsedown->text('![](cache-image.jpg?cropResize=200,200&foo)')); + + $this->uri->initializeWithURL('http://testing.dev/item2/item2-2')->init(); + + $this->assertSame('

    ', + $this->parsedown->text('![](sample-image.jpg)')); + $this->assertRegexp('|

    <\/p>|', + $this->parsedown->text('![](cache-image.jpg?cropResize=200,200&foo)')); + $this->assertRegexp('|

    <\/p>|', + $this->parsedown->text('![](/home-cache-image.jpg?cache)')); + $this->assertSame('

    ', + $this->parsedown->text('![](missing-image.jpg)')); + $this->assertSame('

    ', + $this->parsedown->text('![](/home-missing-image.jpg)')); + $this->assertSame('

    ', + $this->parsedown->text('![](/home-missing-image.jpg)')); + $this->assertSame('

    ', + $this->parsedown->text('![](https://getgrav-grav.netdna-ssl.com/user/pages/media/grav-logo.svg)')); + + } + + public function testImagesSubDir() + { + $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/item2/item2-2', '/subdir')->init(); + + $this->assertRegexp('|

    <\/p>|', + $this->parsedown->text('![](/home-cache-image.jpg?cache)')); + $this->assertSame('

    ', + $this->parsedown->text('![](sample-image.jpg)')); + $this->assertRegexp('|

    <\/p>|', + $this->parsedown->text('![](cache-image.jpg?cache)')); + $this->assertSame('

    ', + $this->parsedown->text('![](missing-image.jpg)')); + $this->assertSame('

    ', + $this->parsedown->text('![](/home-missing-image.jpg)')); + + } + + public function testImagesAbsoluteUrls() + { + $this->config->set('system.absolute_urls', true); + $this->uri->initializeWithURL('http://testing.dev/item2/item2-2')->init(); + + $this->assertSame('

    ', + $this->parsedown->text('![](sample-image.jpg)')); + $this->assertRegexp('|

    <\/p>|', + $this->parsedown->text('![](cache-image.jpg?cache)')); + $this->assertRegexp('|

    <\/p>|', + $this->parsedown->text('![](/home-cache-image.jpg?cache)')); + $this->assertSame('

    ', + $this->parsedown->text('![](missing-image.jpg)')); + $this->assertSame('

    ', + $this->parsedown->text('![](/home-missing-image.jpg)')); + } + + public function testImagesSubDirAbsoluteUrls() + { + $this->config->set('system.absolute_urls', true); + $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/item2/item2-2', '/subdir')->init(); + + $this->assertSame('

    ', + $this->parsedown->text('![](sample-image.jpg)')); + $this->assertRegexp('|

    <\/p>|', + $this->parsedown->text('![](cache-image.jpg?cache)')); + $this->assertRegexp('|

    <\/p>|', + $this->parsedown->text('![](/home-cache-image.jpg?cropResize=200,200)')); + $this->assertSame('

    ', + $this->parsedown->text('![](missing-image.jpg)')); + $this->assertSame('

    ', + $this->parsedown->text('![](/home-missing-image.jpg)')); + } + + public function testImagesAttributes() + { + $this->uri->initializeWithURL('http://testing.dev/item2/item2-2')->init(); + + $this->assertSame('

    ', + $this->parsedown->text('![](sample-image.jpg "My Title")')); + $this->assertSame('

    ', + $this->parsedown->text('![](sample-image.jpg?classes=foo)')); + $this->assertSame('

    ', + $this->parsedown->text('![](sample-image.jpg?classes=foo,bar)')); + $this->assertSame('

    ', + $this->parsedown->text('![](sample-image.jpg?id=foo)')); + $this->assertSame('

    Alt Text

    ', + $this->parsedown->text('![Alt Text](sample-image.jpg?id=foo)')); + $this->assertSame('

    Alt Text

    ', + $this->parsedown->text('![Alt Text](sample-image.jpg?class=bar&id=foo)')); + $this->assertSame('

    Alt Text

    ', + $this->parsedown->text('![Alt Text](sample-image.jpg?class=bar&id=foo "My Title")')); + } + + + public function testRootImages() + { + $this->uri->initializeWithURL('http://testing.dev/')->init(); + + $defaults = [ + 'extra' => false, + 'auto_line_breaks' => false, + 'auto_url_links' => false, + 'escape_markup' => false, + 'special_chars' => ['>' => 'gt', '<' => 'lt'], + ]; + $page = $this->pages->dispatch('/'); + $this->parsedown = new Parsedown($page, $defaults); + + $this->assertSame('

    ', + $this->parsedown->text('![](home-sample-image.jpg)')); + $this->assertRegexp('|

    <\/p>|', + $this->parsedown->text('![](home-cache-image.jpg?cache)')); + $this->assertRegexp('|

    <\/p>|', + $this->parsedown->text('![](home-cache-image.jpg?cropResize=200,200&foo)')); + $this->assertSame('

    ', + $this->parsedown->text('![](/home-missing-image.jpg)')); + + $this->config->set('system.languages.supported', ['fr','en']); + unset($this->grav['language']); + $this->grav['language'] = new Language($this->grav); + $this->uri->initializeWithURL('http://testing.dev/fr/item2/item2-2')->init(); + + $this->assertSame('

    ', + $this->parsedown->text('![](home-sample-image.jpg)')); + + + } + + public function testRootImagesSubDirAbsoluteUrls() + { + $this->config->set('system.absolute_urls', true); + $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/item2/item2-2', '/subdir')->init(); + + $this->assertSame('

    ', + $this->parsedown->text('![](sample-image.jpg)')); + $this->assertRegexp('|

    <\/p>|', + $this->parsedown->text('![](cache-image.jpg?cache)')); + $this->assertRegexp('|

    <\/p>|', + $this->parsedown->text('![](/home-cache-image.jpg?cropResize=200,200)')); + $this->assertSame('

    ', + $this->parsedown->text('![](missing-image.jpg)')); + $this->assertSame('

    ', + $this->parsedown->text('![](/home-missing-image.jpg)')); + } + + public function testRootAbsoluteLinks() + { + $this->uri->initializeWithURL('http://testing.dev/')->init(); + + $defaults = [ + 'extra' => false, + 'auto_line_breaks' => false, + 'auto_url_links' => false, + 'escape_markup' => false, + 'special_chars' => ['>' => 'gt', '<' => 'lt'], + ]; + $page = $this->pages->dispatch('/'); + $this->parsedown = new Parsedown($page, $defaults); + + + $this->assertSame('

    Down a Level

    ', + $this->parsedown->text('[Down a Level](item1-3)')); + + $this->assertSame('

    Peer Page

    ', + $this->parsedown->text('[Peer Page](../item2)')); + + $this->assertSame('

    With Query

    ', + $this->parsedown->text('[With Query](?foo=bar)')); + $this->assertSame('

    With Param

    ', + $this->parsedown->text('[With Param](/foo:bar)')); + $this->assertSame('

    With Anchor

    ', + $this->parsedown->text('[With Anchor](#foo)')); + + $this->config->set('system.languages.supported', ['fr','en']); + unset($this->grav['language']); + $this->grav['language'] = new Language($this->grav); + $this->uri->initializeWithURL('http://testing.dev/fr/item2/item2-2')->init(); + + $this->assertSame('

    Peer Page

    ', + $this->parsedown->text('[Peer Page](../item2)')); + $this->assertSame('

    Down a Level

    ', + $this->parsedown->text('[Down a Level](item1-3)')); + $this->assertSame('

    With Query

    ', + $this->parsedown->text('[With Query](?foo=bar)')); + $this->assertSame('

    With Param

    ', + $this->parsedown->text('[With Param](/foo:bar)')); + $this->assertSame('

    With Anchor

    ', + $this->parsedown->text('[With Anchor](#foo)')); + } + + + public function testAnchorLinksLangRelativeUrls() + { + $this->config->set('system.languages.supported', ['fr','en']); + unset($this->grav['language']); + $this->grav['language'] = new Language($this->grav); + $this->uri->initializeWithURL('http://testing.dev/fr/item2/item2-2')->init(); + + $this->assertSame('

    Current Anchor

    ', + $this->parsedown->text('[Current Anchor](#foo)')); + $this->assertSame('

    Root Anchor

    ', + $this->parsedown->text('[Root Anchor](/#foo)')); + $this->assertSame('

    Peer Anchor

    ', + $this->parsedown->text('[Peer Anchor](../item2-1#foo)')); + $this->assertSame('

    Peer Anchor 2

    ', + $this->parsedown->text('[Peer Anchor 2](../item2-1/#foo)')); + + } + + public function testAnchorLinksLangAbsoluteUrls() + { + $this->config->set('system.absolute_urls', true); + $this->config->set('system.languages.supported', ['fr','en']); + unset($this->grav['language']); + $this->grav['language'] = new Language($this->grav); + $this->uri->initializeWithURL('http://testing.dev/fr/item2/item2-2')->init(); + + $this->assertSame('

    Current Anchor

    ', + $this->parsedown->text('[Current Anchor](#foo)')); + $this->assertSame('

    Peer Anchor

    ', + $this->parsedown->text('[Peer Anchor](../item2-1#foo)')); + $this->assertSame('

    Peer Anchor 2

    ', + $this->parsedown->text('[Peer Anchor 2](../item2-1/#foo)')); + $this->assertSame('

    Root Anchor

    ', + $this->parsedown->text('[Root Anchor](/#foo)')); + + } + + + public function testExternalLinks() + { + $this->assertSame('

    cnn.com

    ', + $this->parsedown->text('[cnn.com](http://www.cnn.com)')); + $this->assertSame('

    google.com

    ', + $this->parsedown->text('[google.com](https://www.google.com)')); + $this->assertSame('

    complex url

    ', + $this->parsedown->text('[complex url](https://github.com/getgrav/grav/issues/new?title=[add-resource]%20New%20Plugin/Theme&body=Hello%20**There**)')); + } + + public function testExternalLinksSubDir() + { + $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/item2/item2-2', '/subdir')->init(); + + $this->assertSame('

    cnn.com

    ', + $this->parsedown->text('[cnn.com](http://www.cnn.com)')); + $this->assertSame('

    google.com

    ', + $this->parsedown->text('[google.com](https://www.google.com)')); + } + + public function testExternalLinksSubDirAbsoluteUrls() + { + $this->config->set('system.absolute_urls', true); + $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/item2/item2-2', '/subdir')->init(); + + $this->assertSame('

    cnn.com

    ', + $this->parsedown->text('[cnn.com](http://www.cnn.com)')); + $this->assertSame('

    google.com

    ', + $this->parsedown->text('[google.com](https://www.google.com)')); + } + + public function testAnchorLinksRelativeUrls() + { + $this->uri->initializeWithURL('http://testing.dev/item2/item2-2')->init(); + + $this->assertSame('

    Current Anchor

    ', + $this->parsedown->text('[Current Anchor](#foo)')); + $this->assertSame('

    Root Anchor

    ', + $this->parsedown->text('[Root Anchor](/#foo)')); + $this->assertSame('

    Peer Anchor

    ', + $this->parsedown->text('[Peer Anchor](../item2-1#foo)')); + $this->assertSame('

    Peer Anchor 2

    ', + $this->parsedown->text('[Peer Anchor 2](../item2-1/#foo)')); + } + + public function testAnchorLinksAbsoluteUrls() + { + $this->config->set('system.absolute_urls', true); + $this->uri->initializeWithURL('http://testing.dev/item2/item2-2')->init(); + + $this->assertSame('

    Current Anchor

    ', + $this->parsedown->text('[Current Anchor](#foo)')); + $this->assertSame('

    Peer Anchor

    ', + $this->parsedown->text('[Peer Anchor](../item2-1#foo)')); + $this->assertSame('

    Peer Anchor 2

    ', + $this->parsedown->text('[Peer Anchor 2](../item2-1/#foo)')); + $this->assertSame('

    Root Anchor

    ', + $this->parsedown->text('[Root Anchor](/#foo)')); + } + + public function testAnchorLinksWithPortAbsoluteUrls() + { + $this->config->set('system.absolute_urls', true); + $this->uri->initializeWithURL('http://testing.dev:8080/item2/item2-2')->init(); + + $this->assertSame('

    Peer Anchor

    ', + $this->parsedown->text('[Peer Anchor](../item2-1#foo)')); + $this->assertSame('

    Peer Anchor 2

    ', + $this->parsedown->text('[Peer Anchor 2](../item2-1/#foo)')); + $this->assertSame('

    Current Anchor

    ', + $this->parsedown->text('[Current Anchor](#foo)')); + $this->assertSame('

    Root Anchor

    ', + $this->parsedown->text('[Root Anchor](/#foo)')); + } + + public function testAnchorLinksSubDirRelativeUrls() + { + $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/item2/item2-2', '/subdir')->init(); + + $this->assertSame('

    Peer Anchor

    ', + $this->parsedown->text('[Peer Anchor](../item2-1#foo)')); + $this->assertSame('

    Peer Anchor 2

    ', + $this->parsedown->text('[Peer Anchor 2](../item2-1/#foo)')); + $this->assertSame('

    Current Anchor

    ', + $this->parsedown->text('[Current Anchor](#foo)')); + $this->assertSame('

    Root Anchor

    ', + $this->parsedown->text('[Root Anchor](/#foo)')); + } + + public function testAnchorLinksSubDirAbsoluteUrls() + { + $this->config->set('system.absolute_urls', true); + $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/item2/item2-2', '/subdir')->init(); + + $this->assertSame('

    Peer Anchor

    ', + $this->parsedown->text('[Peer Anchor](../item2-1#foo)')); + $this->assertSame('

    Peer Anchor 2

    ', + $this->parsedown->text('[Peer Anchor 2](../item2-1/#foo)')); + $this->assertSame('

    Current Anchor

    ', + $this->parsedown->text('[Current Anchor](#foo)')); + $this->assertSame('

    Root Anchor

    ', + $this->parsedown->text('[Root Anchor](/#foo)')); + } + + public function testSlugRelativeLinks() + { + $this->uri->initializeWithURL('http://testing.dev/item2/item2-2')->init(); + + $this->assertSame('

    Up to Root Level

    ', + $this->parsedown->text('[Up to Root Level](../..)')); + $this->assertSame('

    Peer Page

    ', + $this->parsedown->text('[Peer Page](../item2-1)')); + $this->assertSame('

    Down a Level

    ', + $this->parsedown->text('[Down a Level](item2-2-1)')); + $this->assertSame('

    Up a Level

    ', + $this->parsedown->text('[Up a Level](..)')); + $this->assertSame('

    Up and Down

    ', + $this->parsedown->text('[Up and Down](../../item3/item3-3)')); + $this->assertSame('

    Down a Level with Query

    ', + $this->parsedown->text('[Down a Level with Query](item2-2-1?foo=bar)')); + $this->assertSame('

    Up a Level with Query

    ', + $this->parsedown->text('[Up a Level with Query](../?foo=bar)')); + $this->assertSame('

    Up and Down with Query

    ', + $this->parsedown->text('[Up and Down with Query](../../item3/item3-3?foo=bar)')); + $this->assertSame('

    Up and Down with Param

    ', + $this->parsedown->text('[Up and Down with Param](../../item3/item3-3/foo:bar)')); + $this->assertSame('

    Up and Down with Anchor

    ', + $this->parsedown->text('[Up and Down with Anchor](../../item3/item3-3#foo)')); + } + + public function testSlugRelativeLinksAbsoluteUrls() + { + $this->config->set('system.absolute_urls', true); + $this->uri->initializeWithURL('http://testing.dev/item2/item2-2')->init(); + + $this->assertSame('

    Peer Page

    ', + $this->parsedown->text('[Peer Page](../item2-1)')); + $this->assertSame('

    Down a Level

    ', + $this->parsedown->text('[Down a Level](item2-2-1)')); + $this->assertSame('

    Up a Level

    ', + $this->parsedown->text('[Up a Level](..)')); + $this->assertSame('

    Up to Root Level

    ', + $this->parsedown->text('[Up to Root Level](../..)')); + $this->assertSame('

    Up and Down

    ', + $this->parsedown->text('[Up and Down](../../item3/item3-3)')); + $this->assertSame('

    Down a Level with Query

    ', + $this->parsedown->text('[Down a Level with Query](item2-2-1?foo=bar)')); + $this->assertSame('

    Up a Level with Query

    ', + $this->parsedown->text('[Up a Level with Query](../?foo=bar)')); + $this->assertSame('

    Up and Down with Query

    ', + $this->parsedown->text('[Up and Down with Query](../../item3/item3-3?foo=bar)')); + $this->assertSame('

    Up and Down with Param

    ', + $this->parsedown->text('[Up and Down with Param](../../item3/item3-3/foo:bar)')); + $this->assertSame('

    Up and Down with Anchor

    ', + $this->parsedown->text('[Up and Down with Anchor](../../item3/item3-3#foo)')); + } + + public function testSlugRelativeLinksSubDir() + { + $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/item2/item2-2', '/subdir')->init(); + + $this->assertSame('

    Peer Page

    ', + $this->parsedown->text('[Peer Page](../item2-1)')); + $this->assertSame('

    Down a Level

    ', + $this->parsedown->text('[Down a Level](item2-2-1)')); + $this->assertSame('

    Up a Level

    ', + $this->parsedown->text('[Up a Level](..)')); + $this->assertSame('

    Up to Root Level

    ', + $this->parsedown->text('[Up to Root Level](../..)')); + $this->assertSame('

    Up and Down

    ', + $this->parsedown->text('[Up and Down](../../item3/item3-3)')); + $this->assertSame('

    Down a Level with Query

    ', + $this->parsedown->text('[Down a Level with Query](item2-2-1?foo=bar)')); + $this->assertSame('

    Up a Level with Query

    ', + $this->parsedown->text('[Up a Level with Query](../?foo=bar)')); + $this->assertSame('

    Up and Down with Query

    ', + $this->parsedown->text('[Up and Down with Query](../../item3/item3-3?foo=bar)')); + $this->assertSame('

    Up and Down with Param

    ', + $this->parsedown->text('[Up and Down with Param](../../item3/item3-3/foo:bar)')); + $this->assertSame('

    Up and Down with Anchor

    ', + $this->parsedown->text('[Up and Down with Anchor](../../item3/item3-3#foo)')); + } + + public function testSlugRelativeLinksSubDirAbsoluteUrls() + { + $this->config->set('system.absolute_urls', true); + $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/item2/item2-2', '/subdir')->init(); + + $this->assertSame('

    Peer Page

    ', + $this->parsedown->text('[Peer Page](../item2-1)')); + $this->assertSame('

    Down a Level

    ', + $this->parsedown->text('[Down a Level](item2-2-1)')); + $this->assertSame('

    Up a Level

    ', + $this->parsedown->text('[Up a Level](..)')); + $this->assertSame('

    Up to Root Level

    ', + $this->parsedown->text('[Up to Root Level](../..)')); + $this->assertSame('

    Up and Down

    ', + $this->parsedown->text('[Up and Down](../../item3/item3-3)')); + $this->assertSame('

    Down a Level with Query

    ', + $this->parsedown->text('[Down a Level with Query](item2-2-1?foo=bar)')); + $this->assertSame('

    Up a Level with Query

    ', + $this->parsedown->text('[Up a Level with Query](../?foo=bar)')); + $this->assertSame('

    Up and Down with Query

    ', + $this->parsedown->text('[Up and Down with Query](../../item3/item3-3?foo=bar)')); + $this->assertSame('

    Up and Down with Param

    ', + $this->parsedown->text('[Up and Down with Param](../../item3/item3-3/foo:bar)')); + $this->assertSame('

    Up and Down with Anchor

    ', + $this->parsedown->text('[Up and Down with Anchor](../../item3/item3-3#foo)')); + } + + + public function testDirectoryRelativeLinks() + { + $this->uri->initializeWithURL('http://testing.dev/item2/item2-2')->init(); + + $this->assertSame('

    Up and Down with Param

    ', + $this->parsedown->text('[Up and Down with Param](../../03.item3/03.item3-3/foo:bar)')); + $this->assertSame('

    Peer Page

    ', + $this->parsedown->text('[Peer Page](../01.item2-1)')); + $this->assertSame('

    Down a Level

    ', + $this->parsedown->text('[Down a Level](01.item2-2-1)')); + $this->assertSame('

    Up and Down

    ', + $this->parsedown->text('[Up and Down](../../03.item3/03.item3-3)')); + $this->assertSame('

    Down a Level with Query

    ', + $this->parsedown->text('[Down a Level with Query](01.item2-2-1?foo=bar)')); + $this->assertSame('

    Up and Down with Query

    ', + $this->parsedown->text('[Up and Down with Query](../../03.item3/03.item3-3?foo=bar)')); + $this->assertSame('

    Up and Down with Anchor

    ', + $this->parsedown->text('[Up and Down with Anchor](../../03.item3/03.item3-3#foo)')); + } + + + public function testAbsoluteLinks() + { + $this->uri->initializeWithURL('http://testing.dev/item2/item2-2')->init(); + + $this->assertSame('

    Root

    ', + $this->parsedown->text('[Root](/)')); + $this->assertSame('

    Peer Page

    ', + $this->parsedown->text('[Peer Page](/item2/item2-1)')); + $this->assertSame('

    Down a Level

    ', + $this->parsedown->text('[Down a Level](/item2/item2-2/item2-2-1)')); + $this->assertSame('

    Up a Level

    ', + $this->parsedown->text('[Up a Level](/item2)')); + $this->assertSame('

    With Query

    ', + $this->parsedown->text('[With Query](/item2?foo=bar)')); + $this->assertSame('

    With Param

    ', + $this->parsedown->text('[With Param](/item2/foo:bar)')); + $this->assertSame('

    With Anchor

    ', + $this->parsedown->text('[With Anchor](/item2#foo)')); + } + + public function testDirectoryAbsoluteLinksSubDir() + { + $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/item2/item2-2', '/subdir')->init(); + + $this->assertSame('

    Root

    ', + $this->parsedown->text('[Root](/)')); + $this->assertSame('

    Peer Page

    ', + $this->parsedown->text('[Peer Page](/item2/item2-1)')); + $this->assertSame('

    Down a Level

    ', + $this->parsedown->text('[Down a Level](/item2/item2-2/item2-2-1)')); + $this->assertSame('

    Up a Level

    ', + $this->parsedown->text('[Up a Level](/item2)')); + $this->assertSame('

    With Query

    ', + $this->parsedown->text('[With Query](/item2?foo=bar)')); + $this->assertSame('

    With Param

    ', + $this->parsedown->text('[With Param](/item2/foo:bar)')); + $this->assertSame('

    With Anchor

    ', + $this->parsedown->text('[With Anchor](/item2#foo)')); + } + + public function testDirectoryAbsoluteLinksSubDirAbsoluteUrl() + { + $this->config->set('system.absolute_urls', true); + $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/item2/item2-2', '/subdir')->init(); + + $this->assertSame('

    Root

    ', + $this->parsedown->text('[Root](/)')); + $this->assertSame('

    Peer Page

    ', + $this->parsedown->text('[Peer Page](/item2/item2-1)')); + $this->assertSame('

    Down a Level

    ', + $this->parsedown->text('[Down a Level](/item2/item2-2/item2-2-1)')); + $this->assertSame('

    Up a Level

    ', + $this->parsedown->text('[Up a Level](/item2)')); + $this->assertSame('

    With Query

    ', + $this->parsedown->text('[With Query](/item2?foo=bar)')); + $this->assertSame('

    With Param

    ', + $this->parsedown->text('[With Param](/item2/foo:bar)')); + $this->assertSame('

    With Anchor

    ', + $this->parsedown->text('[With Anchor](/item2#foo)')); + } + + public function testSpecialProtocols() + { + $this->uri->initializeWithURL('http://testing.dev/item2/item2-2')->init(); + + $this->assertSame('

    mailto

    ', + $this->parsedown->text('[mailto](mailto:user@domain.com)')); + $this->assertSame('

    xmpp

    ', + $this->parsedown->text('[xmpp](xmpp:xyx@domain.com)')); + $this->assertSame('

    tel

    ', + $this->parsedown->text('[tel](tel:123-555-12345)')); + $this->assertSame('

    sms

    ', + $this->parsedown->text('[sms](sms:123-555-12345)')); + $this->assertSame('

    ts.example.com

    ', + $this->parsedown->text('[ts.example.com](rdp://ts.example.com)')); + } + + public function testSpecialProtocolsSubDir() + { + $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/item2/item2-2', '/subdir')->init(); + + $this->assertSame('

    mailto

    ', + $this->parsedown->text('[mailto](mailto:user@domain.com)')); + $this->assertSame('

    xmpp

    ', + $this->parsedown->text('[xmpp](xmpp:xyx@domain.com)')); + $this->assertSame('

    tel

    ', + $this->parsedown->text('[tel](tel:123-555-12345)')); + $this->assertSame('

    sms

    ', + $this->parsedown->text('[sms](sms:123-555-12345)')); + $this->assertSame('

    ts.example.com

    ', + $this->parsedown->text('[ts.example.com](rdp://ts.example.com)')); + } + + public function testSpecialProtocolsSubDirAbsoluteUrl() + { + $this->config->set('system.absolute_urls', true); + $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/item2/item2-2', '/subdir')->init(); + + $this->assertSame('

    mailto

    ', + $this->parsedown->text('[mailto](mailto:user@domain.com)')); + $this->assertSame('

    xmpp

    ', + $this->parsedown->text('[xmpp](xmpp:xyx@domain.com)')); + $this->assertSame('

    tel

    ', + $this->parsedown->text('[tel](tel:123-555-12345)')); + $this->assertSame('

    sms

    ', + $this->parsedown->text('[sms](sms:123-555-12345)')); + $this->assertSame('

    ts.example.com

    ', + $this->parsedown->text('[ts.example.com](rdp://ts.example.com)')); + } + + public function testReferenceLinks() + { + $this->uri->initializeWithURL('http://testing.dev/item2/item2-2')->init(); + + $sample = '[relative link][r_relative] + [r_relative]: ../item2-3#blah'; + $this->assertSame('

    relative link

    ', + $this->parsedown->text($sample)); + + $sample = '[absolute link][r_absolute] + [r_absolute]: /item3#blah'; + $this->assertSame('

    absolute link

    ', + $this->parsedown->text($sample)); + + $sample = '[external link][r_external] + [r_external]: http://www.cnn.com'; + $this->assertSame('

    external link

    ', + $this->parsedown->text($sample)); + } + + public function testAttributeLinks() + { + $this->uri->initializeWithURL('http://testing.dev/item2/item2-2')->init(); + + $this->assertSame('

    Anchor Class

    ', + $this->parsedown->text('[Anchor Class](?classes=button#something)')); + $this->assertSame('

    Relative Class

    ', + $this->parsedown->text('[Relative Class](../item2-3?classes=button)')); + $this->assertSame('

    Relative ID

    ', + $this->parsedown->text('[Relative ID](../item2-3?id=unique)')); + $this->assertSame('

    External

    ', + $this->parsedown->text('[External](https://github.com/getgrav/grav?classes=button,big)')); + $this->assertSame('

    Relative Noprocess

    ', + $this->parsedown->text('[Relative Noprocess](../item2-3?id=unique&noprocess)')); + $this->assertSame('

    Relative Target

    ', + $this->parsedown->text('[Relative Target](../item2-3?target=_blank)')); + $this->assertSame('

    Relative Rel

    ', + $this->parsedown->text('[Relative Rel](../item2-3?rel=nofollow)')); + $this->assertSame('

    Relative Mixed

    ', + $this->parsedown->text('[Relative Mixed](../item2-3?foo=bar&baz=qux&rel=nofollow&class=button)')); + } + + public function testInvalidLinks() + { + $this->uri->initializeWithURL('http://testing.dev/item2/item2-2')->init(); + + $this->assertSame('

    Non Existent Page

    ', + $this->parsedown->text('[Non Existent Page](no-page)')); + $this->assertSame('

    Existent File

    ', + $this->parsedown->text('[Existent File](existing-file.zip)')); + $this->assertSame('

    Non Existent File

    ', + $this->parsedown->text('[Non Existent File](missing-file.zip)')); + } + + public function testInvalidLinksSubDir() + { + $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/item2/item2-2', '/subdir')->init(); + + $this->assertSame('

    Non Existent Page

    ', + $this->parsedown->text('[Non Existent Page](no-page)')); + $this->assertSame('

    Existent File

    ', + $this->parsedown->text('[Existent File](existing-file.zip)')); + $this->assertSame('

    Non Existent File

    ', + $this->parsedown->text('[Non Existent File](missing-file.zip)')); + } + + public function testInvalidLinksSubDirAbsoluteUrl() + { + $this->config->set('system.absolute_urls', true); + $this->uri->initializeWithUrlAndRootPath('http://testing.dev/subdir/item2/item2-2', '/subdir')->init(); + + $this->assertSame('

    Non Existent Page

    ', + $this->parsedown->text('[Non Existent Page](no-page)')); + $this->assertSame('

    Existent File

    ', + $this->parsedown->text('[Existent File](existing-file.zip)')); + $this->assertSame('

    Non Existent File

    ', + $this->parsedown->text('[Non Existent File](missing-file.zip)')); + } + + + /** + * @param $string + * + * @return mixed + */ + private function stripLeadingWhitespace($string) + { + return preg_replace('/^\s*(.*)/', '', $string); + } + +} diff --git a/tests/unit/Grav/Common/Page/PagesTest.php b/tests/unit/Grav/Common/Page/PagesTest.php new file mode 100644 index 0000000..3a70571 --- /dev/null +++ b/tests/unit/Grav/Common/Page/PagesTest.php @@ -0,0 +1,281 @@ +grav = $grav(); + $this->pages = $this->grav['pages']; + $this->grav['config']->set('system.home.alias', '/home'); + + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + $locator->addPath('page', '', 'tests/fake/simple-site/user/pages', false); + $this->pages->init(); + } + + public function testBase() + { + $this->assertSame('', $this->pages->base()); + $this->pages->base('/test'); + $this->assertSame('/test', $this->pages->base()); + $this->pages->base(''); + $this->assertNull($this->pages->base()); + } + + public function testLastModified() + { + $this->assertNull($this->pages->lastModified()); + $this->pages->lastModified('test'); + $this->assertSame('test', $this->pages->lastModified()); + } + + public function testInstances() + { + $this->assertInternalType('array', $this->pages->instances()); + foreach($this->pages->instances() as $instance) { + $this->assertInstanceOf('Grav\Common\Page\Page', $instance); + } + } + + public function testRoutes() + { + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + $this->assertInternalType('array', $this->pages->routes()); + $this->assertSame($locator->findResource('tests://') . '/fake/simple-site/user/pages/01.home', $this->pages->routes()['/']); + $this->assertSame($locator->findResource('tests://') . '/fake/simple-site/user/pages/01.home', $this->pages->routes()['/home']); + $this->assertSame($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog', $this->pages->routes()['/blog']); + $this->assertSame($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-one', $this->pages->routes()['/blog/post-one']); + $this->assertSame($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-two', $this->pages->routes()['/blog/post-two']); + $this->assertSame($locator->findResource('tests://') . '/fake/simple-site/user/pages/03.about', $this->pages->routes()['/about']); + } + + public function testAddPage() + { + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + $path = $locator->findResource('tests://') . '/fake/single-pages/01.simple-page/default.md'; + $aPage = new Page(); + $aPage->init(new \SplFileInfo($path)); + + $this->pages->addPage($aPage, '/new-page'); + + $this->assertContains('/new-page', array_keys($this->pages->routes())); + $this->assertSame($locator->findResource('tests://') . '/fake/single-pages/01.simple-page', $this->pages->routes()['/new-page']); + } + + public function testSort() + { + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + $aPage = $this->pages->dispatch('/blog'); + $subPagesSorted = $this->pages->sort($aPage); + + $this->assertInternalType('array', $subPagesSorted); + $this->assertCount(2, $subPagesSorted); + + $this->assertSame($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-one', array_keys($subPagesSorted)[0]); + $this->assertSame($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-two', array_keys($subPagesSorted)[1]); + + $this->assertContains($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-one', array_keys($subPagesSorted)); + $this->assertContains($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-two', array_keys($subPagesSorted)); + + $this->assertSame(["slug" => "post-one"], $subPagesSorted[$locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-one']); + $this->assertSame(["slug" => "post-two"], $subPagesSorted[$locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-two']); + + $subPagesSorted = $this->pages->sort($aPage, null, 'desc'); + + $this->assertInternalType('array', $subPagesSorted); + $this->assertCount(2, $subPagesSorted); + + $this->assertSame($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-two', array_keys($subPagesSorted)[0]); + $this->assertSame($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-one', array_keys($subPagesSorted)[1]); + + $this->assertContains($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-one', array_keys($subPagesSorted)); + $this->assertContains($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-two', array_keys($subPagesSorted)); + + $this->assertSame(["slug" => "post-one"], $subPagesSorted[$locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-one']); + $this->assertSame(["slug" => "post-two"], $subPagesSorted[$locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-two']); + } + + public function testSortCollection() + { + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + $aPage = $this->pages->dispatch('/blog'); + $subPagesSorted = $this->pages->sortCollection($aPage->children(), $aPage->orderBy()); + + $this->assertInternalType('array', $subPagesSorted); + $this->assertCount(2, $subPagesSorted); + + $this->assertSame($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-one', array_keys($subPagesSorted)[0]); + $this->assertSame($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-two', array_keys($subPagesSorted)[1]); + + $this->assertContains($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-one', array_keys($subPagesSorted)); + $this->assertContains($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-two', array_keys($subPagesSorted)); + + $this->assertSame(["slug" => "post-one"], $subPagesSorted[$locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-one']); + $this->assertSame(["slug" => "post-two"], $subPagesSorted[$locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-two']); + + $subPagesSorted = $this->pages->sortCollection($aPage->children(), $aPage->orderBy(), 'desc'); + + $this->assertInternalType('array', $subPagesSorted); + $this->assertCount(2, $subPagesSorted); + + $this->assertSame($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-two', array_keys($subPagesSorted)[0]); + $this->assertSame($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-one', array_keys($subPagesSorted)[1]); + + $this->assertContains($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-one', array_keys($subPagesSorted)); + $this->assertContains($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-two', array_keys($subPagesSorted)); + + $this->assertSame(["slug" => "post-one"], $subPagesSorted[$locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-one']); + $this->assertSame(["slug" => "post-two"], $subPagesSorted[$locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog/post-two']); + } + + public function testGet() + { + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + //Page existing + $aPage = $this->pages->get($locator->findResource('tests://') . '/fake/simple-site/user/pages/03.about'); + $this->assertInternalType('object', $aPage); + $this->assertInstanceOf('Grav\Common\Page\Page', $aPage); + + //Page not existing + $anotherPage = $this->pages->get($locator->findResource('tests://') . '/fake/simple-site/user/pages/03.non-existing'); + $this->assertNotInternalType('object', $anotherPage); + $this->assertNull($anotherPage); + } + + public function testChildren() + { + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + //Page existing + $children = $this->pages->children($locator->findResource('tests://') . '/fake/simple-site/user/pages/02.blog'); + $this->assertInstanceOf('Grav\Common\Page\Collection', $children); + + //Page not existing + $children = $this->pages->children($locator->findResource('tests://') . '/fake/whatever/non-existing'); + $this->assertSame([], $children->toArray()); + } + + public function testDispatch() + { + $aPage = $this->pages->dispatch('/blog'); + $this->assertInstanceOf('Grav\Common\Page\Page', $aPage); + + $aPage = $this->pages->dispatch('/about'); + $this->assertInstanceOf('Grav\Common\Page\Page', $aPage); + + $aPage = $this->pages->dispatch('/blog/post-one'); + $this->assertInstanceOf('Grav\Common\Page\Page', $aPage); + + //Page not existing + $aPage = $this->pages->dispatch('/non-existing'); + $this->assertNull($aPage); + } + + public function testRoot() + { + $root = $this->pages->root(); + $this->assertInstanceOf('Grav\Common\Page\Page', $root); + $this->assertSame('pages', $root->folder()); + } + + public function testBlueprints() + { + + } + + public function testAll() + { + $this->assertInternalType('object', $this->pages->all()); + $this->assertInternalType('array', $this->pages->all()->toArray()); + foreach($this->pages->all() as $page) { + $this->assertInstanceOf('Grav\Common\Page\Page', $page); + } + } + + public function testGetList() + { + $list = $this->pages->getList(); + $this->assertInternalType('array', $list); + $this->assertSame('—-▸ Home', $list['/']); + $this->assertSame('—-▸ Blog', $list['/blog']); + } + + public function testGetTypes() + { + + } + + public function testTypes() + { + + } + + public function testModularTypes() + { + + } + + public function testPageTypes() + { + + } + + public function testAccessLevels() + { + + } + + public function testParents() + { + + } + + public function testParentsRawRoutes() + { + + } + + public function testGetHomeRoute() + { + + } + + public function testResetPages() + { + + } + +} diff --git a/tests/unit/Grav/Common/Twig/TwigExtensionTest.php b/tests/unit/Grav/Common/Twig/TwigExtensionTest.php new file mode 100644 index 0000000..56181f9 --- /dev/null +++ b/tests/unit/Grav/Common/Twig/TwigExtensionTest.php @@ -0,0 +1,208 @@ +grav = Fixtures::get('grav'); + $this->twig_ext = new TwigExtension(); + } + + public function testInflectorFilter() + { + $this->assertSame('people', $this->twig_ext->inflectorFilter('plural', 'person')); + $this->assertSame('shoe', $this->twig_ext->inflectorFilter('singular', 'shoes')); + $this->assertSame('Welcome Page', $this->twig_ext->inflectorFilter('title', 'welcome page')); + $this->assertSame('SendEmail', $this->twig_ext->inflectorFilter('camel', 'send_email')); + $this->assertSame('camel_cased', $this->twig_ext->inflectorFilter('underscor', 'CamelCased')); + $this->assertSame('something-text', $this->twig_ext->inflectorFilter('hyphen', 'Something Text')); + $this->assertSame('Something text to read', $this->twig_ext->inflectorFilter('human', 'something_text_to_read')); + $this->assertSame(5, $this->twig_ext->inflectorFilter('month', 175)); + $this->assertSame('10th', $this->twig_ext->inflectorFilter('ordinal', 10)); + } + + public function testMd5Filter() + { + $this->assertSame(md5('grav'), $this->twig_ext->md5Filter('grav')); + $this->assertSame(md5('devs@getgrav.org'), $this->twig_ext->md5Filter('devs@getgrav.org')); + } + + public function testKsortFilter() + { + $object = array("name"=>"Bob","age"=>8,"colour"=>"red"); + $this->assertSame(array("age"=>8,"colour"=>"red","name"=>"Bob"), $this->twig_ext->ksortFilter($object)); + } + + public function testContainsFilter() + { + $this->assertTrue($this->twig_ext->containsFilter('grav','grav')); + $this->assertTrue($this->twig_ext->containsFilter('So, I found this new cms, called grav, and it\'s pretty awesome guys','grav')); + } + + public function testNicetimeFilter() + { + $now = time(); + $threeMinutes = time() - (60*3); + $threeHours = time() - (60*60*3); + $threeDays = time() - (60*60*24*3); + $threeMonths = time() - (60*60*24*30*3); + $threeYears = time() - (60*60*24*365*3); + $measures = ['minutes','hours','days','months','years']; + + $this->assertSame('No date provided', $this->twig_ext->nicetimeFunc(null)); + + for ($i=0; $iassertSame('3 ' . $measures[$i] . ' ago', $this->twig_ext->nicetimeFunc($$time)); + } + } + + public function testRandomizeFilter() + { + $array = [1,2,3,4,5]; + $this->assertContains(2, $this->twig_ext->randomizeFilter($array)); + $this->assertSame($array, $this->twig_ext->randomizeFilter($array, 5)); + $this->assertSame($array[0], $this->twig_ext->randomizeFilter($array, 1)[0]); + $this->assertSame($array[3], $this->twig_ext->randomizeFilter($array, 4)[3]); + $this->assertSame($array[1], $this->twig_ext->randomizeFilter($array, 4)[1]); + } + + public function testModulusFilter() + { + $this->assertSame(3, $this->twig_ext->modulusFilter(3,4)); + $this->assertSame(1, $this->twig_ext->modulusFilter(11,2)); + $this->assertSame(0, $this->twig_ext->modulusFilter(10,2)); + $this->assertSame(2, $this->twig_ext->modulusFilter(10,4)); + } + + public function testAbsoluteUrlFilter() + { + + } + + public function testMarkdownFilter() + { + + } + + public function testStartsWithFilter() + { + + } + + public function testEndsWithFilter() + { + + } + + public function testDefinedDefaultFilter() + { + + } + + public function testRtrimFilter() + { + + } + + public function testLtrimFilter() + { + + } + + public function testRepeatFunc() + { + + } + + public function testRegexReplace() + { + + } + + public function testUrlFunc() + { + + } + + public function testEvaluateFunc() + { + + } + + public function testDump() + { + + } + + public function testGistFunc() + { + + } + + public function testRandomStringFunc() + { + + } + + public function testPadFilter() + { + + } + + public function testArrayFunc() + { + $this->assertSame('this is my text', + $this->twig_ext->regexReplace('

    this is my text

    ', '(<\/?p>)', '')); + $this->assertSame('this is my text', + $this->twig_ext->regexReplace('

    this is my text

    ', ['(

    )','(<\/p>)'], ['',''])); + } + + public function testArrayKeyValue() + { + $this->assertSame(['meat' => 'steak'], + $this->twig_ext->arrayKeyValueFunc('meat', 'steak')); + $this->assertSame(['fruit' => 'apple', 'meat' => 'steak'], + $this->twig_ext->arrayKeyValueFunc('meat', 'steak', ['fruit' => 'apple'])); + } + + public function stringFunc() + { + + } + + public function testRangeFunc() + { + $hundred = []; + for($i = 0; $i <= 100; $i++) { $hundred[] = $i; } + + + $this->assertSame([0], $this->twig_ext->rangeFunc(0, 0)); + $this->assertSame([0, 1, 2], $this->twig_ext->rangeFunc(0, 2)); + + $this->assertSame([0, 5, 10, 15], $this->twig_ext->rangeFunc(0, 16, 5)); + + // default (min 0, max 100, step 1) + $this->assertSame($hundred, $this->twig_ext->rangeFunc()); + + // 95 items, starting from 5, (min 5, max 100, step 1) + $this->assertSame(array_slice($hundred, 5), $this->twig_ext->rangeFunc(5)); + + // reversed range + $this->assertSame(array_reverse($hundred), $this->twig_ext->rangeFunc(100, 0)); + $this->assertSame([4, 2, 0], $this->twig_ext->rangeFunc(4, 0, 2)); + } +} diff --git a/tests/unit/Grav/Common/UriTest.php b/tests/unit/Grav/Common/UriTest.php new file mode 100644 index 0000000..32db8a1 --- /dev/null +++ b/tests/unit/Grav/Common/UriTest.php @@ -0,0 +1,1135 @@ + [ + 'scheme' => '', + 'user' => null, + 'password' => null, + 'host' => null, + 'port' => null, + 'path' => '/path', + 'query' => '', + 'fragment' => null, + + 'route' => '/path', + 'paths' => ['path'], + 'params' => null, + 'url' => '/path', + 'environment' => 'unknown', + 'basename' => 'path', + 'base' => '', + 'currentPage' => 1, + 'rootUrl' => '', + 'extension' => null, + 'addNonce' => '/path/nonce:{{nonce}}', + ], + '//localhost/' => [ + 'scheme' => '//', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => null, + 'path' => '/', + 'query' => '', + 'fragment' => null, + + 'route' => '/', + 'paths' => [], + 'params' => null, + 'url' => '/', + 'environment' => 'localhost', + 'basename' => '', + 'base' => '//localhost', + 'currentPage' => 1, + 'rootUrl' => '//localhost', + 'extension' => null, + 'addNonce' => '//localhost/nonce:{{nonce}}', + ], + 'http://localhost/' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 80, + 'path' => '/', + 'query' => '', + 'fragment' => null, + + 'route' => '/', + 'paths' => [], + 'params' => null, + 'url' => '/', + 'environment' => 'localhost', + 'basename' => '', + 'base' => 'http://localhost', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost', + 'extension' => null, + 'addNonce' => 'http://localhost/nonce:{{nonce}}', + ], + 'http://127.0.0.1/' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => '127.0.0.1', + 'port' => 80, + 'path' => '/', + 'query' => '', + 'fragment' => null, + + 'route' => '/', + 'paths' => [], + 'params' => null, + 'url' => '/', + 'environment' => 'localhost', + 'basename' => '', + 'base' => 'http://127.0.0.1', + 'currentPage' => 1, + 'rootUrl' => 'http://127.0.0.1', + 'extension' => null, + 'addNonce' => 'http://127.0.0.1/nonce:{{nonce}}', + ], + 'https://localhost/' => [ + 'scheme' => 'https://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 443, + 'path' => '/', + 'query' => '', + 'fragment' => null, + + 'route' => '/', + 'paths' => [], + 'params' => null, + 'url' => '/', + 'environment' => 'localhost', + 'basename' => '', + 'base' => 'https://localhost', + 'currentPage' => 1, + 'rootUrl' => 'https://localhost', + 'extension' => null, + 'addNonce' => 'https://localhost/nonce:{{nonce}}', + ], + 'http://localhost:8080/grav/it/ueper' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 8080, + 'path' => '/grav/it/ueper', + 'query' => '', + 'fragment' => null, + + 'route' => '/grav/it/ueper', + 'paths' => ['grav', 'it', 'ueper'], + 'params' => null, + 'url' => '/grav/it/ueper', + 'environment' => 'localhost', + 'basename' => 'ueper', + 'base' => 'http://localhost:8080', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost:8080', + 'extension' => null, + 'addNonce' => 'http://localhost:8080/grav/it/ueper/nonce:{{nonce}}', + ], + 'http://localhost:8080/grav/it/ueper:xxx' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 8080, + 'path' => '/grav/it', + 'query' => '', + 'fragment' => null, + + 'route' => '/grav/it', + 'paths' => ['grav', 'it'], + 'params' => '/ueper:xxx', + 'url' => '/grav/it', + 'environment' => 'localhost', + 'basename' => 'it', + 'base' => 'http://localhost:8080', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost:8080', + 'extension' => null, + 'addNonce' => 'http://localhost:8080/grav/it/ueper:xxx/nonce:{{nonce}}', + ], + 'http://localhost:8080/grav/it/ueper:xxx/page:/test:yyy' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 8080, + 'path' => '/grav/it', + 'query' => '', + 'fragment' => null, + + 'route' => '/grav/it', + 'paths' => ['grav', 'it'], + 'params' => '/ueper:xxx/page:/test:yyy', + 'url' => '/grav/it', + 'environment' => 'localhost', + 'basename' => 'it', + 'base' => 'http://localhost:8080', + 'currentPage' => '', + 'rootUrl' => 'http://localhost:8080', + 'extension' => null, + 'addNonce' => 'http://localhost:8080/grav/it/ueper:xxx/page:/test:yyy/nonce:{{nonce}}', + ], + 'http://localhost:8080/grav/it/ueper?test=x' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 8080, + 'path' => '/grav/it/ueper', + 'query' => 'test=x', + 'fragment' => null, + + 'route' => '/grav/it/ueper', + 'paths' => ['grav', 'it', 'ueper'], + 'params' => null, + 'url' => '/grav/it/ueper', + 'environment' => 'localhost', + 'basename' => 'ueper', + 'base' => 'http://localhost:8080', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost:8080', + 'extension' => null, + 'addNonce' => 'http://localhost:8080/grav/it/ueper/nonce:{{nonce}}?test=x', + ], + 'http://localhost:80/grav/it/ueper?test=x' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 80, + 'path' => '/grav/it/ueper', + 'query' => 'test=x', + 'fragment' => null, + + 'route' => '/grav/it/ueper', + 'paths' => ['grav', 'it', 'ueper'], + 'params' => null, + 'url' => '/grav/it/ueper', + 'environment' => 'localhost', + 'basename' => 'ueper', + 'base' => 'http://localhost:80', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost:80', + 'extension' => null, + 'addNonce' => 'http://localhost:80/grav/it/ueper/nonce:{{nonce}}?test=x', + ], + 'http://localhost/grav/it/ueper?test=x' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 80, + 'path' => '/grav/it/ueper', + 'query' => 'test=x', + 'fragment' => null, + + 'route' => '/grav/it/ueper', + 'paths' => ['grav', 'it', 'ueper'], + 'params' => null, + 'url' => '/grav/it/ueper', + 'environment' => 'localhost', + 'basename' => 'ueper', + 'base' => 'http://localhost', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost', + 'extension' => null, + 'addNonce' => 'http://localhost/grav/it/ueper/nonce:{{nonce}}?test=x', + ], + 'http://grav/grav/it/ueper' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'grav', + 'port' => 80, + 'path' => '/grav/it/ueper', + 'query' => '', + 'fragment' => null, + + 'route' => '/grav/it/ueper', + 'paths' => ['grav', 'it', 'ueper'], + 'params' => null, + 'url' => '/grav/it/ueper', + 'environment' => 'grav', + 'basename' => 'ueper', + 'base' => 'http://grav', + 'currentPage' => 1, + 'rootUrl' => 'http://grav', + 'extension' => null, + 'addNonce' => 'http://grav/grav/it/ueper/nonce:{{nonce}}', + ], + 'https://username:password@api.getgrav.com:4040/v1/post/128/page:x/?all=1' => [ + 'scheme' => 'https://', + 'user' => 'username', + 'password' => 'password', + 'host' => 'api.getgrav.com', + 'port' => 4040, + 'path' => '/v1/post/128/', // FIXME <- + 'query' => 'all=1', + 'fragment' => null, + + 'route' => '/v1/post/128', + 'paths' => ['v1', 'post', '128'], + 'params' => '/page:x', + 'url' => '/v1/post/128', + 'environment' => 'api.getgrav.com', + 'basename' => '128', + 'base' => 'https://api.getgrav.com:4040', + 'currentPage' => 'x', + 'rootUrl' => 'https://api.getgrav.com:4040', + 'extension' => null, + 'addNonce' => 'https://username:password@api.getgrav.com:4040/v1/post/128/page:x/nonce:{{nonce}}?all=1', + '__toString' => 'https://username:password@api.getgrav.com:4040/v1/post/128/page:x?all=1' + ], + 'https://google.com:443/' => [ + 'scheme' => 'https://', + 'user' => null, + 'password' => null, + 'host' => 'google.com', + 'port' => 443, + 'path' => '/', + 'query' => '', + 'fragment' => null, + + 'route' => '/', + 'paths' => [], + 'params' => null, + 'url' => '/', + 'environment' => 'google.com', + 'basename' => '', + 'base' => 'https://google.com:443', + 'currentPage' => 1, + 'rootUrl' => 'https://google.com:443', + 'extension' => null, + 'addNonce' => 'https://google.com:443/nonce:{{nonce}}', + ], + // Path tests. + 'http://localhost:8080/a/b/c/d' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 8080, + 'path' => '/a/b/c/d', + 'query' => '', + 'fragment' => null, + + 'route' => '/a/b/c/d', + 'paths' => ['a', 'b', 'c', 'd'], + 'params' => null, + 'url' => '/a/b/c/d', + 'environment' => 'localhost', + 'basename' => 'd', + 'base' => 'http://localhost:8080', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost:8080', + 'extension' => null, + 'addNonce' => 'http://localhost:8080/a/b/c/d/nonce:{{nonce}}', + ], + 'http://localhost:8080/a/b/c/d/e/f/a/b/c/d/e/f/a/b/c/d/e/f' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 8080, + 'path' => '/a/b/c/d/e/f/a/b/c/d/e/f/a/b/c/d/e/f', + 'query' => '', + 'fragment' => null, + + 'route' => '/a/b/c/d/e/f/a/b/c/d/e/f/a/b/c/d/e/f', + 'paths' => ['a', 'b', 'c', 'd', 'e', 'f', 'a', 'b', 'c', 'd', 'e', 'f', 'a', 'b', 'c', 'd', 'e', 'f'], + 'params' => null, + 'url' => '/a/b/c/d/e/f/a/b/c/d/e/f/a/b/c/d/e/f', + 'environment' => 'localhost', + 'basename' => 'f', + 'base' => 'http://localhost:8080', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost:8080', + 'extension' => null, + 'addNonce' => 'http://localhost:8080/a/b/c/d/e/f/a/b/c/d/e/f/a/b/c/d/e/f/nonce:{{nonce}}', + ], + 'http://localhost/this is the path/my page' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 80, + 'path' => '/this%20is%20the%20path/my%20page', + 'query' => '', + 'fragment' => null, + + 'route' => '/this%20is%20the%20path/my%20page', + 'paths' => ['this%20is%20the%20path', 'my%20page'], + 'params' => null, + 'url' => '/this%20is%20the%20path/my%20page', + 'environment' => 'localhost', + 'basename' => 'my%20page', + 'base' => 'http://localhost', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost', + 'extension' => null, + 'addNonce' => 'http://localhost/this%20is%20the%20path/my%20page/nonce:{{nonce}}', + '__toString' => 'http://localhost/this%20is%20the%20path/my%20page' + ], + 'http://localhost/pölöpölö/päläpälä' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 80, + 'path' => '/p%C3%B6l%C3%B6p%C3%B6l%C3%B6/p%C3%A4l%C3%A4p%C3%A4l%C3%A4', + 'query' => '', + 'fragment' => null, + + 'route' => '/p%C3%B6l%C3%B6p%C3%B6l%C3%B6/p%C3%A4l%C3%A4p%C3%A4l%C3%A4', + 'paths' => ['p%C3%B6l%C3%B6p%C3%B6l%C3%B6', 'p%C3%A4l%C3%A4p%C3%A4l%C3%A4'], + 'params' => null, + 'url' => '/p%C3%B6l%C3%B6p%C3%B6l%C3%B6/p%C3%A4l%C3%A4p%C3%A4l%C3%A4', + 'environment' => 'localhost', + 'basename' => 'p%C3%A4l%C3%A4p%C3%A4l%C3%A4', + 'base' => 'http://localhost', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost', + 'extension' => null, + 'addNonce' => 'http://localhost/p%C3%B6l%C3%B6p%C3%B6l%C3%B6/p%C3%A4l%C3%A4p%C3%A4l%C3%A4/nonce:{{nonce}}', + '__toString' => 'http://localhost/p%C3%B6l%C3%B6p%C3%B6l%C3%B6/p%C3%A4l%C3%A4p%C3%A4l%C3%A4' + ], + // Query params tests. + 'http://localhost:8080/grav/it/ueper?test=x&test2=y' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 8080, + 'path' => '/grav/it/ueper', + 'query' => 'test=x&test2=y', + 'fragment' => null, + + 'route' => '/grav/it/ueper', + 'paths' => ['grav', 'it', 'ueper'], + 'params' => null, + 'url' => '/grav/it/ueper', + 'environment' => 'localhost', + 'basename' => 'ueper', + 'base' => 'http://localhost:8080', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost:8080', + 'extension' => null, + 'addNonce' => 'http://localhost:8080/grav/it/ueper/nonce:{{nonce}}?test=x&test2=y', + ], + 'http://localhost:8080/grav/it/ueper?test=x&test2=y&test3=x&test4=y' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 8080, + 'path' => '/grav/it/ueper', + 'query' => 'test=x&test2=y&test3=x&test4=y', + 'fragment' => null, + + 'route' => '/grav/it/ueper', + 'paths' => ['grav', 'it', 'ueper'], + 'params' => null, + 'url' => '/grav/it/ueper', + 'environment' => 'localhost', + 'basename' => 'ueper', + 'base' => 'http://localhost:8080', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost:8080', + 'extension' => null, + 'addNonce' => 'http://localhost:8080/grav/it/ueper/nonce:{{nonce}}?test=x&test2=y&test3=x&test4=y', + ], + 'http://localhost:8080/grav/it/ueper?test=x&test2=y&test3=x&test4=y/test' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 8080, + 'path' => '/grav/it/ueper', + 'query' => 'test=x&test2=y&test3=x&test4=y%2Ftest', + 'fragment' => null, + + 'route' => '/grav/it/ueper', + 'paths' => ['grav', 'it', 'ueper'], + 'params' => null, + 'url' => '/grav/it/ueper', + 'environment' => 'localhost', + 'basename' => 'ueper', + 'base' => 'http://localhost:8080', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost:8080', + 'extension' => null, + 'addNonce' => 'http://localhost:8080/grav/it/ueper/nonce:{{nonce}}?test=x&test2=y&test3=x&test4=y/test', + ], + // Port tests. + 'http://localhost/a-page' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 80, + 'path' => '/a-page', + 'query' => '', + 'fragment' => null, + + 'route' => '/a-page', + 'paths' => ['a-page'], + 'params' => null, + 'url' => '/a-page', + 'environment' => 'localhost', + 'basename' => 'a-page', + 'base' => 'http://localhost', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost', + 'extension' => null, + 'addNonce' => 'http://localhost/a-page/nonce:{{nonce}}', + ], + 'http://localhost:8080/a-page' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 8080, + 'path' => '/a-page', + 'query' => '', + 'fragment' => null, + + 'route' => '/a-page', + 'paths' => ['a-page'], + 'params' => null, + 'url' => '/a-page', + 'environment' => 'localhost', + 'basename' => 'a-page', + 'base' => 'http://localhost:8080', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost:8080', + 'extension' => null, + 'addNonce' => 'http://localhost:8080/a-page/nonce:{{nonce}}', + ], + 'http://localhost:443/a-page' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 443, + 'path' => '/a-page', + 'query' => '', + 'fragment' => null, + + 'route' => '/a-page', + 'paths' => ['a-page'], + 'params' => null, + 'url' => '/a-page', + 'environment' => 'localhost', + 'basename' => 'a-page', + 'base' => 'http://localhost:443', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost:443', + 'extension' => null, + 'addNonce' => 'http://localhost:443/a-page/nonce:{{nonce}}', + ], + // Extension tests. + 'http://localhost/a-page.html' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 80, + 'path' => '/a-page', + 'query' => '', + 'fragment' => null, + + 'route' => '/a-page', + 'paths' => ['a-page'], + 'params' => null, + 'url' => '/a-page', + 'environment' => 'localhost', + 'basename' => 'a-page.html', + 'base' => 'http://localhost', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost', + 'extension' => 'html', + 'addNonce' => 'http://localhost/a-page.html/nonce:{{nonce}}', + '__toString' => 'http://localhost/a-page', // FIXME <- + ], + 'http://localhost/a-page.json' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 80, + 'path' => '/a-page', + 'query' => '', + 'fragment' => null, + + 'route' => '/a-page', + 'paths' => ['a-page'], + 'params' => null, + 'url' => '/a-page', + 'environment' => 'localhost', + 'basename' => 'a-page.json', + 'base' => 'http://localhost', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost', + 'extension' => 'json', + 'addNonce' => 'http://localhost/a-page.json/nonce:{{nonce}}', + '__toString' => 'http://localhost/a-page', // FIX ME <- + ], + 'http://localhost/admin/ajax.json/task:getnewsfeed' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 80, + 'path' => '/admin/ajax', + 'query' => '', + 'fragment' => null, + + 'route' => '/admin/ajax', + 'paths' => ['admin', 'ajax'], + 'params' => '/task:getnewsfeed', + 'url' => '/admin/ajax', + 'environment' => 'localhost', + 'basename' => 'ajax.json', + 'base' => 'http://localhost', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost', + 'extension' => 'json', + 'addNonce' => 'http://localhost/admin/ajax.json/task:getnewsfeed/nonce:{{nonce}}', + '__toString' => 'http://localhost/admin/ajax/task:getnewsfeed', + ], + 'http://localhost/grav/admin/media.json/route:L1VzZXJzL3JodWsvd29ya3NwYWNlL2dyYXYtZGVtby1zYW1wbGVyL3VzZXIvYXNzZXRzL3FRMXB4Vk1ERTNJZzh5Ni5qcGc=/task:removeFileFromBlueprint/proute:/blueprint:Y29uZmlnL2RldGFpbHM=/type:config/field:deep.nested.custom_file/path:dXNlci9hc3NldHMvcVExcHhWTURFM0lnOHk2LmpwZw==' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 80, + 'path' => '/grav/admin/media', + 'query' => '', + 'fragment' => null, + + 'route' => '/grav/admin/media', + 'paths' => ['grav','admin','media'], + 'params' => '/route:L1VzZXJzL3JodWsvd29ya3NwYWNlL2dyYXYtZGVtby1zYW1wbGVyL3VzZXIvYXNzZXRzL3FRMXB4Vk1ERTNJZzh5Ni5qcGc=/task:removeFileFromBlueprint/proute:/blueprint:Y29uZmlnL2RldGFpbHM=/type:config/field:deep.nested.custom_file/path:dXNlci9hc3NldHMvcVExcHhWTURFM0lnOHk2LmpwZw==', + 'url' => '/grav/admin/media', + 'environment' => 'localhost', + 'basename' => 'media.json', + 'base' => 'http://localhost', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost', + 'extension' => 'json', + 'addNonce' => 'http://localhost/grav/admin/media.json/route:L1VzZXJzL3JodWsvd29ya3NwYWNlL2dyYXYtZGVtby1zYW1wbGVyL3VzZXIvYXNzZXRzL3FRMXB4Vk1ERTNJZzh5Ni5qcGc=/task:removeFileFromBlueprint/proute:/blueprint:Y29uZmlnL2RldGFpbHM=/type:config/field:deep.nested.custom_file/path:dXNlci9hc3NldHMvcVExcHhWTURFM0lnOHk2LmpwZw==/nonce:{{nonce}}', + '__toString' => 'http://localhost/grav/admin/media/route:L1VzZXJzL3JodWsvd29ya3NwYWNlL2dyYXYtZGVtby1zYW1wbGVyL3VzZXIvYXNzZXRzL3FRMXB4Vk1ERTNJZzh5Ni5qcGc=/task:removeFileFromBlueprint/proute:/blueprint:Y29uZmlnL2RldGFpbHM=/type:config/field:deep.nested.custom_file/path:dXNlci9hc3NldHMvcVExcHhWTURFM0lnOHk2LmpwZw==', // FIXME <- + ], + 'http://localhost/a-page.foo' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 80, + 'path' => '/a-page.foo', + 'query' => '', + 'fragment' => null, + + 'route' => '/a-page.foo', + 'paths' => ['a-page.foo'], + 'params' => null, + 'url' => '/a-page.foo', + 'environment' => 'localhost', + 'basename' => 'a-page.foo', + 'base' => 'http://localhost', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost', + 'extension' => 'foo', + 'addNonce' => 'http://localhost/a-page.foo/nonce:{{nonce}}', + '__toString' => 'http://localhost/a-page.foo' + ], + // Fragment tests. + 'http://localhost:8080/a/b/c#my-fragment' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 8080, + 'path' => '/a/b/c', + 'query' => '', + 'fragment' => 'my-fragment', + + 'route' => '/a/b/c', + 'paths' => ['a', 'b', 'c'], + 'params' => null, + 'url' => '/a/b/c', + 'environment' => 'localhost', + 'basename' => 'c', + 'base' => 'http://localhost:8080', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost:8080', + 'extension' => null, + 'addNonce' => 'http://localhost:8080/a/b/c/nonce:{{nonce}}#my-fragment', + ], + // Attacks. + '">://localhost' => [ + 'scheme' => '', + 'user' => null, + 'password' => null, + 'host' => null, + 'port' => null, + 'path' => '%22%3E%3Cscript%3Ealert%3C/localhost', + 'query' => '', + 'fragment' => null, + + 'route' => '/%22%3E%3Cscript%3Ealert%3C/localhost', + 'paths' => ['%22%3E%3Cscript%3Ealert%3C', 'localhost'], + 'params' => '/script%3E:', + 'url' => '%22%3E%3Cscript%3Ealert%3C//localhost', + 'environment' => 'unknown', + 'basename' => 'localhost', + 'base' => '', + 'currentPage' => 1, + 'rootUrl' => '', + 'extension' => null, + //'addNonce' => '%22%3E%3Cscript%3Ealert%3C/localhost/script%3E:/nonce:{{nonce}}', // FIXME <- + '__toString' => '%22%3E%3Cscript%3Ealert%3C/localhost/script%3E:' // FIXME <- + ], + 'http://">' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'unknown', + 'port' => 80, + 'path' => '/script%3E', + 'query' => '', + 'fragment' => null, + + 'route' => '/script%3E', + 'paths' => ['script%3E'], + 'params' => null, + 'url' => '/script%3E', + 'environment' => 'unknown', + 'basename' => 'script%3E', + 'base' => 'http://unknown', + 'currentPage' => 1, + 'rootUrl' => 'http://unknown', + 'extension' => null, + 'addNonce' => 'http://unknown/script%3E/nonce:{{nonce}}', + '__toString' => 'http://unknown/script%3E' + ], + 'http://localhost/">' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 80, + 'path' => '/%22%3E%3Cscript%3Ealert%3C/script%3E', + 'query' => '', + 'fragment' => null, + + 'route' => '/%22%3E%3Cscript%3Ealert%3C/script%3E', + 'paths' => ['%22%3E%3Cscript%3Ealert%3C', 'script%3E'], + 'params' => null, + 'url' => '/%22%3E%3Cscript%3Ealert%3C/script%3E', + 'environment' => 'localhost', + 'basename' => 'script%3E', + 'base' => 'http://localhost', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost', + 'extension' => null, + 'addNonce' => 'http://localhost/%22%3E%3Cscript%3Ealert%3C/script%3E/nonce:{{nonce}}', + '__toString' => 'http://localhost/%22%3E%3Cscript%3Ealert%3C/script%3E' + ], + 'http://localhost/something/p1:foo/p2:">' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 80, + 'path' => '/something/script%3E', + 'query' => '', + 'fragment' => null, + + 'route' => '/something/script%3E', + 'paths' => ['something', 'script%3E'], + 'params' => '/p1:foo/p2:%22%3E%3Cscript%3Ealert%3C', + 'url' => '/something/script%3E', + 'environment' => 'localhost', + 'basename' => 'script%3E', + 'base' => 'http://localhost', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost', + 'extension' => null, + //'addNonce' => 'http://localhost/something/script%3E/p1:foo/p2:%22%3E%3Cscript%3Ealert%3C/nonce:{{nonce}}', // FIXME <- + '__toString' => 'http://localhost/something/script%3E/p1:foo/p2:%22%3E%3Cscript%3Ealert%3C' + ], + 'http://localhost/something?p=">' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 80, + 'path' => '/something', + 'query' => 'p=%22%3E%3Cscript%3Ealert%3C%2Fscript%3E', + 'fragment' => null, + + 'route' => '/something', + 'paths' => ['something'], + 'params' => null, + 'url' => '/something', + 'environment' => 'localhost', + 'basename' => 'something', + 'base' => 'http://localhost', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost', + 'extension' => null, + 'addNonce' => 'http://localhost/something/nonce:{{nonce}}?p=%22%3E%3Cscript%3Ealert%3C/script%3E', + '__toString' => 'http://localhost/something?p=%22%3E%3Cscript%3Ealert%3C/script%3E' + ], + 'http://localhost/something#">' => [ + 'scheme' => 'http://', + 'user' => null, + 'password' => null, + 'host' => 'localhost', + 'port' => 80, + 'path' => '/something', + 'query' => '', + 'fragment' => '%22%3E%3Cscript%3Ealert%3C/script%3E', + + 'route' => '/something', + 'paths' => ['something'], + 'params' => null, + 'url' => '/something', + 'environment' => 'localhost', + 'basename' => 'something', + 'base' => 'http://localhost', + 'currentPage' => 1, + 'rootUrl' => 'http://localhost', + 'extension' => null, + 'addNonce' => 'http://localhost/something/nonce:{{nonce}}#%22%3E%3Cscript%3Ealert%3C/script%3E', + '__toString' => 'http://localhost/something#%22%3E%3Cscript%3Ealert%3C/script%3E' + ], + 'https://www.getgrav.org/something/"><' => [ + 'scheme' => 'https://', + 'user' => null, + 'password' => null, + 'host' => 'www.getgrav.org', + 'port' => 443, + 'path' => '/something/%22%3E%3Cscript%3Eeval%28atob%28%22aGlzdG9yeS5wdXNoU3RhdGUoJycsJycsJy8nKTskKCdoZWFkLGJvZHknKS5odG1sKCcnKS5sb2FkKCcvJyk7JC5wb3N0KCcvYWRtaW4nLGZ1bmN0aW9uKGRhdGEpeyQucG9zdCgkKGRhdGEpLmZpbmQoJ1tpZD1hZG1pbi11c2VyLWRldGFpbHNdIGEnKS5hdHRyKCdocmVmJykseydhZG1pbi1ub25jZSc6JChkYXRhKS5maW5kKCdbZGF0YS1jbGVhci1jYWNoZV0nKS5hdHRyKCdkYXRhLWNsZWFyLWNhY2hlJykuc3BsaXQoJzonKS5wb3AoKS50cmltKCksJ2RhdGFbcGFzc3dvcmRdJzonSW0zdjFsaDR4eDByJywndGFzayc6J3NhdmUnfSl9KQ==%22%29%29%3C/script%3E%3C', + 'query' => '', + 'fragment' => null, + + 'route' => '/something/%22%3E%3Cscript%3Eeval%28atob%28%22aGlzdG9yeS5wdXNoU3RhdGUoJycsJycsJy8nKTskKCdoZWFkLGJvZHknKS5odG1sKCcnKS5sb2FkKCcvJyk7JC5wb3N0KCcvYWRtaW4nLGZ1bmN0aW9uKGRhdGEpeyQucG9zdCgkKGRhdGEpLmZpbmQoJ1tpZD1hZG1pbi11c2VyLWRldGFpbHNdIGEnKS5hdHRyKCdocmVmJykseydhZG1pbi1ub25jZSc6JChkYXRhKS5maW5kKCdbZGF0YS1jbGVhci1jYWNoZV0nKS5hdHRyKCdkYXRhLWNsZWFyLWNhY2hlJykuc3BsaXQoJzonKS5wb3AoKS50cmltKCksJ2RhdGFbcGFzc3dvcmRdJzonSW0zdjFsaDR4eDByJywndGFzayc6J3NhdmUnfSl9KQ==%22%29%29%3C/script%3E%3C', + 'paths' => ['something', '%22%3E%3Cscript%3Eeval%28atob%28%22aGlzdG9yeS5wdXNoU3RhdGUoJycsJycsJy8nKTskKCdoZWFkLGJvZHknKS5odG1sKCcnKS5sb2FkKCcvJyk7JC5wb3N0KCcvYWRtaW4nLGZ1bmN0aW9uKGRhdGEpeyQucG9zdCgkKGRhdGEpLmZpbmQoJ1tpZD1hZG1pbi11c2VyLWRldGFpbHNdIGEnKS5hdHRyKCdocmVmJykseydhZG1pbi1ub25jZSc6JChkYXRhKS5maW5kKCdbZGF0YS1jbGVhci1jYWNoZV0nKS5hdHRyKCdkYXRhLWNsZWFyLWNhY2hlJykuc3BsaXQoJzonKS5wb3AoKS50cmltKCksJ2RhdGFbcGFzc3dvcmRdJzonSW0zdjFsaDR4eDByJywndGFzayc6J3NhdmUnfSl9KQ==%22%29%29%3C', 'script%3E%3C'], + 'params' => null, + 'url' => '/something/%22%3E%3Cscript%3Eeval%28atob%28%22aGlzdG9yeS5wdXNoU3RhdGUoJycsJycsJy8nKTskKCdoZWFkLGJvZHknKS5odG1sKCcnKS5sb2FkKCcvJyk7JC5wb3N0KCcvYWRtaW4nLGZ1bmN0aW9uKGRhdGEpeyQucG9zdCgkKGRhdGEpLmZpbmQoJ1tpZD1hZG1pbi11c2VyLWRldGFpbHNdIGEnKS5hdHRyKCdocmVmJykseydhZG1pbi1ub25jZSc6JChkYXRhKS5maW5kKCdbZGF0YS1jbGVhci1jYWNoZV0nKS5hdHRyKCdkYXRhLWNsZWFyLWNhY2hlJykuc3BsaXQoJzonKS5wb3AoKS50cmltKCksJ2RhdGFbcGFzc3dvcmRdJzonSW0zdjFsaDR4eDByJywndGFzayc6J3NhdmUnfSl9KQ==%22%29%29%3C/script%3E%3C', + 'environment' => 'www.getgrav.org', + 'basename' => 'script%3E%3C', + 'base' => 'https://www.getgrav.org', + 'currentPage' => 1, + 'rootUrl' => 'https://www.getgrav.org', + 'extension' => null, + 'addNonce' => 'https://www.getgrav.org/something/%22%3E%3Cscript%3Eeval%28atob%28%22aGlzdG9yeS5wdXNoU3RhdGUoJycsJycsJy8nKTskKCdoZWFkLGJvZHknKS5odG1sKCcnKS5sb2FkKCcvJyk7JC5wb3N0KCcvYWRtaW4nLGZ1bmN0aW9uKGRhdGEpeyQucG9zdCgkKGRhdGEpLmZpbmQoJ1tpZD1hZG1pbi11c2VyLWRldGFpbHNdIGEnKS5hdHRyKCdocmVmJykseydhZG1pbi1ub25jZSc6JChkYXRhKS5maW5kKCdbZGF0YS1jbGVhci1jYWNoZV0nKS5hdHRyKCdkYXRhLWNsZWFyLWNhY2hlJykuc3BsaXQoJzonKS5wb3AoKS50cmltKCksJ2RhdGFbcGFzc3dvcmRdJzonSW0zdjFsaDR4eDByJywndGFzayc6J3NhdmUnfSl9KQ==%22%29%29%3C/script%3E%3C/nonce:{{nonce}}', + '__toString' => 'https://www.getgrav.org/something/%22%3E%3Cscript%3Eeval%28atob%28%22aGlzdG9yeS5wdXNoU3RhdGUoJycsJycsJy8nKTskKCdoZWFkLGJvZHknKS5odG1sKCcnKS5sb2FkKCcvJyk7JC5wb3N0KCcvYWRtaW4nLGZ1bmN0aW9uKGRhdGEpeyQucG9zdCgkKGRhdGEpLmZpbmQoJ1tpZD1hZG1pbi11c2VyLWRldGFpbHNdIGEnKS5hdHRyKCdocmVmJykseydhZG1pbi1ub25jZSc6JChkYXRhKS5maW5kKCdbZGF0YS1jbGVhci1jYWNoZV0nKS5hdHRyKCdkYXRhLWNsZWFyLWNhY2hlJykuc3BsaXQoJzonKS5wb3AoKS50cmltKCksJ2RhdGFbcGFzc3dvcmRdJzonSW0zdjFsaDR4eDByJywndGFzayc6J3NhdmUnfSl9KQ==%22%29%29%3C/script%3E%3C' + ], + ]; + + protected function _before() + { + $grav = Fixtures::get('grav'); + $this->grav = $grav(); + $this->uri = $this->grav['uri']; + } + + protected function _after() + { + } + + protected function runTestSet(array $tests, $method, $params = []) + { + foreach ($tests as $url => $candidates) { + if (!array_key_exists($method, $candidates) && $method !== '__toString') { + continue; + } + if ($method === 'addNonce') { + $nonce = Utils::getNonce('test-action'); + $expected = str_replace('{{nonce}}', $nonce, $candidates[$method]); + + $this->assertSame($expected, Uri::addNonce($url, 'test-action')); + + continue; + } + + $this->uri->initializeWithURL($url)->init(); + if ($method === '__toString' && !isset($candidates[$method])) { + $expected = $url; + } else { + $expected = $candidates[$method]; + } + + if ($params) { + $result = call_user_func_array([$this->uri, $method], $params); + } else { + $result = $this->uri->{$method}(); + } + + $this->assertSame($expected, $result, "Test \$url->{$method}() for {$url}"); + // Deal with $url->query($key) + if ($method === 'query') { + parse_str($expected, $queryParams); + foreach ($queryParams as $key => $value) { + $this->assertSame($value, $this->uri->{$method}($key), "Test \$url->{$method}('{$key}') for {$url}"); + } + $this->assertNull($this->uri->{$method}('non-existing'), "Test \$url->{$method}('non-existing') for {$url}"); + } + } + } + + public function testValidatingHostname() + { + $this->assertTrue($this->uri->validateHostname('localhost')); + $this->assertTrue($this->uri->validateHostname('google.com')); + $this->assertTrue($this->uri->validateHostname('google.it')); + $this->assertTrue($this->uri->validateHostname('goog.le')); + $this->assertTrue($this->uri->validateHostname('goog.wine')); + $this->assertTrue($this->uri->validateHostname('goog.localhost')); + + $this->assertFalse($this->uri->validateHostname('localhost:80') ); + $this->assertFalse($this->uri->validateHostname('http://localhost')); + $this->assertFalse($this->uri->validateHostname('localhost!')); + } + + public function testToString() + { + $this->runTestSet($this->tests, '__toString'); + } + + public function testScheme() + { + $this->runTestSet($this->tests, 'scheme'); + } + + public function testUser() + { + $this->runTestSet($this->tests, 'user'); + } + + public function testPassword() + { + $this->runTestSet($this->tests, 'password'); + } + + public function testHost() + { + $this->runTestSet($this->tests, 'host'); + } + + public function testPort() + { + $this->runTestSet($this->tests, 'port'); + } + + public function testPath() + { + $this->runTestSet($this->tests, 'path'); + } + + public function testQuery() + { + $this->runTestSet($this->tests, 'query'); + } + + public function testFragment() + { + $this->runTestSet($this->tests, 'fragment'); + + $this->uri->fragment('something-new'); + $this->assertSame('something-new', $this->uri->fragment()); + } + + public function testPaths() + { + $this->runTestSet($this->tests, 'paths'); + } + + public function testRoute() + { + $this->runTestSet($this->tests, 'route'); + } + + public function testParams() + { + $this->runTestSet($this->tests, 'params'); + + $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx')->init(); + $this->assertSame('/ueper:xxx', $this->uri->params('ueper')); + $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx/test:yyy')->init(); + $this->assertSame('/ueper:xxx', $this->uri->params('ueper')); + $this->assertSame('/test:yyy', $this->uri->params('test')); + $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx++/test:yyy')->init(); + $this->assertSame('/ueper:xxx++/test:yyy', $this->uri->params()); + $this->assertSame('/ueper:xxx++', $this->uri->params('ueper')); + $this->assertSame('/test:yyy', $this->uri->params('test')); + $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx++/test:yyy#something')->init(); + $this->assertSame('/ueper:xxx++/test:yyy', $this->uri->params()); + $this->assertSame('/ueper:xxx++', $this->uri->params('ueper')); + $this->assertSame('/test:yyy', $this->uri->params('test')); + $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx++/test:yyy?foo=bar')->init(); + $this->assertSame('/ueper:xxx++/test:yyy', $this->uri->params()); + $this->assertSame('/ueper:xxx++', $this->uri->params('ueper')); + $this->assertSame('/test:yyy', $this->uri->params('test')); + $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x')->init(); + $this->assertNull($this->uri->params()); + $this->assertNull($this->uri->params('ueper')); + $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y')->init(); + $this->assertNull($this->uri->params()); + $this->assertNull($this->uri->params('ueper')); + $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y&test3=x&test4=y')->init(); + $this->assertNull($this->uri->params()); + $this->assertNull($this->uri->params('ueper')); + $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper?test=x&test2=y&test3=x&test4=y/test')->init(); + $this->assertNull($this->uri->params()); + $this->assertNull($this->uri->params('ueper')); + $this->uri->initializeWithURL('http://localhost:8080/a/b/c/d')->init(); + $this->assertNull($this->uri->params()); + $this->assertNull($this->uri->params('ueper')); + $this->uri->initializeWithURL('http://localhost:8080/a/b/c/d/e/f/a/b/c/d/e/f/a/b/c/d/e/f')->init(); + $this->assertNull($this->uri->params()); + $this->assertNull($this->uri->params('ueper')); + } + + public function testParam() + { + $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx')->init(); + $this->assertSame('xxx', $this->uri->param('ueper')); + $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx/test:yyy')->init(); + $this->assertSame('xxx', $this->uri->param('ueper')); + $this->assertSame('yyy', $this->uri->param('test')); + $this->uri->initializeWithURL('http://localhost:8080/grav/it/ueper:xxx++/test:yy%20y/foo:bar_baz-bank')->init(); + $this->assertSame('xxx++', $this->uri->param('ueper')); + $this->assertSame('yy y', $this->uri->param('test')); + $this->assertSame('bar_baz-bank', $this->uri->param('foo')); + } + + public function testUrl() + { + $this->runTestSet($this->tests, 'url'); + } + + public function testExtension() + { + $this->runTestSet($this->tests, 'extension'); + + $this->uri->initializeWithURL('http://localhost/a-page')->init(); + $this->assertSame('x', $this->uri->extension('x')); + } + + public function testEnvironment() + { + $this->runTestSet($this->tests, 'environment'); + } + + public function testBasename() + { + $this->runTestSet($this->tests, 'basename'); + } + + public function testBase() + { + $this->runTestSet($this->tests, 'base'); + } + + public function testRootUrl() + { + $this->runTestSet($this->tests, 'rootUrl', [true]); + + $this->uri->initializeWithUrlAndRootPath('https://localhost/grav/page-foo', '/grav')->init(); + $this->assertSame('/grav', $this->uri->rootUrl()); + $this->assertSame('https://localhost/grav', $this->uri->rootUrl(true)); + } + + public function testCurrentPage() + { + $this->runTestSet($this->tests, 'currentPage'); + + $this->uri->initializeWithURL('http://localhost:8080/a-page/page:2')->init(); + $this->assertSame('2', $this->uri->currentPage()); + } + + public function testReferrer() + { + $this->uri->initializeWithURL('http://localhost/foo/page:test')->init(); + $this->assertSame('/foo', $this->uri->referrer()); + $this->uri->initializeWithURL('http://localhost/foo/bar/page:test')->init(); + $this->assertSame('/foo/bar', $this->uri->referrer()); + } + + public function testIp() + { + $this->uri->initializeWithURL('http://localhost/foo/page:test')->init(); + $this->assertSame('UNKNOWN', Uri::ip()); + } + + public function testIsExternal() + { + $this->uri->initializeWithURL('http://localhost/')->init(); + $this->assertFalse(Uri::isExternal('/test')); + $this->assertFalse(Uri::isExternal('/foo/bar')); + $this->assertTrue(Uri::isExternal('http://localhost/test')); + $this->assertTrue(Uri::isExternal('http://google.it/test')); + } + + public function testBuildUrl() + { + $parsed_url = [ + 'scheme' => 'http', + 'host' => 'localhost', + 'port' => 8080, + ]; + + $this->assertSame('http://localhost:8080', Uri::buildUrl($parsed_url)); + + $parsed_url = [ + 'scheme' => 'http', + 'host' => 'localhost', + 'port' => 8080, + 'user' => 'foo', + 'pass' => 'bar', + 'path' => '/test', + 'query' => 'x=2', + 'fragment' => 'xxx', + ]; + + $this->assertSame('http://foo:bar@localhost:8080/test?x=2#xxx', Uri::buildUrl($parsed_url)); + } + + public function testConvertUrl() + { + + } + + public function testAddNonce() + { + $this->runTestSet($this->tests, 'addNonce'); + } +} diff --git a/tests/unit/Grav/Common/UtilsTest.php b/tests/unit/Grav/Common/UtilsTest.php new file mode 100644 index 0000000..5e3684c --- /dev/null +++ b/tests/unit/Grav/Common/UtilsTest.php @@ -0,0 +1,333 @@ +grav = $grav(); + } + + protected function _after() + { + } + + public function testStartsWith() + { + $this->assertTrue(Utils::startsWith('english', 'en')); + $this->assertTrue(Utils::startsWith('English', 'En')); + $this->assertTrue(Utils::startsWith('ENGLISH', 'EN')); + $this->assertTrue(Utils::startsWith('ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH', + 'EN')); + + $this->assertFalse(Utils::startsWith('english', 'En')); + $this->assertFalse(Utils::startsWith('English', 'EN')); + $this->assertFalse(Utils::startsWith('ENGLISH', 'en')); + $this->assertFalse(Utils::startsWith('ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH', + 'e')); + } + + public function testEndsWith() + { + $this->assertTrue(Utils::endsWith('english', 'sh')); + $this->assertTrue(Utils::endsWith('EngliSh', 'Sh')); + $this->assertTrue(Utils::endsWith('ENGLISH', 'SH')); + $this->assertTrue(Utils::endsWith('ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH', + 'ENGLISH')); + + $this->assertFalse(Utils::endsWith('english', 'de')); + $this->assertFalse(Utils::endsWith('EngliSh', 'sh')); + $this->assertFalse(Utils::endsWith('ENGLISH', 'Sh')); + $this->assertFalse(Utils::endsWith('ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH', + 'DEUSTCH')); + } + + public function testContains() + { + $this->assertTrue(Utils::contains('english', 'nglis')); + $this->assertTrue(Utils::contains('EngliSh', 'gliSh')); + $this->assertTrue(Utils::contains('ENGLISH', 'ENGLI')); + $this->assertTrue(Utils::contains('ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH', + 'ENGLISH')); + + $this->assertFalse(Utils::contains('EngliSh', 'GLI')); + $this->assertFalse(Utils::contains('EngliSh', 'English')); + $this->assertFalse(Utils::contains('ENGLISH', 'SCH')); + $this->assertFalse(Utils::contains('ENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISHENGLISH', + 'DEUSTCH')); + } + + public function testSubstrToString() + { + $this->assertEquals('en', Utils::substrToString('english', 'glish')); + $this->assertEquals('english', Utils::substrToString('english', 'test')); + $this->assertNotEquals('en', Utils::substrToString('english', 'lish')); + } + + public function testMergeObjects() + { + $obj1 = new stdClass(); + $obj1->test1 = 'x'; + $obj2 = new stdClass(); + $obj2->test2 = 'y'; + + $objMerged = Utils::mergeObjects($obj1, $obj2); + + $this->assertObjectHasAttribute('test1', $objMerged); + $this->assertObjectHasAttribute('test2', $objMerged); + } + + public function testDateFormats() + { + $dateFormats = Utils::dateFormats(); + $this->assertInternalType('array', $dateFormats); + $this->assertContainsOnly('string', $dateFormats); + + $default_format = $this->grav['config']->get('system.pages.dateformat.default'); + + if ($default_format !== null) { + $this->assertArrayHasKey($default_format, $dateFormats); + } + } + + public function testTruncate() + { + $this->assertEquals('engli' . '…', Utils::truncate('english', 5)); + $this->assertEquals('english', Utils::truncate('english')); + $this->assertEquals('This is a string to truncate', Utils::truncate('This is a string to truncate')); + $this->assertEquals('Th' . '…', Utils::truncate('This is a string to truncate', 2)); + $this->assertEquals('engli' . '...', Utils::truncate('english', 5, true, " ", "...")); + $this->assertEquals('english', Utils::truncate('english')); + $this->assertEquals('This is a string to truncate', Utils::truncate('This is a string to truncate')); + $this->assertEquals('This' . '…', Utils::truncate('This is a string to truncate', 3, true)); + $this->assertEquals('', 6, true)); + + } + + public function testSafeTruncate() + { + $this->assertEquals('This' . '…', Utils::safeTruncate('This is a string to truncate', 1)); + $this->assertEquals('This' . '…', Utils::safeTruncate('This is a string to truncate', 4)); + $this->assertEquals('This is' . '…', Utils::safeTruncate('This is a string to truncate', 5)); + } + + public function testTruncateHtml() + { + $this->assertEquals('

    T...

    ', Utils::truncateHtml('

    This is a string to truncate

    ', 1)); + $this->assertEquals('

    This...

    ', Utils::truncateHtml('

    This is a string to truncate

    ', 4)); + $this->assertEquals('

    This is a...

    ', Utils::truncateHtml('

    This is a string to truncate

    ', 10)); + $this->assertEquals('

    This is a string to truncate

    ', Utils::truncateHtml('

    This is a string to truncate

    ', 100)); + $this->assertEquals('', Utils::truncateHtml('', 6)); + $this->assertEquals('
    1. item 1 so...
    ', Utils::truncateHtml('
    1. item 1 something
    2. item 2 bold
    ', 10)); + $this->assertEquals("

    This is a string.

    \n

    It splits two lines.

    ", Utils::truncateHtml("

    This is a string.

    \n

    It splits two lines.

    ", 100)); + } + + public function testSafeTruncateHtml() + { + $this->assertEquals('

    This...

    ', Utils::safeTruncateHtml('

    This is a string to truncate

    ', 1)); + $this->assertEquals('

    This is...

    ', Utils::safeTruncateHtml('

    This is a string to truncate

    ', 2)); + $this->assertEquals('

    This is a string to...

    ', Utils::safeTruncateHtml('

    This is a string to truncate

    ', 5)); + $this->assertEquals('

    This is a string to truncate

    ', Utils::safeTruncateHtml('

    This is a string to truncate

    ', 20)); + $this->assertEquals('', Utils::safeTruncateHtml('', 6)); + $this->assertEquals('
    1. item 1 something
    2. item 2...
    ', Utils::safeTruncateHtml('
    1. item 1 something
    2. item 2 bold
    ', 5)); + } + + public function testGenerateRandomString() + { + $this->assertNotEquals(Utils::generateRandomString(), Utils::generateRandomString()); + $this->assertNotEquals(Utils::generateRandomString(20), Utils::generateRandomString(20)); + } + + public function download() + { + + } + + public function testGetMimeByExtension() + { + $this->assertEquals('application/octet-stream', Utils::getMimeByExtension('')); + $this->assertEquals('text/html', Utils::getMimeByExtension('html')); + $this->assertEquals('application/json', Utils::getMimeByExtension('json')); + $this->assertEquals('application/atom+xml', Utils::getMimeByExtension('atom')); + $this->assertEquals('application/rss+xml', Utils::getMimeByExtension('rss')); + $this->assertEquals('image/jpeg', Utils::getMimeByExtension('jpg')); + $this->assertEquals('image/png', Utils::getMimeByExtension('png')); + $this->assertEquals('text/plain', Utils::getMimeByExtension('txt')); + $this->assertEquals('application/msword', Utils::getMimeByExtension('doc')); + $this->assertEquals('application/octet-stream', Utils::getMimeByExtension('foo')); + $this->assertEquals('foo/bar', Utils::getMimeByExtension('foo', 'foo/bar')); + $this->assertEquals('text/html', Utils::getMimeByExtension('foo', 'text/html')); + } + + public function testGetExtensionByMime() + { + $this->assertEquals('html', Utils::getExtensionByMime('*/*')); + $this->assertEquals('html', Utils::getExtensionByMime('text/*')); + $this->assertEquals('html', Utils::getExtensionByMime('text/html')); + $this->assertEquals('json', Utils::getExtensionByMime('application/json')); + $this->assertEquals('atom', Utils::getExtensionByMime('application/atom+xml')); + $this->assertEquals('rss', Utils::getExtensionByMime('application/rss+xml')); + $this->assertEquals('jpg', Utils::getExtensionByMime('image/jpeg')); + $this->assertEquals('png', Utils::getExtensionByMime('image/png')); + $this->assertEquals('txt', Utils::getExtensionByMime('text/plain')); + $this->assertEquals('doc', Utils::getExtensionByMime('application/msword')); + $this->assertEquals('html', Utils::getExtensionByMime('foo/bar')); + $this->assertEquals('baz', Utils::getExtensionByMime('foo/bar', 'baz')); + } + + public function testNormalizePath() + { + $this->assertEquals('/test', Utils::normalizePath('/test')); + $this->assertEquals('test', Utils::normalizePath('test')); + $this->assertEquals('test', Utils::normalizePath('../test')); + $this->assertEquals('/test', Utils::normalizePath('/../test')); + $this->assertEquals('/test2', Utils::normalizePath('/test/../test2')); + $this->assertEquals('/test/test2', Utils::normalizePath('/test/./test2')); + } + + public function testIsFunctionDisabled() + { + $disabledFunctions = explode(',', ini_get('disable_functions')); + + if ($disabledFunctions[0]) { + $this->assertEquals(Utils::isFunctionDisabled($disabledFunctions[0]), true); + } + } + + public function testTimezones() + { + $timezones = Utils::timezones(); + + $this->assertInternalType('array', $timezones); + $this->assertContainsOnly('string', $timezones); + } + + public function testArrayFilterRecursive() + { + $array = [ + 'test' => '', + 'test2' => 'test2' + ]; + + $array = Utils::arrayFilterRecursive($array, function ($k, $v) { + return !(is_null($v) || $v === ''); + }); + + $this->assertContainsOnly('string', $array); + $this->assertArrayNotHasKey('test', $array); + $this->assertArrayHasKey('test2', $array); + $this->assertEquals('test2', $array['test2']); + } + + public function testPathPrefixedByLangCode() + { + $languagesEnabled = $this->grav['config']->get('system.languages.supported', []); + $arrayOfLanguages = ['en', 'de', 'it', 'es', 'dk', 'el']; + $languagesNotEnabled = array_diff($arrayOfLanguages, $languagesEnabled); + $oneLanguageNotEnabled = reset($languagesNotEnabled); + + if (count($languagesEnabled)) { + $this->assertTrue(Utils::pathPrefixedByLangCode('/' . $languagesEnabled[0] . '/test')); + } + + $this->assertFalse(Utils::pathPrefixedByLangCode('/' . $oneLanguageNotEnabled . '/test')); + $this->assertFalse(Utils::pathPrefixedByLangCode('/test')); + $this->assertFalse(Utils::pathPrefixedByLangCode('/xx')); + $this->assertFalse(Utils::pathPrefixedByLangCode('/xx/')); + $this->assertFalse(Utils::pathPrefixedByLangCode('/')); + } + + public function testDate2timestamp() + { + $timestamp = strtotime('10 September 2000'); + $this->assertSame($timestamp, Utils::date2timestamp('10 September 2000')); + $this->assertSame($timestamp, Utils::date2timestamp('2000-09-10 00:00:00')); + } + + public function testResolve() + { + $array = [ + 'test' => [ + 'test2' => 'test2Value' + ] + ]; + + $this->assertEquals('test2Value', Utils::resolve($array, 'test.test2')); + } + + public function testGetDotNotation() + { + $array = [ + 'test' => [ + 'test2' => 'test2Value', + 'test3' => [ + 'test4' => 'test4Value' + ] + ] + ]; + + $this->assertEquals('test2Value', Utils::getDotNotation($array, 'test.test2')); + $this->assertEquals('test4Value', Utils::getDotNotation($array, 'test.test3.test4')); + $this->assertEquals('defaultValue', Utils::getDotNotation($array, 'test.non_existent', 'defaultValue')); + } + + public function testSetDotNotation() + { + $array = [ + 'test' => [ + 'test2' => 'test2Value', + 'test3' => [ + 'test4' => 'test4Value' + ] + ] + ]; + + $new = [ + 'test1' => 'test1Value' + ]; + + Utils::setDotNotation($array, 'test.test3.test4' , $new); + $this->assertEquals('test1Value', $array['test']['test3']['test4']['test1']); + } + + public function testIsPositive() + { + $this->assertTrue(Utils::isPositive(true)); + $this->assertTrue(Utils::isPositive(1)); + $this->assertTrue(Utils::isPositive('1')); + $this->assertTrue(Utils::isPositive('yes')); + $this->assertTrue(Utils::isPositive('on')); + $this->assertTrue(Utils::isPositive('true')); + $this->assertFalse(Utils::isPositive(false)); + $this->assertFalse(Utils::isPositive(0)); + $this->assertFalse(Utils::isPositive('0')); + $this->assertFalse(Utils::isPositive('no')); + $this->assertFalse(Utils::isPositive('off')); + $this->assertFalse(Utils::isPositive('false')); + $this->assertFalse(Utils::isPositive('some')); + $this->assertFalse(Utils::isPositive(2)); + } + + public function testGetNonce() + { + $this->assertInternalType('string', Utils::getNonce('test-action')); + $this->assertInternalType('string', Utils::getNonce('test-action', true)); + $this->assertSame(Utils::getNonce('test-action'), Utils::getNonce('test-action')); + $this->assertNotSame(Utils::getNonce('test-action'), Utils::getNonce('test-action2')); + } + + public function testVerifyNonce() + { + $this->assertTrue(Utils::verifyNonce(Utils::getNonce('test-action'), 'test-action')); + } +} diff --git a/tests/unit/Grav/Console/Gpm/InstallCommandTest.php b/tests/unit/Grav/Console/Gpm/InstallCommandTest.php new file mode 100644 index 0000000..e76843b --- /dev/null +++ b/tests/unit/Grav/Console/Gpm/InstallCommandTest.php @@ -0,0 +1,28 @@ +grav = Fixtures::get('grav'); + $this->installCommand = new InstallCommand(); + + } + + protected function _after() + { + } +} \ No newline at end of file diff --git a/tests/unit/_bootstrap.php b/tests/unit/_bootstrap.php new file mode 100644 index 0000000..f92ef0c --- /dev/null +++ b/tests/unit/_bootstrap.php @@ -0,0 +1,4 @@ +Membre expert de l''Association des correcteurs
    de langue française (ACLF), certifié Voltaire
    Chef de projet « print ».' +summary: + enabled: true + format: short + size: 300 + delimiter: '===' +redirects: null +routes: null +blog: + route: /blog diff --git a/user/config/streams.yaml b/user/config/streams.yaml new file mode 100644 index 0000000..e69de29 diff --git a/user/config/system.yaml b/user/config/system.yaml new file mode 100644 index 0000000..9ce757d --- /dev/null +++ b/user/config/system.yaml @@ -0,0 +1,154 @@ +absolute_urls: false +timezone: '' +default_locale: null +param_sep: ':' +wrapped_site: false +reverse_proxy_setup: false +force_ssl: false +force_lowercase_urls: true +custom_base_url: '' +username_regex: '^[a-z0-9_-]{3,16}$' +pwd_regex: '(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}' +intl_enabled: true +languages: + supported: { } + include_default_lang: true + translations: true + translations_fallback: true + session_store_active: false + http_accept_language: false + override_locale: false +home: + alias: /home + hide_in_urls: false +pages: + theme: le_style_de_lours_modif + order: + by: default + dir: asc + list: + count: 20 + dateformat: + default: null + short: 'd-m-y G:i' + long: 'F jS \a\t g:ia' + publish_dates: true + process: + markdown: true + twig: false + twig_first: false + never_cache_twig: false + events: + page: true + twig: true + markdown: + extra: false + auto_line_breaks: true + auto_url_links: false + escape_markup: false + special_chars: + '>': gt + '<': lt + types: + - txt + - xml + - html + - htm + - json + - rss + - atom + append_url_extension: '' + expires: 604800 + cache_control: null + last_modified: false + etag: false + vary_accept_encoding: false + redirect_default_route: false + redirect_default_code: '302' + redirect_trailing_slash: true + ignore_files: + - .DS_Store + ignore_folders: + - .git + - .idea + ignore_hidden: true + url_taxonomy_filters: true + frontmatter: + process_twig: false + ignore_fields: + - form + - forms +cache: + enabled: false + check: + method: file + driver: auto + prefix: g + clear_images_by_default: false + cli_compatibility: false + lifetime: 604800 + gzip: false + allow_webserver_gzip: false + redis: + socket: false +twig: + cache: false + debug: false + auto_reload: false + autoescape: false + undefined_functions: true + undefined_filters: true + umask_fix: false +assets: + css_pipeline: false + css_pipeline_include_externals: true + css_pipeline_before_excludes: true + css_minify: true + css_minify_windows: false + css_rewrite: true + js_pipeline: false + js_pipeline_include_externals: true + js_pipeline_before_excludes: true + js_minify: true + enable_asset_timestamp: false + collections: + jquery: 'system://assets/jquery/jquery-2.x.min.js' +errors: + display: 1 + log: true +debugger: + enabled: false + shutdown: + close_connection: true + twig: true +images: + default_image_quality: 85 + cache_all: false + cache_perms: '0755' + debug: false + auto_fix_orientation: false +media: + enable_media_timestamp: false + unsupported_inline_types: { } + allowed_fallback_types: { } + auto_metadata_exif: false + upload_limit: 2097152 +session: + enabled: true + initialize: true + timeout: 1800 + name: grav-site + secure: false + httponly: true + split: true + path: null +gpm: + releases: stable + proxy_url: null + method: auto + verify_peer: true + official_gpm_only: true +strict_mode: + yaml_compat: true + twig_compat: true + blueprint_compat: true diff --git a/user/config/versions.yaml b/user/config/versions.yaml new file mode 100644 index 0000000..da9142a --- /dev/null +++ b/user/config/versions.yaml @@ -0,0 +1,6 @@ +core: + grav: + version: 1.7.48 + history: + - { version: 1.7.48, date: '2025-05-05 08:54:00' } + schema: 1.7.0_2020-11-20_1 diff --git a/user/data/.gitkeep b/user/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/user/pages/01.home/RectoHD.jpg b/user/pages/01.home/RectoHD.jpg new file mode 100644 index 0000000000000000000000000000000000000000..336f306d1297e4039cdfcc6cbf2bd9db0b8ae976 GIT binary patch literal 2057877 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]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

    NcXwv0W`MSXSGycWzjdR2=2;x!3Y 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

    Hrr2f87TUlWHF7Z1c(%&{UqxJtr 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 kXOZI51D+$+xEYd%?|JMphx^DnL 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

  • +8I3urGG`Z`x$3+%mx?G~p{y@_GC=}Fa95fA?=G8_ zterpvqUP}U;dPxZ!gA>eA&2LZxt?lo80#CZW1ZGVcRZ)E?w~LzvDCL45!Q=pC5Vnt z{Vn#37U+Vz_?vHUu0n_@I%J!92?gl32qDv4o6a_(uMKE0*|1Z?!*o}sgY_7ezb;M! zG&!jb2imo1|Ac8i>aANq2kX;%ep_)F{GG%d`j~%j+s@Oe_6$RHq-e+XC~;-ppbjEo zVrS0n>H=QSnZ_KeZ=QqA79Qe}agc>YlkWp$oels`3YXHc%aUJ7G8sF|e&UREe_I#g zGi}Ba9W!PtSV23_Tn^}&UF+qUmnUVk61DUlm@_mg>Q1sFpR zC!p?4X`*HsV1Z_^Uaq5~sbo`YsvMV{wOkkzt)`J3E`kKrb3P zKmW;cmKDIhbS3LFTC`sqMe6^u78Y=PRBk7mIYHxGC!D@Bei`lTRCU7=jWU$xy_#h% zWwaG?lt%Rz7E`i%lGi z#e-WY`JaQb`$Z{(Q-Fo`xP`*{r^gT5MIA!801QogVs25G9Hn!M@I6RziU6lL4z3?B zA~(P`?YaD)S9+Xhz~85+MH^xFk=Z~OoWr7YMx|w3(POAaIVZJfF+TU;kHKTl^S3#} zO}K4z^w=Xek`JKu=yW3^lF2D?^!U_W z=zTQsA}T97QG&Bai)cGOMhs;Yky{m|p!f{H9Z~|XvV2;k3|RwdMYQE2pc7mR9dG{N ze0T$}CKz3%i#oq`%w#%+^K z>~h855u3Feb8QhB-v*WkrgkDHzJ)_&^JZb#jU6}qP8fsu;ab4i5Q{kN8DShs|Q3q;Ci(!=p2;Nz9 z8Y?t_ktSw4)x8|0pa=a8{Zj3j%#clAAD|U;n|Yh--rY1)JrJ1C;zDnsh5`TaMNpOc z!K;@5^6zgf;uVlo|9sm|au1pXn$K1$&Mrz7u}Yf5maE<{dd*3uYc8Y1PJ!pUqOAaf>#snrLF_cB8)(Lz_;OmR~C>?W>3s)(gXIl!l zg!&cB7UG+*Q*6Fhr9&Ok|I%DKUTN!9h?=HGC(}-wHKWe`wrU|?{gOo_70$a}&%h&8 zLon6FeumO`Isrv$^RY%-;XeLR|9f@^h_B@wY+`_zJ_s1m{g3XHl41SzE5k z%+=?@Mj14IhXTi3%hyyZl|KGFsjC<@Wy7Q(4T}~d{YIN;pE=9oiknZPFrLkBn2`cz z0ifMSfQ+p~)7G(mQilD0HVHf;KbItrE(Ah)=yrcE%nsM2VrM@@Bs~?mQLmZeNx=1Nv2~|0(FmqMr<5}rY?CcBqn-8%`c?JsIKVa!9m%Z#2x*5;Q*9-B6DI85c z?-zn38-ofmqJK@Ee|DlR_YPqs0su1V5MCC6QujLKuz^tn)kYCut<2k$7yt1^K5R|8 zVPf?Fk(S?1rRhn&w+VKxBMo#=_xXZ>d$u@%7wdvmdq5(na-Hq`1DBbn`WGa#HVv=X zriKT)(GWA(%Ym74yW;kIjIR=0YQ;%$)7_m;J$HbKj%AQFgE>)SQ>R&|E$9|Xb_JcT zna`DZ2~X?t$faz}IP*iz_8}4J%i7nka5&zOKzMD`877>L+*IoXCqH-mb`oRhO)uO? zNNk>5%+>)!l;^yaFK$~>WY@z+SWaPA zp6QQO;1sc}61=s7^X(DTEfYeAvkCt2*l!_~D9}P`>VPdjn>P?NC`&zUYg<7U95=LU zp3|{^5OgsL!-YLaMoaln>FU=hEggx&_j?5@pB)J@Ln94Y?S((RJ1p;H=|vt#Z1>GQ zd~|lYLvETg+%|QZyLU=6;>}?Sqa#vJzZpm=jxi{PL3(V{qhyn>H;!3_~oyNt+K<;Gwv(WgUI# z7Cq(5{dQ`Wd%)wY)=u|dt$;oUR zzjT_az^^!>yJSI+dvrgpEDOb#D2jW zf4FI~DbW##7vo8~C_PECql%UmT&Z7CWVS0AMdL>)5Gv{6h+%JE#nS$Tf;d8uWJXM-9&g3?H;wgc9juIZlyoJs zPP|LgZD2@ZI6N|^;lIL@-|8F@N)4g5EH7*uSHdFiF{nZ1C(9_=>hIQmD*|PygQ&e ziV&}Os~WMV0{M0yCfzmmWAh8(k7Zqe&Oz+>+0vFRvmv-iZZF4Px1K5o4s^7%=+9nC z%&yhD@udXm{&Dn1kJr=SX0bF5txf+&Vc`MPgKfo2xH-Zv|L(@!u;O?`y#V=%mLw)R z6b$gdC~mR!@w2CPY&H$y20RBaYk+hP20B=dlLP-`GvRYo-hs)Di_`6Bc)U zRnJiucc*?H?w#v+al=iMA>z^|zniD&@Mljalaqk$ldHvaM1tO=t~xQeM@r&PWZ?8@oh#s}T+`pLH%CTdFPyVYC?WT1%oU}rz4&KKr;x%fF-v`<}%tY!ae z*GgSl8Bt=taS{FL3eshJc1G*=r0BVoqeEfrZ>fA{kM}A+GP3w0h6J4lNCO|LPY+#_ z+E)X?!pP7SOya+Hb_Ll{a`j5gsg^`^I`Om8m(K_T;O*U3KK~_~%Kd8}yvfhCWBqlR z{jyFV;x4uF@Tv&=H9kAU)CC0QNYe9cQj`JnT@>4Uoc;t-%GhpdDrV9XefsZc(=H;n zq3;aN%|%-R1!7i62p=}BK5868UMc_-Bon3;N`yf7+vffsO9LkmVe&kqkElGyR;_bxr3;{^SgBLZn+Fzm7Ztn;Z#@zOyKDSFAH>O-Nr^*Sj=- zWg|zhr+<#Ch47z#;GfX#%DH~ay{imkhaVP#m>C?1$!232U%UAkLrS$$*(dEf1-IA* zzV>{F(D4Yo($y$;UxIA}5zYe3<1qLZx%~_5>Bu9rwC3)N)VL(*LF$ht!jsnD{nP)R zTUMD^yB{LUC>HRyiO^j4_E)_#Dmv?98X_hvbu8gk{e650bx@+!)R=A?LyQ`?b>fIm zZvcJ}Xy_=X1xyQ_ck1lx>I@v%Alv8l)Vy9WRSB&Y$eBq*QP@R)vaPtUJQwX%ri3~2 z{&c+3N>*_tcih^Ns;((lU`Zsfpm1BD-)fgo0?Ct+1qo4@CfkKYVDd#TRyeiT2amoh zB()|QO0a5r$x3(r5CaNbg=evn$@FA#6`)w_Q3%`EEKrNI<=;6r@*)t^*jV8H_&qe582q|u#W=7`O9nAMBXu|zin0q+jWZIV za;rfuKq=3M295kg#xkW1wve+c$hyPT^gnJy!cO`r*>qSH-Q#MbpOYa#SN{6iV|orNnygj^ZVd z>(~)skp~=0SYl{%X`K?Xa1i*hR5E-`9Gky&5)Pv zHH!8#Aq9NAq_reZZ$tT*r_JS(=1Cq7oITZaq#r>xe|!UCvbJX%d{U3k^bEY0>>R`; zXo9Tb6CPJxIv!zbK>fcVmi_;GPybK6r&XbgmO>an*8Cq5hJhrv(}r4|6TS%WcUl4e zA5cB(O#cPW0d2MY*g^OB3($e+^k4Q+>tpltAn%y}GK6*zWBv)bfD9VC2$UxNm(2Q~ zAI^8oxIi}rJ^{J*|CAlJ{3{%sK=JAv?Va+49fo^#9&vA8{KxR<@91;*_L;iZMhs!! z=nbIUT!L)vJ7=08wLX4ZmP_plUfa4m5%%AH#I?8ZJRd(vTo-@*{F;@O*3ax@nlnS9 z3tb{(Zu!k;ZblUtguG1O@QGP7`ab(fDXWZAvz5qF@?xvxY3I-M%i))0nGoGY0{y%; zEpvFFkr3;)g^Id&WsH)1Ga8(_@ng|_-WTy9;^XfgT}qAGxWhbh1X;SLV*9M@V(`x9 zD=ALTqEhU;ikhz*71f@V(ZC^dc??Mq)h76q)ENZ-E*O->Yo)Au(?&22XYx~2=je0x zb7|Je@m>|HXM!n3z&mf33hg{iJ@RldVw>pmVa=nR(~-%5hNj%juA7`x;_(nJ2L@ivVb6Y6?iMX@N(zPrvXfJhWp4Nnu|##S@Kd7V#MSU&S(`T~xW+h@Xb ziU;K!<7TYstb`-b79=B+gAG;~pXCRcwAIoyok#l*HlIK9waW&UG2}FOBG>XBx4tF~ z9|JMQfXu7EHVUBoKHq(3%@Rgc?b(pY*CCxdUU~kKQQ!(dK3u~@cNG5kNUa;Ko~(aZ zzGj!>Q9foMaqldxeOJoB9^q(i!r3_bEUqpO_UuMebQ4blA9%_s&#Ovv(~-5Hg@)H( zL7tWjFOH+VIM8gLrRL;$|h(g1vbV|CoxzUSxzn3 z6m$-|!FnF#1C*~%=zwCMF&uc44rIbKs_4BQSL1n8bWYAHatmOknl@)m?5-#FQRF(> zmeQ#rq^f!qc!)SY8}LF*rY$;`H+4=QJ9^`jn$12Fhg0>u^Uo850;oOnS1~aVE8*&R z-uT5dpYH?hSr${_pvShey_uaP4#aV%PuArD8yZ5c1_$v)r@Sx)KQBuI>_E@|nzoE{ z3Ry`WB!?C&LARw|wx@9#@D`FGnaV(?9hdzQp*}(B8;`EuhuP&tvz>%t27#K=dd2O1!KN@y%`**gG z=S3f+i7QzGh}p2*8}l#D2{ssAa@aKxcL8G&y(G(AP(5{g2={vKv2cSbuIy>8eMM~A z2X{J-B1NX#!~s2l>C(Im;ifYrEtugk_q~_K2tT7`al4$Q2H`9ZmR?|YosRG_D7Z3U z7%j41U3DpH6U?`-NR66juD}P2KyO?RWapv@dIZLXdgkfaSb_9jb1li%gelS``#eYz zMx~q?s5q>hT(+d~@|*BgJjyW@DHh02JhWsh>DH6B?7G0%j9LW%GP7xJ(UK&kfJdGX zki=f2;mtFb=o12l0S37VR6*Q4MQ96g9qBePSiotb&6L2- zR&29QY6fJB zlb=rS$GEzS;!!3|iJf+D;%U5;E2yJ}iA5`>baAl1H08m-a$F}dltO64=7B9viJ{We zkL<^b`mcxCp!pxmzRC-({iQK;KLj|{*dSoZ4L@AoW@3ZXA~uNT=Sc^C-}?sm@^Alf zp0;Elsnn3lIuj22RM3_2H;i;xH3MrjXnGxFo+v&OO5R{!|M@C(#Ka5To+(KleXHl} z6QGbJSFRkUFPWWMC%=40#MytQ=fKdA#w zybiS2JA&XbNn+Dk1p)pV&eZth(%+IPf!q}5w*YPV%)ddpJ}Gv@FWger?5<2vTf&lg zvD+gSVk0g9mT7A<#w&c+6_`59FF)XEvg^BHD0@at31SXDd$hy>>>Ldpy3f$|t2Y7m z=5J`$rVf+WONZ~TC`W!<32D67@$N1WNO}YO)UPvTrLuIv33lIWUs;r9-HLRpgiIPFzv;WZbDi#G)MJw zEf?LhAwU4+`Mh z86=_hL%OZJ?FT4+6~`Z;xAJsi>~~FbpzA#+?-zvxuK$|pFR)EP5!*Rm$ZejnZ~PA+I!NrKNfv<^UaFYWQWka*nu9TO9` zXt+B%YbcAGHy&zj=AWg_FX=PTee2eC^GL*5j~MFt``xeh_ODTr7*CVSjUQPx8`=aR zqyv4jD&G6b70?SDTY4F-7`5ColbiVS&GD~0wf0Cq>s<;x?Db~&OwY9zOf&=e%sO_{ zcHI~gp%E{fisoN_R{RidvC61Zb7TKkOllsEREo~2jHaTiCnRh59fbQNrP)hCQ zYNbOo93?CotQMnQUcw7~wWx2c2t}9-P*`_5orTD>|3<{F4W`!Oq4?S>RdlA2S8u#y zT)hiB_!kAf`QX&t`DSM{mIVBCj!{>iPr?7xN%*%j^ z=Nj>%yK$<}uq7d00R`Z@F}2ePx!Vt(I)y&uv57HT?H(Ut-_Z-|0(6iGr#Z*3!O9H8 z&RfkciLHn4y)NsyM{wl!Pft;d>bAxlxYUFNKsR^0Zm9mkTvUIG@X6gY2t)KbFZ6X0 zQ1*9`#tn>Sf<4QrCBn8&U_J62^7*~{x7x!MpsI~Zp80uV0YQ@ulIIh-j$i09vexz0 zA&wR%92^HO6nY`m22d*r4ZqO2zaF}wMV5X>aq!G>vTg_Yd2&&DtZa@B_oA=35i%Q6 z>dzR3(=g8<8i=HVPbob4)vgv1n2YhHs^Eb5fD<}IOJ_%Xn@N^Z-K(h4T311?PoE;g z{nZbucBTJluN{tS!;W7|T1*4a>(VmMA63`RWUyB@(4>x@kUq1EOuV7MCL_$4VbB~N ze$zhFBpLnoN#0FhY14dsDd_6eD|oM*j5|xP1GB2LS6h{xiO$Jk7gM|#Aa|oM8iMCd ztEnl{{7r zV&XaeINPq0L80AFt$apzxuy{qv@0;{IL}9~7JsV=VT3K6z@Enz?|;bR`jU_60WJfV zX!Y{PYtsoE!3J)s@Yo0Lhi&P(`xy;_)w++NZE2n|wde8Qd9GWovH{22%w>0bm$3FR z%mpwt<)Ce3)mt-*wIq#Z!fR1a=N)5$&PmdjK5cA&7eLC;}V{y;oupZZgY-st-SQUEI^p9zMZyrp0hHq z$irN^+tK>h+xcmX9V@dJZJi8Jjk88_EWj3OsSk7=jp%}ZZJC|BPKz#>B-~5KqnpIV z=@2VG;~nzJZ=Mp6R6Ix0+jq>C=2q%b%C|(ciCiLQhkdplv{{R%jxGcEdHE05GSdei zSG>lEhcT=-MA&l2}wFVt_C-s0Ny1z4vF z#8CCF!a9Kr=_}BP%RRWjb7@bz=I)R=w)?MVI;&Kuv$E@LO>_w8N7nE0#eD5WBu+Y0 zIzLKsiZ-R4>3vM*7yeWoI3V7&1PfJnROO2TWV5rN0uZW{1{0$<0+VHXRQXO2i#&Ff z2b&kvw~%PJCf1_+;tYPbf^Nhb${T($N}Xs@6{aBSh}0py!i_Gr`l-~V6v5hD<}i30 z`%yRnRhB*mPiqzHWv_5PNrK1vJn>Sx*;>nP)KI~x4T*kC1Ei0QzT{8ct;`9aE$O<@ zgGTYpT8ZPpB`_0tqSL}e_uZ*{WY!()4mk^;Yosd5Lz~{$XYe=XsMgBPG^*<`OHS-$ zL!+S5eum46Mi4F3+8RI=CX!g@)O}XP5Vt=Tm*3zltHYw-Kq%4!OC&=hg+qembjT7X zvzHdI?W{&jFNOM)OnB=b9tNCO?!uRa_YT-uTCKg$r)m1rb^J>xAOUGy=_)Y^(kvf- zSTWrH^RfpRqCM^OR815+ZttvT&0z|xJCEhYbMCKi;YF-uEEc!Dgx^O5(s$EPb%p1h z#8;?O`h?&#@%y|s)x;NkX9k3E)B!AXz!*Bn9A<*q_XXkWf-$)f9;Jyh=XOU*E)uw} zuL6bRAHJ%mWnP(7^7dL}#lbe9p66N`@>c>U()P*Awx_Eh$kMrSMadFVvhRKrq6O%fY+}jJ{T;|jDJVtLA z_7z$_^^WolkH1ungZ^e3)F6xS95VfA7?4U;Ut7^}sn&{x>{0i&UR?E1-4WB>5WZg7 zW+_XvQm3s-2=j3lC6W$+aECbRxxsdwlSf3u!2_9BpC;bQ3!SN0Zd+wL4?GKE`s_ZUC`pNXuT{RLcq!k*xm&zI52?$gVkOVkF>;pCtU6&0 z&ZbqXwtld+>!kiQe7(rR{a#K!znei{K)ED@2v;MARy|*Tv$^Cs!1jLQ__F)iEBew# z3i6sM#1%4<_ks__CtzEI= z=LA*;Y%Q>(*k*(16MkJ_!TNooX@2?P!mF^+1H#A-Q5M*eJ&^4-{VMBR_j?5B>5*Ec z7Keku2T<2fy(;vw86MWdazA15d(w?Z5j4Dqt zA98?LS#=Ek-$tqq_BlFSlF%hc28=fCaA_4YMcyCxXGx6GSR1Q|9b##^@|dY9xW{m) zi>-?227w#ZARaP*vv>^RUJ4WZy`kqGK)5^pMV1OTRu1wG_}(f9Hio0F;vAK5=UEsJ zXBH#8sV|P3Y2pI#bN7KweB^{p8;P3A5!K9BY4`%A5sx9ye*HqB=RDrCe?u4H zv3Dgy#$8U6_YZTZ>^6w;KA>|I0U^l}XFLZ0A*nd$^Igo}ssDpu>?nxp5NHg64lKM@ zsssM<$r5VOgW5(le+V57_L(n!o%}6p?&oI@X1-UPozF9>^%d-mz?$a7ye|=Iq7hqn zf4syr?u&};yu^R`5-(jg9om*8`3u`SQE$KJ!Cb1t^@wI@qb_7#`WdKf{lyoV*VCez zqld2M{m6UtGzT*LK8hckzub580kwSG9a`!0Nf5YCugVnttgPRxR3z}5U)7hyK>5iA zku)O;84)xf?>qOG<_Dxs*{`PZ;Q6Qgou_HEqmsH--rX0iGx#p6n$plfhaBk#ET{jE@KXLicu`HD0aXYCFmaCU z3;zM8|D!Pf_xItyH0cF^n)44${p(*pYTf@TN&n{;{$1*N2h{b?yw^X-&hdXSb^tFg zfT9MZ=l^2=)Ik=j05Fmhi82-0c8;s2y`L!z(=ypHb z!IvlUmV50m#(brGg~lOU!khmBqQTEgy5?4$`vtq+{kEm@(sz^yHIO2o`N-@w^YyW_ zCR_YmHERbZD;~oKIyOIT=Ll{#XJa0tZG5w`-)^R2mR-}{2%dUc7L(zF5R*oyr9YRR zG_OanFTbyrIn4|d0lESdfUbZS8!xX%O$|D)?Ezf@Nqf{MpR9AgvpW->EseBDUJk<# zo4H)G7Sv+{bG0#~B8swCz>`q}ZStO^mYqPe_Iyqkx#YwV?Z)guDdbT$<7t`Gp z+upIKiGxRQDALeIx!>*I!ut<`UOf6b?b8vjPfWG(+1{wEBtMP^JzMkI7bJc*xY{Yi z4pb0q-4^nh^zO?d#E_26tDFxT829!cEh-&C86>y;*HTNt6QX41lCUwDMChl+P=k6m zzdvQ9g$H?VKI*ym^M=!14E*bcTbu5To5sB_r2G?*v-79OxmgWnJBDixgIsi z3XbF_)oc|+HP7Bi>ik*|Hp_A-cyfcmBsQWW1{FnZ`MAizSOa@m9HkGPLB0D+)1H3} zu<4d{HkD@LG)_z$rq5>`M+1yD6U@Bfn~*!33oM_R^4pkRoHTMe6LH6NoM1WrCmOPM zP_^n=B^03)ESUkbkkG&;rF0y1hYWJF*Y7;Fd5fnokl07tvkR%$(6KCyOR(V#s~9U> z3DG~KX%ukCdM*w4!mS1lG%SEx&gRT9FpsrMRG9K^`KG_rnIowj(pIx1y zsB~_DPNp+}wo`{KhYMUsE5uOD*P!Xaay(D>H950KDp@WJDqC*$mV|;=yZB-wA&(m& za-HRH9}1k*XMPv+`QAO)?*<@GO@u4*k;b8QHdbEHEQOL!4q^1Q-v~s&U;EhkR`uo2 z#IyzjZ<=DV!EM3qy6qyIJ;6sB6LwFLYl(S2tLraKj0&Nujt&&0xw2P<+?I|xB$Lp5 z!OyY5k5poyAY0;5Y18s&5lv&w|MW5Iw=R!157Sjw??2OQUW_KX7ue0}MO+>;N*c zVD3p6EeVDvjaxn9OgxL7u*=9@B%e9{GtXgN{ktP%$DBjUY?^!S^d^^Xp#d}EF;#pA z-#DAlAWCuevwRRev_!M{;BgS=uIOIGi8?oBb77tr8W+Yx>9E+`8C^!1uGI~X=%rN_ zq!SuPiivErp>XLfG*dhY$kr!6-}D z7`HJZZE!RxV97sP(|LYI>~`kzbZOw8P0(093c{R2$k6Vk=7TYS-5U7(1}m;(lh{w{ z_(&D*pr_~XGG1NjC5w~*;4mTh5eQaazA{-}kUC2=ISKqcM+s5+`QoycB)Xx01ZHW0 zmgQH>(V7_Pgd~rm54OtmH20ram@3`pcvn2R02kZ65bFv{o;>eD-`z$GgJ=4hKY7T_ zmi6<7O|K&Urn96~Y<><8R9!-A?c8km^wTN=5j+31`d3Hdf_bPy*pDWta*A$w{!5rm zcjc4il$y^e#kl2R{rH*C8)gsq>kb0+jCd&G+9>A}@&?3th_jcck3~OSl51fD{~wx$XiWv&U^rt_wl?^YgVR z-BhWkTHAjD2T_fL#>BUvd#gSw+G0}5We?KM&dqQ#G#yPPO%AO&<-lYLm5IT{1Msx_ zwpVW|<;AW#hbvOUL-jzIq^=jY+46Kh-&I?m%!;xnX50~kVDZ3){JK6L5A;!421xYa z@?V;s3g=!KU5xIqopBkkE}$qLJ$3~~KkExVBbb45KFebhpq1>Z655LCh5Pdyqg%CW z8FSP#qI*<|X+%3NMFmmWox90d-JoDoT%*sqMp@n6vwkWCprFSm}{dT_am1E;t# zUR-4pV;dOQ0pg=+!2Gtg5MKdn+SbTlD5=8$6z9BanbC0xtt(6oV63xc&A{u8zk+T z1C3-JRrbF}yd2L9*8^x7bLodG_t-=$lYUQxuobOJvP$b~TwpAXp0w{pSp0K)W1nb_ zbH6;C`*7lWIRITPxR&wZ>NU;G3!ek~b*fB+>;n@bEoC~lQdeBjU+`@`1 zupRrwil(VI)-8fRfzU^Tz~m68{F6e4O34@R1@a8yT3`O+{&t1u4UISVYP}%xN!Oju z*T(GoxY0K@B|G+&MOVd*WWHZoFt~s1TI8LNG&<-=c#d7q#j02vbM)z9(%QSrV^6#% zYGd85Y{WNz*l}okGy-=vhalb1nZzYhn4bA&HM%R&Xi9SCzz&4@lhB*JW9*k_dGjlwOf&A4$nv z&x}*QXE-J`kPl((vsLrxnd%e7WBrj>a|xwByL(Nnkm@+AYp(uX`HDiJpE*+f`+T3z7gAj^4sL2`x%#7*n58z?Kqp`z zFGl%mynNd{oWCEhlakOd0#p-9c+gfiDftV%>_Mw6A^LuQ!iU022U>#N!SCMyiy>&{ zLOt5F5>la*$(V`|%GnP#Yy zg_^UI)LR)mIndfdlS;?vayRV9Rgx#o@*2?2M@Q-&EMz{nGFFP~PA*KI$!rb_I@5o4 zeO}1(=3fd*eA(M4^rn*d2Mx8xDdw~=&8RAtRAjf8a!5gl_~F`A{hA%M^pK?1tgo$N z%+?*pz<2I1@tEyLRMqh9Zo44()!ZizeEha;ULLf|Ih{(0+va{>;?`wbt zUM(ibGBv%W*)YLg?Lcr!eF;Nu(H$qtlMsMAzpH{V>E@5xE+t5W9@zUbg%yg2!j`Z( z<5g?gWbmf<6r%PT8c7GzNxyrRT3XqhO7l8kJ0aN@Pqo|Kr}#tSRdH@Z;B|_CF~7I- zr`g69E1a;aj?@q6UY^h$vae0LXg^Zm%5J3-cms@)2{#XxFofGzc&V_Fx(1=Ym)ze0QAA(J+8vW;%I{7BS1>&%pC`Oyd`TQQ z;taB|_iUm55HvNu4#}jlcE32uB~QVw-6(yOt@JpXOEwZ)Ni!-(y`Y^jJ83)DE<_v` znv?Xb<_>lGJ*ok~5fV9rtZTVs1Qe7&g9S4o<6gF!{)wSe>$yRDyE|SahNfe!aJq*Q zxdd+(JL-d(v^FV|hkWgs>b$87@t&`8zdyHL#Q( zV05}_vv92J>a3dTWq(?v;^%Rf-Ti05Vfdk8#Xk)G4i(TY%tHZ&@e@vp{!{i#+*8=@i)vuL-LvvbXk>gu?T?c;mK zaL^>p;sTACLAiJ>nd3CiHAPQheurfrTacYEF^BG}W;-f>$i)_mNV_im(Z<}RiGa~` ze_;l%?o&P4l^OT19Nd*TyM%*CjB z4R2C>+}(>Kp0RkOF)rtvzlW}_my)kz4HP?}gJWDx;9i6BgnO?%E~zg0;fe78zTxGT z>UwS-Z=5W)V1l~Lh@Ne+JZNAQBUHsfo+0Tq|O(Fullx8uTcCm8SAfa@|;(a=@2`7fJvnFY%EMk ze;?o1atKP(w2~|;V$VtMcy%>+Hi@|GrT+nSB)(aCO09DTe8Uq8CXg9Zr{!{i8eO6m zTX3Y4Ap%*uT(4FQCgg7Q9X)pu9rnB;2m0X`y&)Ol8u|#)h3RlJC7Aa9P_pMxXCU!V z`s5SgOe<5j|9BL{BrknEXzx^pYP6pC72p0&)NW4&00Jvh>U}Gtk&Ftj^tGGF5i9F7 zYlJ^a?+IgE_I3p^+|ZKamkHTl+;BYpROBP*vcw-XuAr(Hc0GNPnXwNyp) zg>d1sqMp^7_#B`a4M&;j)<3xyd1&{Sf_>CuRi=h}A#wz?vxC1DpPw3M*;ih68>J;4 zT^AyA4vbAI)@KQ7-cesqU1kfflc5?jqSr;Q%l&J2`xjq=y||#wUUD#g-w>ijmy*B< zVQmx{KopbfKObeAr5X#ZQ0pC>dm3#Rj#Ma_rCZ2uBxq_%aA``tjbcAjUWj0W63%F5 zA5Hjvv;;?^($2W9h@*+`{Xy@a9rD{I98e+M5ArMfsIPlI7JtvTxDe;{=j)o@9$^+{ zSB$F6VXI}pIhW*f9oTFd zdile!TpsF`FvH9986%oX&hH_po-}rl?Ql(nmc)i&0^mMZqoscacFsTLuKwbr+3Hca z3>j}?`#fGSGuL&2w((o9g(DdJ9&d-Nj09_b)>IxU%=ey<0pop1mya}jJ&$VLo>noB z7Pb=PVYim?NbxB3N@3+4I_T{_nv$k}D!!dlz;HT30;O?hi(ME0as{g+UE?b9E?W@G zPn|`bbzg8aA@cV!VBp#E7`q~`D#OaKwho7hhfm9l6}|Hl{HD(Umo)Y}z9LvSUJ+1a zJ9e3R_msQS;K|Y6N5^H^H@(WT&gLsD5^KO#KC|*oFmw`l6q30K*`Ek?4Kg4-CF%>8 zfl73=D$SD1ZU-fJBrn~8UnA3b9ReB3GZ|-Z4*fTAzi@vi{!>-F@zADOk)#YM^WNzE zOOYlBT-cz82!Rel$@$01y6=)>afE;wUr(W5Ju7TOT>*HLX1AE+m)E@26;BgLcsc_ax|;@!#+N9}4w6X`=am3aa=Y&ZtlyQ)l#z=CXo;3^4^*t9GGEn`HrW;OX)o zTWPW?hhF=Pf=4gGMTPOI&8_Fn1fM@!;h%HHTVx_8r+4}75*`G$zLGY5bcgz`abJzP z?jm0zg8lf$w8uk0oO-C?;30)=;!lo6362%>1p84HOdQGJDlA`Q>t>XI_j&aEEMK$# zj0@?KAF=n98~SC)n1iq1k#f`F2dR*Gv(JP$5p~Mj;s+hr$?d_ZpRbzqj`h`Eph;(Z z6DYjH?hW_{_FPsJ|DT3HCo{FOhEsNZ(wFttZPahB^vprFenPoFOH8@(8A{YJQJi#h z_hVh*WwnDdV83lUIpcW*85NqTJA;;f4~4FH+I0M(%2h!(+>O39lj@ZyWP5@IteTq{eIOz{!qD{YnczmQd1Fv1J_;QKO-We3_ z>>_$pq6j*7$Q4HmZn7owQSx&8upFL8VSya3_2%D%JZuYy|_j6I!e-c(q+ z%Gi&y{@6xT2~KYR6p}t^rMqZ$?ZiPZ=IlD<==rOOk)ro`##DVGp=T86rz>14Cpo}b zlrS@$AYF&X$UZV#3bvidegG%&`dl&IibKQ=)EgmzCpWagpY|$(gR$f9v{u887+bCz z#o(`dGYy}9tRNr$=?RR}LQTUK-q9?9s{L`(kFL~-$q>Vq;ue5;&9k0({LEukDo-a`2INcLau;ALbwp-|!W=63~Sm1T0TugK!;3A>DNJ`PGCyofOndgM;|dc;lLGEco{7k1&kVQIOOFUw zW~JOUu5cuI2Am^o6dI)`Rj(+#upJ1X#6>KYNkhQ=h>!-*ro!2=yCS-R4j;7$SviL_ zCi;DsAc>#+Ls24HDtgliw$_RP{-Zw~wPW)eFtfho#)dZXpZXiamc%Kt_3QKJe2A5g zD>1AcXSg;vL-8TO{s;l_?>*^x8sn<(b=dZ2-9rH~+1d!M)cDws7vWzCBW1>*U~acG zC$iiKf@tohN?SpnH)uRbtvORv)0?2Yy_$imj5Fj%%xz2f5<8Y7=erAw&%sr2mHy@4 zDg;YE(D@E!q4O471s%zs9b=}MIw3nvjhtqOzpDBWu6bU)XVvoynZAE|=4XJrg|MJ6 zcdk~x5M*IgIxN**v?sGhI6cT}TC*ArG6KAEFO+?|~A2xglCnuXYwW zuLuA9B7hn~ZV@`fO`$C^D=1M!H=OW95nzihV-miT=UX{S+G~EOH%yp72^MP$C0F-= z7o-wQhc;Ah$u>=>-D+52xWT zVZy3t?V~U7$CH9+WeE%sv$VltCzMv9k38i#L!k4dF+9P~v+4a@r5}Jz891vfys^>Q z4)%n6g=>`7}^Z@WR91O0uMK?efLkuPY$&sca#JIErMgcew&6uBx4P~4;_na_43M` zdGezFv)Hk|lHV!iQ9;NOa2$XpU=n*F(u-!1aR|kJGFzbiQfvN+j?&wRCEzG!yDmN| z6qDdlRDP=Pv=^I}x(YKK3k1bII_mz>Y{;prDZa9O%2?#|qxNfYNT~$%TZ+Xq`@ttZ zY@P~ofh8l9q1f#4zznv~0Os06Pr2XcAQzd?8;Gl?2l*a%97g1uBa=0X`mQ+Bn@AhI zPi5nrF^)PS<*TMngZKOKE$?2TECapQwR7%&%rSnKd^ImpKy09l?Q_C66 z#id%M^uZ9VW*Q-wU}$(znmfti6l!}&$~UN7(#XM2TvSoh=pJw^%F@?Q@W&Hl)iQ&j z+(Qh7rK)Bb8Gb2F>DkFScuRU;ysap~%_`KZZ^;V~7B|zUAxE@+jTdAOZ_7?;_~g)8 zCQ2Z_a!)%`8?;##)UOWIi7{|WxO^(TbgA1@HK!gh7S5i@OmBY2T#A47;UHq$m&3&{ zX~fvbxh&8rzE(5GHethtqN(HaI|wf&J5}BlEe#V-Fj~CsLvdxl(k)?i2mjYj(08P- zML$$tec8(QUs~IXIvv~OgJ1<@CA9n4Q0i8L0_y;rT43;Hk=eCp8 zW;zXrA}ur6s<%dfnZeR_Mn(pqCvw7#dTtU8Vxq%-!Sfht*a#@~+b^KX*jA=xr(De` z1|F|oj*sI)gV zVFD((t8s%iE~ao3QHMX@C&9}?4V>=%bY;34;P?Gk-kAO; zCy9t6 zDa+5;urezGx{6AHS#D0tv7{4zvj-ZO-|;{UP!3mVB|)UYz1QOM?`(U@?|ArV&X5IXOy97op-f`VdYY1AN!e3*g;lh;yq32X!IEgLPmjPi9}tJea_9pAeBy9534dwJbblRl zQIP@Gdu%8F46CYskttr7+IQ&vu@`lnPAws>qB!JIb`b{kq*pVf4_8eg0SeuU3Kjq< zmgkIQ$NOhnWc;CbpTEb`fJZt#6!r?6MsW>mxFVI}nBMZY;N#FzO+aT- z!Jzrm-U*`=Zw($dYJ{!x4E(TS&cSJ9B@+D$Lsw>=n_n^pd7AOzgGKs$K%T#7{y^t# zWiihNKrr#x98+;Wprr%@gdxhnd?_jYv8*O-@bi0{*YSaeR-s>MEs;m_({lp)4Sk|t z0W6L=7;Yhxpup&EB?k#;0vumD3cXz#7JkC6r~Y4?#(nC^dB-%nK|%GO^!zPAgGKTY zES#~*!(v30kkOTK52y}ep7hbuw%>y}maPMFFg7Cg<0kT#PTuYD2sygPW;vf5^>6Bx zt2Ba1YcoTw55>7;-w<8g^G!&+uJ{JDH+| zC023hW!s^TiA4DI@bZgsIgz`-0tTx3f-75^j1Fu#g|*&pxZR#5Tp75Uxq!lxX{L;6 zwA|vFgk|c|k`AGN*jDD>bGbh+*t1{XAh;HlUGTG^e{dIDrX2=sBwK?Xxb-iEvT$QJ zAX2ogDzE?}Dd z=Qe@II)5IYK|YIW8u`=Qi9RWd~^()222cs&Vl;!-dSseU2lAO#G$z!_M6)`qeOh zWuK5EI~K4?2Ldb$LGmsWt<5g|`X)xRm@l+uJ~g#;F=nAoUR8Ce4Odm7LVMBYX880( zHS*7}tqn$YCI$K)mnSc-HhEux#Jpup1XAOJ$;5~64+OMbbO(z(wlc06>Lfqk_d4Pp zq|t(HNtAdTHXau(!gf|h5Y56XOp4Wh))snD&D5GGiu0K;FMI7GRgva^Q$%K7#kcEW zWsxY25B86B^{+(R^2bPemS0Cc@(xDhdu!cl_Ef)hU%Y%y6m58-%Au_dyZLbgL+F38 z0)M=raDn`_i`8&d_XKvGJ|x)s<+-mzXvww)esC$^Mkm2!N@smh!e(Jvz+%%VP$FAeCig0&|>r}m5w}qn(wq2wy z?f!gcE*{iMeL)Evg6N(4k~36C`_gc2Pk~LC8Hj@e6pO-G(?kw^`N#eD?=}+W?=Rqp zp__5y_qCVWuLJgneACk25+Ah_h*N5zl&g=XIwc=YXoUd8LcpGkgvJ{biOUajHOO5s10(bm9nO*0au=!O%rPW?yCDE!5A_eQr(20UgWCp^AU)yTU>VkE@+ zG2Dv;kMA~U)+o6_%DQ!rwfKe{fd?|um*c9(8dBZ(m%<2urBz7QCruD+mL|+NzV#o( zt6}#TLS&9LF1qN{N5;a2AfbG1V`VuP!~Yb+FIJEnnpIs3;Y_A>8N@@Dde*YuG3@lV zy-!Dyw-l3?5^uyW{=MRjM4?nREFvY@-OR{^w67zGRn zzGPrx<@Xm9*BLi!N~dI?ii)3K#6PoG*h1Eq|GGL??8y*@O=C_MpV4JbIQ192B9jr$ zus!;=T!K`#agM0kDmxhUhBH}y@z6u28I-~`8`y6jK{w#FY>W{9y$2YdFRV~)TVp5y zICHtkr2eZ{JD1XQ464gU^wvH-Dz8_OC+a@s0ABcpf1#5=XPn@BCN$ebFlrHA`+B-x zW)*=lZTMLnnXP8!nt%4*{Kf_RSMd5Hs6MdC`%b>K!O3Kk;9n?D)VVq`l=GR^{Yq2a zdjOeo!ZyAv^fOB>}Ub*t8)Sc5wc3`0%(i@UZ#RpRGMYgy?WRp{$xDvp9WR z?d4@@rO?_uhAr*q7|6awdyr8SP4Ab-aG&*lW!_h*k29JT!&p4Rxu!KuW7+--o-fZb zi-KE0ykuq1+~YJ&&y_wqhoE9B}{Gj-X;pu*kUg z7#p8nyiu~zMEjw1(Odam9l+U!7v76ndhuqMsiBZj6Eb+N0R5F4QJ*F9RQU&$Xb!tG zXoH+R=$^Hh{GDkPX6elm5QfPwC}hympC}*bequls6yG^(N#;3|YkaSJDJ&x{+TMXP zBSHwqUa}TfpTSYwCn~b<)m2hUhp0ZHO_hFY65fd1@dHOIN!lx|P3RRW0qaKZ3JKY4 z(k81!pcDT~vE07R02$>1%fNMX!iBTr%z4muXBF4(#}nUkyl*%OQkb&;(&%jd)tOTi zKWg(E$J|qKh4)P#UO=O1KmM+$v4CckIOir{E%qP)& zbr>yIeKBQREpPVt{l}K5$mznJM5aSw{K}NV#L!ZS+p7wBBx)`D!{Y26vN z7=CwdL3UHa!zLnV_el9`8LOSLe6zF(eQu;xrP|0OP_WL-e_osTw!vjBAmHvSG7x~K zSFDV-V%n%w`F3>vK%2@fG#U#$+>%QBIejYAuisT{yL5U^yR2zs@Su%;*ThOcR1uG?_8NTa;2XMX6msI%f2)G>q+&pxhHNV?b*|+KYhg5p)|g`L&t? zj=oJ@yCGxe-~_PLy<{B2{fhZfIw=-gMXF^Pl$g$jiws8U*)KUihcgeNOgyc}N%8~?h1W#}n2({YDel5gltBe0H`&R}m3 zsNCRf*6B!%&W|@9X6YROavG2)NN2aaWvKotOnGCZV|chQ9P(I-GUNW0Xq~3`O&iU+QY_wZiCG za7YLZ>p162=Mc&vMDS@Dad=yN%)7n}-b!ai61{ob5O4TEwko6ayjhleC$iY~zts8v zf2#BU`S-Gp4B9B*IK;Ib+WZe%`~T$!ggJl;J@+3#6Km!_vyc)X1P?Ho!~Rc``F}6r zS4Pp&-J>nN!XHmTVU?)c7Gf5zZvZ>yWDLh{*8aLSyV4JOg+P$HN6vEx9;W;-Fnl`fIWaM0t5sHY>EBF*75yha z!5KNxOqpn|4zKjF9sBUBe<>Q^!az*+dYV_q@6p{euhX2VhhD+2SS?(4#(I_1>bwnS z!rMGuA6upUrQoz%Aq;cxQzb&1hZkbco}8~VdSue8X2cH)Yz+WII4yp}SLpL2`t#bc z(E2mbkc^~9kC}(*57+y$=kYI~`$>6r?LbMJ_WHT}h&xyK=U3ul8Snh%ZufhMjmwh1 zMOVJc&F2sHUzr50D*zMwz;Ktv#LXC~+qRc|@+E{qq z8SCH(#aY%5oS1ytQ*{JyMTbLN%*)fIJwvFmG55(9!)Q|1s_l6Zl17|u!b0DJ2dnSV zxQ_qz2x@c7Tz4ZF>1U@ISOHWMip68w3QcTWdr#Q)5|i8@AWTun!3efOC|M(`G5)#`O|FDxRT zCVaMdi`FU=ik8vRUU6!Ye*LvajcExyuKo@5+~C>lR7S9gQM~0rBO4HOVFj`imM*(_ zSBZ<)64-#@N~m5tpF;BVv^QB1^Rh>{ZA+%d6GMli`&>Q`TO=nAzt@wa^MI|&WDszO zaus$wF?Zg)D&q+Zf>vHTA&Gh&SHVa_cI$|7V34-5ndUtqVXmo0a^oGMPDJQG4i4H` z0PA+y{>DP~J9b?@Sgl-V2{}~)sJ-e;;kq|%El=nT1p`$3J;S2|` zU8^so6A-Q2Zr}aCZ+{vkwz_&9QhIqE&2OFMeGlX=eJzU8$36FRzWn*c@Cn}XFGU;h z5i_p_a05Mx_0vP#ahil%@Gy~RiabUJk;a|&3HD^dFC6F(n;GdT!gjp@$m#G3B27L2 zci?xH@53Y!6=d}C>=fb>z|WmS_)p=6%Yt_s(P`#+v&NXanrW0b@U71n&Wi|k`=Y=|nDw`WC zIH}mv6@phEpiED!>!_Kta?W>=g4LSYY|1IQe3+Za0E6*(OKYMB_8T0}garf$Gr%N$ zNcaw9AI{?%Z~$J~)u#3OVY>boG73M`D-ZChtGFv3>$KET1Q7qBy90rw&3Yg$WzxXQ zj@-F2AI0TPh2yD&f<{PcfVl21>K`vUJLM^Rj`SCRRU5A1>}Bf8RXV;iouFW2Z5Ane zghVx-Cg7cvj*Fa@aK!#2$;{3-X$ zbDN6C6S|zJ@HLV@XshYiS_@bFrujEGZJixeC4iWhJ2vS5o?Q-{Fke~%dM9wKgMb=t zet_mU^e$NRA9C;xwC!%spN|pVC-^C5`Hn1Lf$yO*7xy;f@Q3Q!I&k6Vw1if$p}G{1 zVJ`WhAl~y}wfgBNoVuoFbM4Gylf};VR1`E5$HXAJ?W>M{dymd9;|DmO)%A&~ogfc8 z1gA|~hAu%2>X*~;J+gDO1uw&wXI(f^1TPo!Fejw$MZQoqE0Gw)M`IG(bGJA%V#W4I zC@EJSHkNV%B$3E1uR9jg=Dfi51Juozy=Pu7cedH&KVb`{N7CR#Qst|0rhWEW9`G-A3XzVyCv@t!$vPn?S#@O5g)}|n9v#<;&aQOR$;ar6SUd`8vD)`i86L5n zskLI;s-)Q`XeQ%F?VVOb-GVQZ+eg!AB6a+FGX`icf24Xo;!ZQM76RCI3^zMFu^XJ% zI@<)AKB=N{IjOMd=8Z6L;!m@X@`Xa^wA$g(gE(1_6-*=O*Luj8nl@eT+HUngQX2jB zB%gv?uqYzX=J9ClIthn(tB|hQyn~}Y>~sm3Bn3wC0mhHFz#c)OZH^HC_*{Y0Olj%6 z*Izz26RIr2XSJXn_MOQXtSQWqWfF5 z^a^29@y(-oF1PFtFDNP??|GxOa(9P03lgoY<0@&Z0h`jbEs|$eXQ>+6f|ij{O&vZM z_BPzc_0fvCVSXatt7n&W0%*=@YDs0@iHq+tKJFiKvDr))Jo^%i7%b!-F1osMv(mi4 zScf{&Ur@nLDz-$zwD6 zS;6xe@uRv^7{=@iHDY~^uY7(C26dtJE$L9lF>v_%f_T=Q>9?o`k}XPQwBnXoKiOL7 zBJJ3n&s3~-Zc~~iAcKp*4pkvFGwf!rXKDbf+oiYip53+aTY)seejga#+6%YU7hY|aylTkr{yzrsW{XZfCXH2 zvdzbjHFpZ|QjEU$HFh!Smnv^MC|hRwBAlxlCXrG2)9eKC?*0=MSeinxW<5)i{cjC@ zb+{-fHfiGq9SJcRWdAV8jJxD6&(4a)!Jin(nAvpDbB#}*5HD}M^}8pjQGTiMm5rGd z({UU;V_N3jJil`e(DPLBYZqC6sq^XRoVIRqDYuRGmnVhv<)ISfmzLyrGlSXCH7*60 z8;oICQuaF&o=mIEM8tgH(G6Cre9vYcOOhv|rz`2t*X*{qFstm1K7HKqb#AcE2UaSf z+lzD?0DIHEOgnoz$SF{?7$`q*c@JaoxgSf+_jcAA3Ayqc!+qxlHw*o7#W1 z1=eOqTi|I`eIzl{%GzMC$f5?+y6mH@dwqLXi$XxCr1KUECOr%6rCnmj)Mk0yDDzanHDm zHl3ezGStT=(6?et&K|h)9Z4sb^KJbnOYxG54vg7xsSj$&2%UVndAEZ}mE;ZB_dtZh zW6!n;j&v1S8B<6+-l?JR{Sp$4-`?d-3caD=5=*0pzkjJNks5PT>r(1tx0EJ~c(6xr z!|(d5RJ@CCBDMLO&tSfMJrg`}m!<#3P{lt-6SveG$vF#TDX(C8$e{}c>T|zrpz21z zjFK3|dFZ!}gQM4VZy$-g@Ws$!D0suwH1rZw3P*%!QapH=3g4!3#sQAWx7KHtc{{~T zHsK;_5-Mr}fbM)@6@Gv>Qy+ElSk>N)d#Vzx0a zH~VK#wY+1#6_W3k^ZdYVM>%?kv-eZ~8$1V-xsFe6<1U;dLVow2!^@;hz(wJgS@BZw zbc`m6`rpg@3nSS<1!b1RJ%x-JmLtz>-&kOm?0^Fk|e5%4AU*l#>GM`Cgp$o-$d zchStFi7Yfv4Hiw<1{nA=Ikj0#eYP7m~34LYfM2l7I5 zo2c&+ffdW#HB^u>Hf(JT;}(ItV!{b=%kifg%W%{~=pG>ofx!Z+l1c_8yi^O*y#yR2 z{$>~4Yz75b6w1x66MRA}+Tr3a1@>;N=iA$ued@U)?_yZ;7<43k^f-WRdcFFqoy~`> zsMM?I_q{rFobeBMIdt)0!Z(nPLXlVv!(;S8ill^r+{qC29TaUUIth$!|{6FXZ_|0dQ-;@FiAIEh#S9J3-7BGa0|r zS9-CWt_1Wacwpgks+TgvCRs{X4}sDUZ{m%}tL5Gv6ww0n-Gg|dZP(6$gyWyvYH%5;IV zVQ-PS64za0s$0maZ7%*`hQ`lFPR#U*KNI?BQ4Pgoh6=YeZ&8d6%wJ(Amgj4C|D`DW zvo$s9T<5y@0Xaw(EzGV_f2yFyg1R5-XDy>OY=3>~nF033}u^gS2=slN*BxI9T90)hV!Bo-d1Qz*Xu3?jKyU_Bb}(%{@0{EF)u<#oc3b z;-<3Y*f~-AzH4HBF&4zC1deD=I;FpW7xmgb+IZdj80(04jY~Sz6PI$AVvfD{W7?5z z@!Cs(#XfM8zFN{Nu@$1mcX`d+lw$EPqf+4|U|lq}Be$Kh9nFdtmf^8`m4)akos;xf z6}r(eCTsAl#8Mvr)kR=pY;9U}Y-gK#cL$i8^%+UJ84g&HP9Uy>dQy_@{+I2&3m>sH zEG{73#I~Q5EM)*aquGm~@0?7!L7I&Pi7UTk%n!A6ygFsARg8iq(9;aRXYa=(FE>Jg z^#R-RrjY-h%%vruq%8KU7yrgdR_dss4LtDD$K68pwqdJGi_>Y1stPhvwW#>6-C~B{ z7i!K#XoYT_xnxW`rN3z;Wf_mDM@a9l-zX`{NOZ|f_iOcXx@UF8>j0{Bas-JsN@sf_ zMICtRcP*PeLOD*>8;#O;2sF@o`z;ci{RsNUX5LBFBGB*aor?W+<>{uo{`xw^r|&+h zZ0Byh^g-|=d#iu$x@cOdis~qEZQ(Apb7sGRSZvt&L-m06A}eLz`r`uor1Co0#+Vrh)hN9>>+1hyA@$s!4cka;5@arF^ zn@R*^My3vgG43;Xm!x*k!5{1ipG#Aa zE_WG0Hn_z)@#ZBUQ)R=zU^%&3W^Dr6&Ah{*A@*2Z}7&4uulA?SaCb^+50i*dD}KtZHw#P#o=(pY|*tn zyuFq%q?h_a>-(-s@xz-0e_efb%VxmGN%MdLGf@AMkz{iAZ3Lj<0Sj2NXx~AHG(D|}` z{?2sB9b=%{keF=)7rJk>Ytr*pss+NrRk2^4mACIWcq0miu6xe(H26xzAZtMWIuxDn#RekqR`eM}e#H5$60ClY|IL8Kn08L%O zyQs?CL)3$QaosYr!e6*@7YY=lf|^mRqtSKAalk-(G~#=ZkiiY3=lKT06QY?UIIvhd zkQB53M86^8fB?pk|4wE13(h`(jV|Fp{u^z6@J)Y{rIC`+IbW#z(a-Kl=7I>6LROL0 zmjqWP-OyYb0aS^JZN32KgX>M~9(>1&OC7DCW@++|pnE?QS2Z7{d4BPA=SU9fce$8x zH6WrXk!S2uRPjjY$U{_9x*Rm=n9<%|%JTdC4SD+EC*i?eU?Hdo>Q4PTH2Q7gWnq`R zxa^FK8zuO~DC(DwsfEDNLJ0x1r4)LKVGDiZLqpxazNfwR#At~=X!$IVKAGxl?_(at zpOmN#`*l50Lo!yZ-27vrh7^C2fyO@nYIe<;L+O99U;atj%>bespnd-fIQ(CTU;N+r z8vieFG5>K={yf|@?q^pGJg#0GX=;V-Qi&FnUBQChE#BgF*S z)_dHlJPycwHRK^a_Z>yA*R$8RfY+zGcOI#$cd?2DOa{bcpCc+z^{pC_5Gh3Cwb z$I4rxkY2P*%RAfi!jp(0St~4$VQ$gPR@%eu0!e8m7F4$sFZyR9tHY`AdfK0k-@qp0 z#hVfT4ukEsex9)e)9v#fQCEXYoL450*YDR1pyJDSK7*_U=b!oL9&7K5?V{tcLkf(IHRC{ITtXGSF!5JL}s z-6rfmu3wwV@>M4$KB%u>m6MN;>R`cn;_qL!nGNJcM=tv~jUBC&M*0hhFd0*d?5cg=Y zit02I=QSTDy2W044V6hi4wuk){K|@aj^1t&dIsJVbG@|>bA_fWT(p-VqyB(rGarwx zU&`{i45)&H`S%;)H!?zTQYKV*pyXi+=Calg=_8~dTjIFfOYp~(je9e$<>Sk1BmA@} zMu{b<(ao$fI}?V9R7{nLVgqpXfeFQxDqncn%}251g0r6HxKQh$$A2jv|Cvs! z3Woav5C3?@j!a;khzTmOn|Ln|J4#*KfL0vtdc; zq<^ZrEliRyt!ow0(LK~gXs8%D^`Gp3TB45T4_wCIW;YevOB@2OZODAmFFL*qF;5!sK47~~Wd%OAIhza=xkE$(v5w~dgzBEK>skc1jlngg~A#!NhV7oeUs^Zowtp zGyi{Mi1T&(3TDFckl*ouH~s5*Rda2X%?PZIFA1gbm%>wFteJRNeVM?g!qbK$0u6x& zRaKS*!6<;u4hZi^*hG7qJ7ZIU*D(6u!8BW&w#O4rYE3IZc~(Ct4rzF8F7I^$0@QAQ z#=3&TJ{3VCs`t>?Mike7<`0)qJACyQ z5dQ6{JcBHeKEi5-p$!D(2zT@2QGl-FwH@KlCCe*SqM(lC?%lWoOcb9~)n}|SazW}z z+EzhDRmyRct8bw=?nxPudAPjzBsZ5vbb5H3%;Nk68)#*?K3kuFjk-pUEs3EH_ZLAP z5l+bMllR46=<2S!8Zp*(Uym-ZJY)`5!|rc2_zRYaRC8%)zJ4oQx=KOK;XobJ(v}Q5 zVm}&GuYq*7zX`VX(95~s@C&Q_SaSazRk~T4%%x5u5_?WlH^isLo&T$=U`eam)+Wsi z=J7zJ<8qXpSN{cIV_*-Dta2)MjN?D>au1PWqQu1J?e&!uh6x#}&2lQTXx05?F@=Dnbo zoY*f>U$OaS4vvq|ShR6eD0dQkgfPJEB{BFDM`a%rKNeC_uuzX2DEqN-}`4kyFZg3EmZoz zcE?Zcm1Cfg8e=X78*y=p0)eptS(8JM$8la;r-en7z34QHXdV^y;VP7t*sJ-Hl6)V2 zvmf1R3H^e~jrJEqi6Lq=53_y>p;=k6tBOBAtkgQNiYg<%VYcJaU*MO~I(|abu2 zBSGeFzMK>r)Y&Cs&N`Q}?qjxASk=-uiE#DQ=8f}7R3WJ<%?HO8-W`zrF>VaJp&-nu z&B9lD!SawK?v-PESmEX5sy~?+;EmT9gA5eO=DGZS@{TVRnnTCvshGX~_~HAJ)T$X= z>4gnl^`vN~prOE@$jIbzo*e}fYCtp)9&B7TvK-j6<)hbL{F4-CPjrNA= zdau&|WEe+M&+H!_)l58z?SfKb4f5}&aKmro?*#@R-;3#g{hsL0MawjHk?LPyyqnZq zQmkX*!f-*!#m=MUEKz&D)XR&?y4-mP{>)64q zzjDHa%mlLPa*8Y6MxyviF@{)y_p$1)8qk(j@rao-dg0s7DXk~)tXmf`xoT<8~7i4DFZ?hOn(1k8c7?2LWtg7KC4 z6gVd&6#vCjUU`+ly?4WdEI5@FF%LHMmCL<(22t|$FF(2G+_>@T8kN41l!D5WV8thK zPs6u*DGl*k3gi{mA0F3L+aF&i!ykINj^1@XCz|z5XZ2By+g|}Kbyu7ospmyg;sX`4 z0yV0|E;mqzp)Dff%clU&%>j%U| zmBw4~Hij?D<<@2WLu)C{q9j39WkQYT`&X z)IxXcC1r^GY+asVrASCkCk16b57-4tVDZ>AJ{VF63HiYK4Tz;nFEVPrZ_2Z? zuA#wK5)JuyL;it~Kln^=FY;Weqx!RH)DHvN`#>~r8>gsPG?x#PRqCLP9Dcqb103e*}8}!AL!C`9{b6#hkl@haQ$ombJ+-0*w zRxit2lHth}Z-JW*xP^ztb|qDL{Mq&nHbzw+k3}1zSHPLXnWSJ1K>`V$=3=XpJVrdo znxjo}V7}cVoP5__d#vyiMR4o%{EwrzqjPM?8$cbZA(1T4VT&u`WK^ut;44#~5|%IV zS@m7<0ILJ0#m(NAO`%4eJyp6ADD^G7gt*Uu2qvRUwf6%sY9Nn-(~fRg(fWDeC}_@Z zk%O~0VI%kkiHq(#(8=Qa;gtRlM7ZIPt}-qEJ~}ELPzT4um3p;*@C!Y$g4y*rh(1Y> z9H|z*-K3G&S9BigRdwd&Ec05=}GAm#2EES3zunfGB38+LHz8z!M~B z{W>Z++$Bz+n{wprE!#V7SVh;q=}*TCMXI> zH%bvgQIQ(D3Q9nF4M;~IC`b_zq=nv*5;`P-wBKHS|Nn>G+1Z_)o!On)nf;o)<=*?A zbIUo;d7d}cqhdN-JWuK|yxua7h|ckeQ?J6+2LgmY)JNsT79Z|M=XZ|uUNDlm*0s&* zo9!++n%sjZ^LjimIq~^JkD(&{N|{qi;z`?hRpu0hA_r29MR^6FL&w9>Npc6`=*A4Y3S=Qm%xyp|=L6coKG!}WbZUtH2- zjn!KYpiD=`?&_W$Y3A7!%7ZKq{N%x&zQf7a9zTmh7woJ@{Sb;w)miCfH4OgboOY$F z*BQQe3e~w!eCWi-*3`-|X!lZI=Im>uMadrqW$qBXCdysrWA1En{QFdfcJ=u{EhBf` z+q^>^nm$3akXK|il>Vh+r%z{ZpL5Vv=!45fMi%jFEH)m1b%r?rXCiRYYj&Kgqg ziT~Xe8UL(MSHMu_*d4Bw4HfaMabg;unj>NorH1M&ZhM|q!^x1zg`1hV_G5H_ z-7bZbf+heG{;iq%P&)UyU7SO+8_Y|%9`Vw}rla~9I9gf>=st4jZZO%LsqZK9dR0-i z%Y^>4oXOb$g!XIj6H7Ohf4&U*bNhVa)}ne|YKq&)iNr$)c04Gq&{`dPL9>vJi6R*I zT&T70a->f7-l~z9i$s&BHr@!opV;{&)p4~b@aluyRn<$o#oLQJHP+G6v96%`oi#OldBG}5`**+T2|1lieW|UT-0y7 zce7@1i0>jqkPm;KHcq{fuYB#c5W{I~VdP+;LK#&WS|B{Vpa-|-M&BEAxUD5&%+1G1 z2a0P6jeQN#7UH>ee1_AJ`TU7a;ec3yjrB>5b;!bnN z@mK#iZEQbNe$B+_A38_XBt8D|xh$sI8pwl{jtk&{K;Zv_qP)!Z8^qdLF1f zJH~{Y4>yM6w>l*m;e0?rZWCQLxmBMy4wj~CZS_GTHf!W@!9IWb24lc^ud{ir(>`kz zb+MfPRpP1lzaFL>kEu9rJ3+DxvUAVZiLT?{S^eO~EE;*Q_0Ur@u%W?ydfkhJDX8hJ z;#$4Yhq5f5=Nw!a%3I)%f`qf@w;$Eb`rGC<7DbGF(!7*B#5gRiZoL_Ma~4^KM&O$Z z<+ag?Ycb}wJ3=m21{Y1QCqA*dV-n_mt>(ul;x)BDE1f6yrLDHP^IX@LfB=wnHM=*Q z;=y@ku%HWL!zEnKK0iXRIsN%$TSXsxU!JdcjBsM>aw%UahbH&48cA*&Q{9tJ*t<1R z^ONxbgr&c;0%nbuV4NX{x_pu96G_({A#(5ZzPInWPa+&vslmyHr=K}5n_%fWC^LKe zL^rl(Y>mR!Ay~(=3hY;NF1{(~x{`>Dd&^&1JM5KRPlC96c;(gd-_^cna16Gyk18J5 zdg^$7ixhLqZE&A5GnR6z>qfHB`QS=6L%gt1oqY|*mujE8vAJJw**(jcWMo2l>NeWE ze=CyovS^s`RrG-fJN{*(z1>^&jj~j;Q>YSGo(6(&R*~do_IGzbXVG_jdZrck58VtT z*tDvG1NN|;pQ_D-zdSsuO3C~yZ&NN zxB)ThkDq>^qI>{RYbX*SfpQ23lFgJ3SKs}J)e*;^2u1NV7@$rXcm;RVwiJJJv%lkq zjtVfnhcsp{&$}A}ZbGgpH?mj1-b>I@PH|<9hY81U1oNC|N4mKsDJQrlTJN`>4vk1R z|8!w4tE)$fZ`S)qw}-izBaHs-GIe1LH)(Uh=)Li$v(mh$7mIgPnN8gdQ@lHk&Hk!e z;CcG%6pbxGeR7-M`|;;bDhhH&xd%kP_~4Wv3kV|8W1ndIZE#-{I8_{VC>p;82&23N zr$Y`&GYblYSPj$y2KcTuJVn#JmL=-`(r5sSv8?hPu}?1?Ow=fogyWVsI}TC zHpJvbl8*uM;RiPLoYS+pcZ>ayvdA(qS4YMl%$*ZMF@E?3ATa^^+l=_<&;K;KKU{&3 z&aB+C@G74|7c@OH(yk;dme-k>8H@IKD!;`C^WS*QrH4C6Gpk<|z7Du?l)l=ZnCWTh z-WVX-UiZWnv%QqZdN{@1m)sR7ItM%P=2G@Iz93@Z-!dLD;*w46!%J(9(ARKnX6S`! zsWUJCu#b7Q93V&d{vU}v|GyI>|G(c-0E-Vcjj(Sdwv_yLxr70^7X)p4JYH#Pt9h^b zIb1E`LU#j^NBqP^uuKZ_ipsm(4hb{lgaJYT=bs_denhp&U~#dh?&(@9KsZ-w-I^+eBYqoD!5@mR={LM2ZxgoQ?- zf-n$P8P>54=20mRItV@;3QhviMV(}9Q~e@x^Dp_&UVN0-^OE3b-aN5M&jn4`N5vU4 z-`qeI$-so?eUAf{y|dGf*O)BJM?)7R=5J7jp51$a-HYgkrlU$pZqe!EEi*DL#MAgj z5Tg4~OPGmA8MGAKH$d+%;I^&=h?Dc4n%to+>^)2J9zHSQRyl|Td3Ak<)TbjK{aSTw z9#>ptQQWKN!CM;2tta*%hAaPEok9FESxP(HyWRXYLkXf-vOu^bAP~0W2Doi*MsdDO zAN7{8qe1P1mjI$3@d7*LmsG7c+43T409DdptM6xx;G+LrrLgx89nT?{?0CjDMGl8b2_zf8lo^8hI;>HCA%QXyIP+RuvOy(>@AdU>y??6DhpVzph3qthv zL``gUojr@z0jLCT5BhVW*~&EjYb7lcuQ{?3xKc#RT<5|Y=QqQ%G1=fW)c3Veer*Ln zH=_!|EtkU<-#q#BFxv9t4{2jjH(gPJL&fxm+CI z+Cp$9e9O2CoYoq@dWjNLz6U!BhY%D7-a_sB-{{i_UEdWTrzBcC!R!L`IC_&H>HzeI3hS*>hmK zu{iUby7$mO8E6ic36(D|9bJ$&J{IH9$w#;MLIu&?LU<9xzXPqJX4We9px%L_gL8R? z`_jUDEWt2PGLYLs0(v)mgH{Pw)k%|E7ooX=h9OdDW#< zXcanSqan}d=pENKJ{Iyyoq-~45Pw=GZqa`bkWXFD-}meR_W)FKbp8`q;*xWj216$?ERdPe$>37d<`5ZvbI$bN^;- zY94GI*ZH(TMS>hS|J6?#JXHL)+PiC~fZJ3~Nq5detIA|2;D4Dma7sjHsRJF|iiK`~ z31ly*1#7Jp2{kr|YTQJ!{Kv>WmdY`IuPr|CPz(vcO0Z_3@jf$2#A7lL-n1K*LQY^6 zCT?EEbDRlKd=6^0ZIJL=Wd*56|66*zgUC(LI&HBYk7UQ4?izU+A&4Lkj|;3X6eHzQlN0@wzP`&p)6= z64@ae*eSLxmn*td)H)tB^+J3Qgx)K$a+~?~or6q}JwNK&!ZhZkRUnXQ?X#z1eN~}e zWFcRJl6Q-)q4qPI6YRv-#QdrC=KnB_xbnX(4#314;>yxaj5~@`E{fBlhz`?)hvo&~ z{lo8`)-&~h{9i`tYV~d%Nn;;#*a57Sit?!4d%X7_ZFqNl=g5r~zuHKj{G#b~_+)0^ zt66BeZ-~}M2*hrFMgD8OU0*G(V5_|+5xpI}|Ik_EHVgc}2>#oP${O2DuA?#PBNu!y z@=dS>Ej;BI*)Ntg#?dhgR52_#c3@tzE%R{8=UjwTALd>4TGLAO5S=KZPMjAS{ z*5=xHc=WZq6w@40gZG&hqrk~?pXe~7sCLvB?3=-7uz!86NTTY?xEJl-=a~=bi<2~Y z@}s)1l7nBtHG`;za!_&f?|`7v7HABhExq8I<^->7Jx2^sBPdk=r&zU|qcI<a4cRX(%vyv^?2`Xr$k!#B?&-^>v80)W0Ji4p3uV!sEA=&`Fqe$nqMl_9vU=(Fi7e)hkyV zUiz$PbL>$<(#))U(37nz6?p>SLHh?2?*%z%=$_Ix5AzsAiqWYIAF&A7L54VRyTET0 znWJg3uD?sA(^kN9QDN1})h2;{R~0!=l-O+ZtIgASa0pt1&Ux1rpI1Iz8b8xu@Z3(8 zdvqIyAKXZ8Xq`5Q2VuU)1tEzY^ykQk-VvX$LSxhSJgxMuf)O-m!Ng;q*u^8)82M3h z+8L0-@s}8~JYZoLxn+yot{|ez-=r#_f$5v`l&vYZ*}U$#Z*+lcKJ#Kdt7x17UMx;+ zixK}3{&={Mf*D&&wzkz#*K>tH3Cex?Z;JCBtZxrgC`oF7lKq&(&145Hi48IO;iNwc z=dx9m4F_QNw-mI(k^RM(!+pw?M$W#&XWL14if!~&BF&J(Nm?o6 z0MPp6gKfIE&}A+`|NR+hvttsXul3Jq-qPuHadBB5#?Jz|=n%k}vEt0d0H~CAwa8 z!0RxhKmE~)kiNLbbK6zooe`e>X5*>Rvk!?mu8%Sa@`paO zU`y2wNv5Nvr*x)$H@Y`J{nI)VxjqJzP37!tqI93AmsEf;!Ug6t(LwsC@n6qLuA1c( z=BS^u(T%r>GoMvxC8G1{G>esP;Ds#ZbB(Zv`|nU3c1G8A2JUDIl#Rv62}&&NtWV#X z@Lyn|?<6$`>WqB3ZuS=U$8jxTP3D|CHGtydRe({OJH=u+SXP#EdgvMX^u(Ks@s~M6 z?}WZN-csVLY18gSn;G-VA6;yEy#^}bPUX?rg&#{TAhp=(kUw=FSo16==%Y!Ul$qKl z8T2qH6rfF%AmZW~VWgJd^)=?pqzi_YY*wEl0R|<6aDE)Yffxfhet15qYJ2s_W3Xo} z8eTVa+U&wryFuw0Q_NJ8PzedqLkq__EM%4dLoe4gYiQQ)R+oJxzNUt0h1P8u@C=7( zFHkVkjl-UM0G|o`jwu;_qi)(LXLRQ7SBD)MPI&TERnY+-vWG%d%HK!EGSJZP?$z+c zwVA>umyB(~?|G=|B5@?W)Ve{6YI!{I>8p?wv6m|~VEwwMP&Pp^wg6L121pK1>BUJ} zf6lNkyGNg_3khXI9Uwhvhtau=ZXpiKIESy+;iXc`v|_j-iYX<3U?1Oq=TDN8;lPfs zmoM)sp3t80I=9A3R7_X}+Bew!SOvilc3&{iNW-E&;c}YwNp(`q;&J*PeH+x^)NZ!X z_7yhhV=Ci7E-8D58@fhTP9>%i)b8ZU>QqU1h?DGhkVLeHKM&Zj!tgIifnQAI(cnWk z2bN~f@kGgL44vzy3)YH7pq^WnF$p~;Ao}f04~9EX_z=5ClOA>P2mOkd^XTvYz;&vy4rLqgIK^QvE&qtBUZ8uRv0wTtT? z-_8niP^(yY{fJT0Xr&-IsZZiL{rj3tRp`3v^vXBCtC^*0reN+UzJumG&UMuMbg^Pb zLj1?zV70q7n4*2MW9fwtM_Z~-{7tJzQ<#((Rx_LVbuWjx+NPpQ%5(6 zA=ii9IzktUvcuj_>T!H{N1@*V`*bp#XIMwJyfwfAZ05e3AD5yB{mqyBsAip4WAHAF zmgTnR$}2dgH!=3gV#J3<>^M;K+mF}3IXRri^sf~>3vzl=JXiEG*7HH?!~Wx$S!KSm z>I4e;i;4_q``v7qY%-|rY8Ggv z`)&>jT)18nks8Wf3KGpjYe5BaNPta~#WJ?$C5brIm36G&ubasTvM-16m-N#FJ6N>a zVSIg!30Md}h|u|;=%lC*ZaHy)W7E++@Ly(@A@${2-$z#=xScI~Rv5zwp54Ad+m!oT z^7o%N`Sl%)NVeR>f>()Jg;4Odvu63zpY_Qq21sdn?XWoLpX9ml#mA-bjWSdidvVB} zDQvFR#}~B0)nDg*eW~((u+$XG|}fkms_A+bu+ESsDaW+WgK>wJJv=(RE}sW z_+P+RGwP6-C(neScKYIjv061(1+W|7W#%RS(4F~rPHAeO%?u1%S3%|Mo1z$8%K(m-XBe27sSV1tQOxdWuIRh>G^E%l4?!@P2g#KOLYd#8dgCkPBA3CD$oMRSFA^p0}^yGDYW05hvB8B~lob0-1^g-eoill_Y z_I|#A&0F`mE{PR?L`1=;KU@mn$|-Kn z`kXWNs>d@z*e^|wZGWhw38M?)KX9Vb^2zx#7Q9Z{V)T80|Ecu!34cl>AFj%frscwY%Irp8iQw91`OPxR?yeJQlBADbu>znZI<*Y=Bh) zt9(-|FW=ht&zaa?d@^Cu?HMxlM5|$!6hKmEbH9DiKA+_aPj3M#KLI-JFFbbTZ%)Y@ zz!jQaFFyu%t6N@05SXU!T(eM7p03VU-W{1d6)Mdv3ZOd}KIQEPBa9`9o_rnVi!s3g z6k*l+2PWT}-R%Q^N?E{)JQ0O8Wt*Aw}c*I0hq@?(1nuG)rw`@FoDyF-Pxjl&9@TlcpU0^%EFY+qENp=Om(%>%Xl z2X4;j6Wo2aKkhvjhYfC@tN?R9{Hm%y-Yq`Itd9%FXVW=ful(low{q4+$phNd2 z+RViydOxFUE~o4JdFvlh!)+zkAUgGm^R!+Wugqb5O5uf%f!aQ9@2(y^DAYjT9~z>u zJjs4xB^IqJY$&Zm;Rr#f{n3|;l7Mp^ANeG4=OmwI5~CDW?)YoVTkWmWzq}CJ7-9VU zWsy*zzU_Z@$V6jNJGSqPF|**=+(geCgzfqPO;?4r7FMlO&(dQa_j1u5b(vh_m2naq zIu!ziRas2`S?G6ibOr7N)xuRLioX@(LibUolxz82Odyl$?S6$gdLXv`jC@xvLC6|* zbe$e8_3dEcvxG_ipN%IU1l*Q4&Ra;j*3Nm7$*h%@`MdUOy{A#Cl-W(D&!2vd=&)3F z-6+JbUV$A6rC7}+O|nma2zjr>d268wW09LK@uwy2)PsYo;%o$&U1uvS$QSV{g3P?y5pGr#eey%7)ddru-cdOfNN;B~mKmtpTw{mb{(i?? zg?Tmk*?@FMS{|Zel?%DQf3~9p5NCz_xr(&a{$(I5fL$i-Y?xl-a`Rc0?-Ft!Ja%0}WLfvb97a-ugs$Q_rnSnS6qotx*TujQ zlNF`2T5Z!XKbNp3Iv0UZ+G*Bm_%S$5_|e1q*789W5+bkC@+z4E~g<4}qq(NM8G z-B@?;(1h%Bl_YhIlSwfI9IU)HJW%c0%Y)Y_7n-kdU7eILE=ZUeI0A28V=WO!>go&< z;N5rMX+1O_5iqN_J1#JT1W?AnOIZp2h{&?oGwdh>-|W1SLBH7)JM+J-<3vIkp8+f4 z%xcnU-<@x`^DxN@PsS){KYGz-3jRbv=$66l$jJNe)4vSC`@eDr-pGHlbr_enCP(WW z*B@2SR5FUZfbqI-(>>nRImbjWDV?yd+vIVRU>1{4`Yw0Sl5a#CC40SyXp>T=gyGDM z!|y%*o%^hC(0#iVabKT9g+T@Zu3`)9Om=aYZ3?mv1K+Hy38P_f z?Af%Ib!Dt&_pzCb9p^&~kLc8!K;oxBRwdyphQq<_>cKSz?_WdyE|IQ?t~$Gevo1k$ ze3SMWa*`%bbN(#TF?yGF?Ip;U1v+b2*i6!U1FS3rO`fSbVVyj{=te(K;Q4SQK5Ov4 zMsDeOKFo!4e6G5@B)@zD!KBgp-29I7!65X>9%OD6p4u643Fhud0cE7;RPGsOl!Y;d z#OB&6ks%NI$A1K>btZON9sqVWG6GMXPz@^IFCw7`kR4cHk)Uz~D3D6HjN#=Kbl3ru z(?iMk@Q%tWYrKp|?5f|E(?{2l;=mPeSr}vx*i0nmWh2oR?FXl@2Nopa;QP2vePI}u z0#zig#|s5*;CTBh+^>if-6dU1bVj_`ust zyzVYT@%78r$?D2uZ3`$Xw9$S?``ESH=YJZ_Ep&MbpQxP-$iI2-C&1a5Z}&=>baYa& z{A_d#Gu@HXF;mZpB{LyT%PYCptonTW#~vU1Idm$>m}ze3LhQX+=l0a!x?;N}lfPY6 zmih$Vkjje16LQruPdgNFF!UG~`a+|k_EtQIbkC0e&m{r=$LvJ^YnlN64NuYkzh(3P z*m(S>$b))5=@8OC<^I=TVro%@&Xz}Q28<@4n{{CR5KZ*RIL3DFx z3k3iINrxtW&CzxXD06Il{M2jH%QjKhCz;7QmkK-V8iE~Q z@AL#C6p-;jUcD#!JGL_0OYCm5#D?(8e0`mQ9_+Dd5DTxQr*I&>b{O`K$}q4F{`L?4 zC@I={G+{XM^U`LgCS?$BZpo*e5dB@JzbpRp&V*{rUvi`3?Dn|a`^P(i!QofB5X&Mf zAGXkcmnJ?S@fkVsL1iM zk~@>sUpDbO7y46bb)Fya9ll}3CvzX>?j(2QL>dc^t@Hd~6o5CSFCxWGv7o9U97TjH zs%KU4d$*P#P65f@FD`B6<)VyRZn>Ljd|A0C(>c+7VlW>0Gi^31CYkyfrUqW5w(RiS z%L}mhbrU#$rsUQYPP}T2Twr~PEHv%4_+^v`rGjf zyNwx2t-QNzJpJpc{uT%E{-RunjKi}5#TG}cT#FqMs=U_zqZcO(mW3?_#=DN{{jQYK&i{U;OYL)ehCqv?v$?_z3W^{G^?CryX_r$0-B1Lp^@@IO zsteN~^02Ye*q2dx*U0pWbmdG&cyaTMhc@b%{1LnVLu3*j>MtQp86!!NjCn6?nm&Jqsoa$^ zaMnAo?2r+LjiCk)=NVoG1V|ZZ1^FJl4gH~X7Qz9y_1#p3-Tbn)a5I;zu2U9`y$E&y ze*L`$I+MKsfa%?jSZsD2d)%oSHPqn`-uIQakNe=1e_Y7mrbqHf*FiH+s!hliMA}OR zE?)4~on;Fc0>KM^HGG*ryn=ZFds|%bSUajCZ<$03K4^^1EQ85biQVIl%qNm~^pQl= zv&Y;_XvSUKh1-jq9`0dnay&r4_s>U$_~zWqFY+?qKxn_b2Z29STN8wTDTu=5#YHLd zDpo8Z=35As^uwtzl(De{mq0O1=DGd^Lw*e-#`u94J;W2o|?lzq_^%L?jH=m83kGmqJj3QwA!H zQ|z`wi9xF%mFZ^B)R+!`bR3@GN=nl|#o%J^2`2n<|HmbUKDZkFsx#f5CmG*`BC?3{ zLtF~Darf_^9&$Kr%Q$yEYFLO@?Qd3|4)>4$A}zj`%f2J^fHpIwPl8u~$rR>`XBl^(Jkyd7g5l*?t!jY^9njkq_#(|(b%Ft7;ta+6V-OnjoK*gvL zty%Cu**i_aXjK`yn8!;Z=Ky63w*dI3oO+X0x?oj(+TKRRn5vD&J~)x#jnnFs9uX^E z#sv~k_Z!-|5{nYzJ)ClZzY9#1v&`JgAlez;*IJmA2TbAm{RBpsr6LTpe z;i)+Y+@YIqDiku6NRsfWsb1}smZw!)VdcjHz(G+z5_x=HFeQli4Kfa3J|NW$y$%^P}SuA8^ zGN|C~>?76?kY6K&!Z=3EvJ32#3ql<-qGWAQ*@{F>pYvs0wBMzb#fSKm0b@qxVkeLr zDdg}8k(Sxalpp?{iOy3ETovhfQ&DW}ap-lB6nvQ5SnzEmG`=Y?De87sqRJgMSt|qN z00l4s%%;1lT33?do9DACn*Jo?Te5orojP&j1@wC${%rYe$zxBGvY^0nw?g*qXMLCm z@QSlNrJp6$Jzdn*EAZ@uNeEm{;Yzc0MEU4I5uKUHKXeSvog~`6ipc@HwQ}IR)>Xmb zycWz{XETz^8$cr1QMPcyq@2xcu~E9Ga$7(0vGv+iv0~j%F8HmWisi;g8J?^Cz7{o{yX-m= zqlFuKZY}bRx&(z}>_Vqi>rYdj371&LE3h>gbK}$BzjO=9{+%IA4~X+_ZZNx#bQww& znv}E88I=NEJX$xK2Lde^^aXcgz?}fk$z@3bLPaI7=sG^jp;f5rq@eoOIQ4>JoWs13 zpF;IRhh7$BmkAy^6skI8(`W4}UiLv0&rp8sbNb@pd;RCj;k8t=T+saNv21;Ck(&O4R_#TX?_ftdG zPI)sG()?+eYnt2rfm2)$ui#?znJ|M77;31dg60N^77l) zvs1vxu%sYwEjdw&v(Q( zUGYkTMAp#ehJ~po>p+2Cd54buEj+f5b9?Z+r&cMEiR$&7qhYq7_>*W1TZ34C#1E~j zVzyI#f{3y$EkWdK41f;!yVA~M?|we(;rk6gS2MGBurSl4v^;X*}rQqjr1^tB2aecM9m=0#|rPxGKyE)ov z##~)S;hWcU23Z1$9=>g8&Im*9E0(*hH=A29gVTkRdZ@AC!W$=qys@m9*?SrxX>z@^ zG|{Q*=8&^w<^Dm6X8C6H)5oEc4!VA=v>ar}rYH;Iv3-`H4o*DnN_xoOTS~)s%Cf)$ zqB^K~)($kdF`hqi1NZeV&vfAPhL%quXndqFb<*G&YHVabEKakW2V%JDl~u*iO$n+S zR~}Yn#zm!{ITrBwbnYIa2nd``@88@U2*jH@<)Gc;bcf~Lz17ORHHaIs{t~KzS%Qh! zD0>-chjj?h0H>l90I(xLReJ-M+W+a&=QD_GKiXbrvr%YyGFchx#j08ESXO=bdAPUy zD7Qg0W*54IdTf&ghT0-Fq$rz}ChbAnR^5#EmnitROOa{phgLBWPUCSH^x*WqE`_O# zGZYNLy+1zWt~SzIJuwS%0JGWHRrMW8NBqufxUepb5XRp{GmPx$0i~lf%e0=$>V(E9 zy5o>-rYRQD^hE2IjZ->%xG0+mlXe9}4b^K4zRv`atyWjjS%V%X%~rd66-nnN1dzyn z3)y`J+vVD}a*H+TP^0~EE#AuIsiK0n0Jh`Pt8Jynt#nPRm7>Fz=+#Rd$eNENz&*rV zatQbh*)w%Xs$!E@5(6Op4l~7hMVby(Xu~jT096q(4ykaK*cYx|1k$)9@)YkJ$aoLC zP5NNNb@;ZA(MqcFzSW5(fWXI0arGfJvMd@)&1_g5(HO~1e2_QvhK4fPG8?#okS*JR z|Bb_QDZ_16%M=hc)3p6_t|dL|s!t-U;p6J-()S&ZG)jHIJ3Tt-n13ptj2Z{s)J{jjQcQ3y# zDDZB*t1omy!`q;qLcTh#uN@+w%hJ|2^64T*_+o~PZ^MdYzYLz2f^ZtjLjRcOf-|lX50ukK8kjZYH_#=LZd&@PR!?R zo*Df`x;oy9OKlbvy^U37C%aY%#&oAu4)7=P6$}GO z*Cw4VscQC6m~s`rxCTP12+zvWZWQo3;}{}5*_X#8Z*};zF5w#7gQ zYW-s^h5Oh%iwm)=%5Sq=&j(xZNP*fFlvn1>&U=T>`S)JYBj8-&GR2e$)DJ4UHX*ZP zm1{-q{K(6@>VM4If7B)0AOEaZuo7a78pS8$VzVPL)ko9cb?a7Fc z;8&Ae9%9e@bFUQQuEZ}GLgNDfR&k$rdq`f@{?jwV@fo8-8fJq^Hg_K>iiWpqcQYV~ zB@-0YEeq=cyJCe65D+~}o0*AWtEFFK)4Q-=75FTbK8%5M#-H$c`1{Xhvynn=T}PFu z!h|9S6o=Xd!AY0JRkzd01Cpku+d^8`8AMppO$GeARjg^#90?5ys){yWh4eB}o2#BA zv(Ms0ItrU92Y3tn(@wbv1zwTEXE;zMabMf82xYw2ZIVM_jVlkvNcJ!Esk$l3F{^e@zO1I4FTVxT@`$vZrcn>K-Y1!}ktdc@ z1i1ly0P^|QxA)(OCioogXEJ0(eE+aw_U1{+`S>rNI^)g0${cDl=pSPm%nXj05@x!h za}D}_MMI#pP|OxTBfi#2VOOKJmBlyW5n<3RXHw9#@{AorHxJ;zWiKE@LPYz}@C_)= z7E*A4KyMA>?0lrCOxT@};C12VU0fI#6(V32eh#AQNQOOk@-)nP0ehDSg#M8CYwRmI zf~IG1HdNeH$^Dw!enTvz8zn_~d2r!swQE}YI*h~Mep_}okL92M^G7OdA-@ZEN(-Gm znW$zfm(s<A>+%TWMeFER42WvIP5H*H@BmzX0b{g;b zO@hK$HKW z<07u(=T#b4Y%_2eO*yCCSdN?X@t?Gwr=?Mp$cX3KPeyf`w5>%rGzTs{%3w;ch^^!gbCk>1v3Ub% zAWWP>TKW?5=boBj=8;-wMXmLOq0ntOL@MD;ZB^f~ia3rlqI9`uWEZXfp-T$>`uOR# z#$0!M5~6pI*W#3X`d}zS!Kbh9b@FJCTgUSXot#`2+pe?8cCMU+AaNUP%MX8}OoZ+H zDV<~?=%W{N-E(!VGhL+pFWX8P1|1m=c2wn%Ml@As9oa4{^pdK4D<2*J|7Y+&1H*qv zL4R=Ck+#9uV*DRs<*-fUUF2MyB_MGVrj1o|0}O@FtMR>BV&5A(9}q~BglQh{@_(4w zTqH3C8y0G*t!vUC?~|)&)eg@$h(6Wt+9s9Y0%o6B1%5PJ=-R=~^pDH@>S~MV_$X!n z85$H&LMqsp!nYgb2UYG@kZ|wMvlYc&GE&q z?{N2fYn)4>#WBZWl63w~>`m_$kqs}VU!eANt9)N?G|6es&%ByQkf3Pd?3v(u!u&Ty zCD}FYswV9HrwTo4SB+rvDa=}`2-9p)>Sd^GR6dF3IrSiRPZJybpy|ca)gn%`@8Z=U zsNlxF)n{wyd<`4w(>1NLkb;7v`UFvOfojiWwZSISwGFZ{|5>4rCJsND(kqi!KAZ0r zHx=I?dar3ssD@4d&G95wOdxfJ^Smms-wi{)w{5JXd!hek?^^gBW{)R4jc?2i)<0hV zly~P>qbQ=&ZEEnM-SsP!Yew3%8tPwmF$9R*P4%Sh8}!Q6@16dfo;JU{nk7!UIwpPg z@}WWxwOJ>_p|UCC(cPBo_Db(x^rI5qin90i-5Csi8M-Chvv-NKVTZ3TdOW=NW5iSX zl_kt!?PPea{|ZQj-sYt56b2Dv)z<`*iD33_L3HiLZk~kv^F)Q;H_ZQP1-&UqE4uHu zJQP#2i;{U-eakNPOa33O9qql|BMSL!0$7~LZzyPakUqde|? zw0;QCIo+BJ^hhjeD`(|;cO-kd)miq+%^UF0(>sAY@`EkYf6Fj_UZo(KkRiAZrJD?( zJHpzHnW`q547Zj2zCZT6<$h7vOLE+{wyu!6)ADVJA?prNi|G!rR{XiXL5HcHBetr0dF6Cz*0AwBm(fFL^ zm2a+;Q?y-Z??^jXw$FwPV&#jvj=`qPB0vnlW_$z`wQlB1Imi9SHFyIGP+$JS()1>Y z@sWMT?&o|P0Z@$1KfU&#woFe3F@W5IKM-quX#lInCrM65I~Y8&wxJrB_R#jH*S2kx zxJ+n6h>Wr*mvci1S6pIwSKX!BiamGgFCY`9+zeC?V*TBZ8iQ?ekND(4h8+T+oJB=L zN%48u-_ORdgJ~Ldc7oxR!zi?OFh-i>+eyf5dR$&dVJ#~quM;L*vOrhg2*WGuj4vEZa|lD?A!7Z(|n{kRi>TqQLRXV<70!N^85 z&*lYKn-#U7{BDWJ_g*to#Bu&8X6X8vLrq$Ye?O{1jxF=T?Tb%0-3n3GUSFG*o;AE$ zFdn#Ag$;f=I2p|RAq;{$6Fk)EMG+;yw>W)opg>7RVcBt%{A{Ar%kqAw{6pLiDV zXtO*_zxX3^^>K(QZi&baEWMETbX9!DGN@l zUPVOo2{!qoAsWmSqfIx+XgxYibLdoaA%U_P6E3b+NEQ0zCAG%{e1fUD{k$s-?AdRC zDgztbW{aS(8}zX`=RGI~wHdxtia8t$qqUgxKsKmbcOc)PkL|HCAwY!OcEqhRsOLP% z_mMMjkj=dFy9@+)v+qt3wfUjdS_5?q(Mc3Q;SY%>f=ANT52SN;AQK~qrZO>m*H9KN zcB!Kyg2%xb`fcRcaQeKLB9N~}1XyY^sN`O$Vi4u%BtrtXMUFp@ec8C3=~Pfpo31=u zYYBJNY6;Z?!kc|x{k{L~zI%I$vk|q~MepYyZ#VG^Gn%4_2m)>5i3p7Y*gNl8<8f#3hf5Sq|4ApPzE+67m$nTm3Jp||^81qUW;@Plo^A>bRAFJ{GgN59X-?ddo zUX90Q779cyVHOYh&H}*9OeF8I90DA}X|D_(n?7VVS(h0!dh8AoLey~b_8|&r` zIzfwkxfLuhX?_4ZZwny^l8d7GkF2u#Vj2d#^C7u$;>_dB4lEVGAfw6X2uAN50^3L4 zvja!X%{H;DGs|>jUJS570nu;_%h@FG(k*_UBXelKfEpk;v9~pSS~DCuHbQY_pNCch6Zu6)J%o1rUYNS41N#na zb>51u4Vc`#q`0()$_y?_(198fOm2(+U_@3%N8^wF`|DQRRhQ|oP3>5qg6N_l5?GG; z&e9xsRigs87@bQ-#6NUGHq-@F$o6L@(1kL8utDGeb3t&gVa3^dbd-}o9TL4Y&7}s+ z(SGM4n70D|)|m0)bmlWGmv<2XxP2{5ROXt8~*jVKWo;><= z!%R5&TvYc9aq8A|OXk&YV8-|!;GTr=vWe&+*&hFmsD)v7y=Z%z z9amR}PXmyhuL5TRePUSvpW*eKI$%85DHb!aJ|7dHk1fvX z-8f4QTp1cd5ubu@CO}=I5iYz90M%fzgTm6Fm3M|AJAXPUZ)P@HT8N+JG(g}oN*p*K z_SN3nX*)DkpHrKMGy@(t5DMSo05bBW;Q?O0>#&1LHQZbQ3mn67fJFzlH<6IgdGKZL zH_vzDu#oE@T_H;Ggpp{(>|kZ|TUzrYxAAu@Z|)A9_@tcPZch}QVrk&8dX89WS?Glsv|SjjV+ptHPJLL$$+ z$~DBJxxW>P!T)@s6_BPuV4uQFtmNOuO-t>Fm&a)eYvh&^nCMiI4Fb#D*hmd9b_>nJfC4~l0I6~v8`BTaXARiC-|>dJbCG$pWNMu@Y~ zDvdiYZi=H>qUfl1XmkxEL=>@#lLViWBH@3T{?s|2e(eUoF2ibX88sODUGJeq*+IF1 zMuDB`y}m~Q58Z?5eL-;1G5Fw4Oe!5bKmG1J%-;Hg%mYzmr+65xPL1GXJrYqCCH!8z z{Pmr>dF=+u8#RhEOk<=;R~2S^dRIxh9o5}{Ing%V?skK%$*zwxaJ}!UNOgSMitI0) zqmXcuJRcof?L)uzWNgzeqVq0bwwT#yCbv1|ZNizCO>99z!k*td3pWjb z(i0;ZcIKG;e8-!Y2D-fnSfYv7NwCT_nPDCm-I6Xz6)i!237nQMb zGDl1CrJ|2neo~wUZ>8Hqp`FvOj3NqP_SbZ@;KKF6L%?jL(qk z;f9N*>E(9oY6V7^eM~c-aS9#0Qp&srCpw~ML)l9M$^>?$Otb9pGa?Y?g0YcbeGYH2 z8>(>P^{c1;ItPuf&kRmeF1MCv*35TXyP+*H3&{}hO}(V$w<pZ4yRudlS2%QKbhCw*NE-P2?Bm`v_J+|Q`olDbwJ{v*@W&~zjD_9&By4%3w04JvM zHe@33P34FY3K`tBjT{AC70&=u=XO~U5A`sv!T4dwNm@9K;`sL8rEF&j@)k^$R0xp~qnQy!CB{-nA?w&jvJPX~N2x4>k!=*k7>s4cGF#{Ceb05yxz4%Hb^bcP z>zwPHzh2in&GS6-e7Dc%{@nNd5zJ*vvg%X7vK{<{>p*|6PziP90&e9ua=HiFB8~4e z9=*!kX_3m$jrrjBD1QjaoL6aRtGm0V;0k!)z8K^}Z^KJ|eD&Jnjp(Vs-aw@5m?8w-aP8ba5Ic!CRr3Y~6zcs8Gtd*? zi)E`zQ$6@W5VVfDtrPk!^eb}!cBzM|#%hADuvpz}UP)WonodvOauBi8-oZv9H z^2f6?A%Uu@%iLa18hw40DSrHj)W2WeiP$)I0~TsO|n!ACl47PIo9A5$L% zg43#V{t#s*Cmi0r-}?;)Yr_6nvT?FD{emrmZ+7lclKFRj-)>zuW}V>7b_1S zukoO=bLyu+HRR~C?K}7EC~%SC4E>tX1YUy2`VNv6k~_*M17g?x&-G|FW6X9uKeW~d z9lI!*Qq1F2Xb7A02)6c}D?h&G%F66GUiEIoEAx=w zoT5G!9Q`Y#y<+5K_VSa{vTTAk`ep4aMF^Y! zcS+p)3v`>~n%txeYv>D0@yO?*QZ841IKXPXSNT@1$>ploX^*Fn9&9b^=|!<<@#OT! zcL`(%Q|AbWs?4qA48Ep7VQ!b=(;L)kl2}TH^KX~Z{h^nq%)G}_P33@r!%9%7;~v#g zfieIGt=N&t(4s0tXnbaRT z*TorFadH|SZSxe?gZR=fAIlqcTigfL-=(N{!o%x_rCf#pmrtG;dc}DmDxUGQhul?l z!u;y}&tgZl1@AydIUZ_Ef4d^irg;FEffZvv@HT0M0*}Rz>T0BxMlq{-c>k%fxBv-* zV<#Z+UXB)Kz@)<<$Qtulk&Ef-$-TF};Kt9@(hjjsG09)V`*K{1e3uwQq>6kTY>|Y< z6);A_{?UGyAz(r06T7OT*`KrXXTk0Q=)9*TyxZVeZa4+Y7styF*u3S)N_4e;ifC4@ z?ro+^+I^0+i-@({Mk?NgZj_6GJ=POGxz6%A=q<08=zp1~5P|1Z@=ro2Lqx@7=;88e zWO#A8m;25R#Y)_-scAAOrk3O=+n6oU*Iu~fn&%vZL+47aw#e`gRfht$tMA<4NGIeQ za#$$Y2Mnx)JtO1uHkr+_@CgQnF*h7ZIfN|ktT2kmNo~8<>n7Z}+S}1*dVgOum$Uo3On>2ro_fP?l?wVyCT=R9O{hLMk?R^bS zE&F6jADJpiG9C|}-y=~50HH?^-;)J7LvXP$GsYzPJGL$M^h*wH} zk}LBFqDd&&2Nb$}#XM+$vj{>%V0&o7+p0E@=zSTk0+=UMI`iENQ4hu*0O#;5T2so9 zpMpcHH?%!}h%v@Sj72s_a1^GnIz=V?`b6`I*+h)WpzcUF3qOh(yb1Q*_wqpx@uui; z9blSK-d*_7F5U1z{f>-TkH!R!O8G{`#FYP`oS>^DSy!vaMs{m*&!f7ut}Vf!tVJoT+c)A2--QfwoB5|%`D=vYuh+GcXWqIo;OkgYCH&-bqT&t~@!QAm{kQ+SmJ&u|iBhsxS? zFOqdFueF)8JCp_13o(W*k>$;Jc_a812JjGMSDE=9>xdrB&_xn;?4!}DmySNLAF2ir z(wajHsFL&rleTgy2n}Xg>k761S3jEw>JRkU%GKZ|EZb)> zU(=hokAG!sF9ie3!ukB|`=0^*5BW&diVUhZV}LNt9h|9tUs*43=lk(Qs+&}=QYq7T zT1)89>}YwES@7I5g=fF-V-?}vY&AtW$mVPO5D^Trsnuryj?gCsG}42DJ2M5)FY(wK zlGDv9!#&bDZ#rx(`a0A$N=8V9K>oxxnYPN1eryQVGZsUd5-!8^o>f++eDLjm!u@UG z_Wve#{QvRJKmP-*|Nk$4T(2u4v^wKe8Hnvey?!>V+!xObb8UIORwaE(T~L_ef9N5c zHO`d^C#l@Rof_qf9uD5yTF(}F|GFXX_gj-nv6GN&IwIvqOGtQ>M{rx#PWpip`GYT6 zb_UdC`L%*N;~vxY$|mBS0}XaJJjKm4tFX94?Nq5KDrvkV0IWla=-|(g(TUa4DVyEj zUXknGu!>us_Sre|btU)D59A@M$zO2gB0($hd8_It+>@@r9^H20mk}l*IT1GC78su~ z9K$3hlJ66mN%Od;y{7#c3CU^`SACxNRE)C6|whsji+H)q_nZL3+=202t5~!tq+hqL9)K&9Pe9DCvy-x+P znz3@?(BDlO;o8bedid@o?=Js(GwbWG8{&RgDilhcMpGPYZIP)r^s8S7Vc!jF7B=}< zPB=jpQ#E?eZ(!wVv#$2N0%8FP$E5<=H9?`SB2^T^#LpLB1I+4CEYXfVqd@fILpixI zR*dYeV=G3rTXQ3vXmn;D^m;ko>wl$Ycc?W{MiYS#(NAg>ii@{n4*;$HGVE* zoKUf?Zv=V9vg{i!=HI%@A8tx%RjbK;LDjo7^L4(0zsPk2P~D9hNo zS7iS?fy=>Hsv?_2AL>88o|yqz?UW4slVj7cKkxV-Y-j;VGv@VOsS)d&=3E#6bhTd> zj2U)*lv*@)mSP_{Tv~z4JV~!82$2blo;c)X^Pt&ym+7m`F~7y<8s|?bOqqNmdVCIu z4*YZS<+B4PFNb~f+PBs5&7;S0` zMRnk?iJJ6*bB~8UqTBcu3Nvo5@}cK}tRT?<9HMg%L^#}mmqxWNxQmk8L=%YZO(LV` z#X%3<)8O^{ycFay$`F?%yzYg*%Lrw+H}SXw1p}1WP8$*iZGxWl#h5 zB#mNllQD}3VDcx+l8qc+5_dyuStrq(>z@ zcI34Lz`D8B7T!3|I0#Tnfa|!}|EBux6KD!rR_DyB@2l1XmV^pmjF@sgMuc*WJDli* zm=mpeqs#yxy$`K&;9VLS@4?4T`YbY?XC@H?=^NeM$YV1`{W?@lRgP@_G<2p2?^yE= zGHtq1TAT9<%p=|g(+AY)kbOqA(u^Sqa495clR=~&azvk7d$pnF=rLqObY0Y(&kaee zVday#T_mSyAoS?0=}-nYWr10=aj}|4VZ7G}aHSz~Rw4@S%)Z z#%Q=0s0Gk`*d)=hN-AOcAdHD61o0D>be4v1zP{48ZkJWU<^PyKpP-P7ln@{t|Lr+Oj_u*{d{yR3O+F!?)4HN-q(i00ZVfn7u7!*E>kTFj~kAg(N~ z!+g-9c*KVhj|@x~@iBXz7!=0GP)Q^gVoZ%7F@O3b4~t#`Z>MG_lf}8a2Ag31kiWjb z7_v~M3%HBS{+T?lNDIg~29`!9xmIGcyn9XBlF-_KIMmOm^rS6V@GPcim5&hZ%_&h^ z!QAJen2GL;R`=COkdm&>L!B0JUY-kRT>j!JGs}Z962^}vk*?tpR3iIz3N&&bw&1VO z!_^rHlZJe)X0X|SVOZOEw|=0=>L-t2j$UVXH@||!-`tR_o@ul2qCHOo<{MxW^P!c~ z2P(axNCCUQl1{yY`9NF7ECN?NYAlHYS~C5h0-q}alMi0!1amY78pDCC<^#1WNed80 zg8t=p0Ee^D+qd`_ngp7Gis4Vu2y7&f{}uh~zW9@m&f^cfS!R&dus9+j1bWNSFJ=(j z7Y78wN`<*mepPQTWGQ-YB*6UUl^;gPTIrtyQ2niBzHdwn5m{~I8NC0nYbI1Z;DyZP z;PR^?6dZ#uIyHzvx_wE&gF=a@g-3udR+&6U4-Y{nQqkKvKnf-CD0*RfShXsSsz`HA zgC?WT_ID^Ja~_{TZR1?@xt8WX-R#&9_QLt}bhel|#bRwCjSBfex{ zk1FKTzYufYeKCtQiOsi@S@BZTzkBuo8aZhR5-v-5z82JgB`vXH@}=gv6WOwZpQ~}#8YhR) za&na2g&E#+)1uKX^*zr030*R0S@dyr{a`t%FQC=)c?_(!+bO=sYoN`srhc71&r5wI zg|ZNmh`}dn?xj}xPgEidg1^6^+NE!Mm8lyNUE3eJGDewC!%~_dzR-}54gRY_=)Z3uK357%+UrX6Jck`1a3wzn5@?<=y zPVYjc>gY5+Gj)I>Pk3qR9mIPtbapI4R+B&q&XhEyR!@T}VRR1Jl*Cz4VELO)QS0|m zyuB-o#4bu_>s_dDIPzqKLp+o%(EPko^F^ll$*v)TvTI-af1Om^A)k8&WsZuEcUl_+6TS z61s+KWC#Atx5byf2xIi+3=SaAD$Oh=hh==LZvg9^wbI|Z?~mf7oWhGVGjoaTpA_Sa zt!Fpq!s*6*O>)DRCzmaRDM#5t5R;t1zM$=2$~|a6IPDX3P}LT1lKOpXwXvwpJ>zTn z1t!n=+XRg(H5H@E2UB^3XJ+Y@w`OvsWJo&pw$q+ zai4(lw1LU19inGtlmuL_&LrE zlp&-8^StC{$niJ2B;Xg=+n%JI)S;ezwMVt5AbShSr^iwSvLg7bTG!gBV$_Gkvc*#r z+ZvnY6B4^wGj=Q-{KW0CR;q)D88zT1Pk?^LvQ-V^Ta(gs1 zC-~Kg&%bt^rth3BQ0_Kl#fFYZDDDlS@ne6DeekQlKW#EP-pnYwdgNy{2OTd^9UB!9 zLpY&S?HH;f`lLfGB<>DO^?ds-3a)Yu=YlsO{q5JDqR&S_QOYYj+l#m zcjdOp?H!E^3kO~_j(7UiHWPefx>CP5mq^QbZbCU2B@O@3KEAw_`o*&q^UY&2Z)fIk zs9qnFw`=%Q@0T%8$?fZ`#9Jepk<|oLFT4JIuxzI?QYG*rc2bxTkV5(~I7a*->*)9E zv;fjjYdCUr_m*w_nr7Co;2!GO)hkP)IcDouRcRffEyl})m}gzwu4dVuze4-Rw5AAQ z?)Mh298FUbY)h@OG)|L>MtrutJT~8wfo`MWVfC#~e=Dct-mtV^GCk*$DzCwhLmvMB z#qQMqM^Znhm1t0IFDl@V*Xq#oy}{0=m7gEuN1`Y>Mi@J+s4dfN5`E@$@Vwh3_A>O( zs{T3EbL7x|jyflWswHAn=*xq88k1>dS}OW(|Yij^}@P)reiK+a&RgaQHc6 z9ml&qtZ+S&zzq3V;dTC>Y-sz<<}85pru4VgSgZA8iYzQtIRjH;zTpG|QE%M)x1BVd9-Q+kZW}clo6S%&sQm2uI$>CpsQLF$Qy=Mhio4M(6z% ziU>R7SC_D3+e3lOasG|R?anR_v68q%2dy8o;@@_HZitz;=)0@VugH6ANG@-I|LD=B z`53f2tw`h;lW)%7ah4m(n$^G6dm|^}etZ2NFTDKGrGs)1kKP_6m_r^+B+DeWrig0otTCGwCUw!B(NHR)9 z3W=#5SC-hft{iXZZ!zK|Q0+ZZD{~raA^|B(&*uCI5Ln9iF%RF+=eGvdpWj)tZSLh` zd%uS=hJ8qNMKRGqQM2m>31d1^+ayJ|*a<-{Nr{xX%Wh;S9`=-aC{VEibRHB&$sj2I zLLMtaj!Jj~gJr%gAR}&Q)j5gy0BE?-@E8ZcCP?xaXH>!q#ENh<&bt>mD+2rs?btVW z8qJew^?6NZ)JT)rEnAUn2`?;q=6&MEzcdpJj}d49W|>CK6Yb)?TLG(atiq`FC-o6v zu@hs;8E5yT4V-fk+5{UT;Yl09`3?Aki@zRf+p;AH1)WL6ZPGJD01p;m2t8|vVD97_ zG0py?Nup&rhz{jpRz7m(?Sb4FVATpx7$S!l15#od(C32#ZG+SZB=|LFKxFL*^z`o& zJ;cUx!;VmmV|qmKQlNKTN+uB4IkCNt8WR|wrc#TsNTAKLI4M#E-$MgU2tne@9Ao8G z*e6O-cZ$OR4RkbNE3#)Z;^9*~i-$=h+2!T@D$oc2g^uz5BxPT`pC=>3c8px2_7@U(pJC!s~CIx+2v_nt~{=I~LhDooG((Kl9@s zd9w?zw&>NL*o-~&_?qIDYTOyr=7o#`ou=NO^GP4@QN;8q=9Sw&UoV$5C_YIGj*%&? zC)hi39Cqn`+3G!Z`n9UO=KhNZL}}4M;e&^J!U;vN9asPuWb?3awEioW?4C6NX<}Zn z4~je}#7^^zL1$nVIblF+eGvo~UJtTUT)>;}L&4tD8n9Y;vkUC6=Cm1L;N899fZ$6d z{80)*XN1E6NWv`-0}*awRi&)QeHf@tIL_a{j|32l_CJYSRsJ}J$Q@{4|2JOy;XN>b zsO^P&H%b$YzNA?Svmp32(4V*f!TwjcJ#g|QE3Jbw%ugov)p6Jk)pUTBV9Jg8(M?lh z4HDi}QtSzUojkt@lL1fw70lx+PM5arxGXU#L1&4Mp5KHV6s0Vo3P z0SzN7x0ryQs3YDp7zl+wF?ulzfJ#@lMYA%iUW-T*l}z)u0c z@GM(0QBYL(Vz`H!v5|QAG4ys+r~I2i{F8bVZ4!~Mv_!~#t1}-e6OL6 zcHF~bl^~%MJbP?-8)E0qM9g>vc{eR4)jOAy0f z*`SiKk!+(G+8m!l49rE2@j>HH>RAysFNO^akYG&GU<}P&8NUNS7GSynP#^+bIKh7a zhG2;?0AYBK@f`;^)7sRfXn<-|hoV*Sj`#rBI1I2vMlGC6j25xY*#xZOQ4>_a7z2KKkEo0DIbFX8y+C&vS1Qq~n zA!!jP>3;RxGrO0DrtCe zV|DejXZjce9GbuY6N3jscfSRIM8M{$4Y?@y9P?`R=kkoe3$fk=pds&N#sHuqG7(D* zCr076O@PyY#(OhbZ|(%|3+U6=5f!dAv8(fqqF#$2y1#>BKx5=1g3(YWXmE`K;0jxf zs;NW;hU&bS{#&+9)I;0(rN%oJ*8xm`Jk&-QR3KjIE!#owGl_+~M{k$omRK1ff$Wp< z>6(B#DS_Kcn}u@EtRv=ZF0en%oSy2lAk zP@^38@W{mO;Zu(4=U`dpkw+a6K8N=UP}?58zbL}lBiOt_TJ?=Pg)|n0hCj~rOtDm? z&4>cKH%2G9^u_4Oytopn-81cOvp392vK#R$3IlHEe~u_Ch>9-Lp}j#5v-oa|t%ult z0fSBRM}n`ewjNDnW4xiQQS}7h$td*q@?ic06Tg~e69N)BD&i$ukszm&{5>7>X$VUl ztBSdDT_X|l74s1h6Dzjeat+f7EHo)kw_hxuI6To4b3`cCW_=~|SGk%9?s8Ez@`-Nw zC1F99@pFvNjhwXpk4Cmv4{klY*_$VR^7Ud2SNBy$8>TYRDr9d{*{*}`h{U*_`0$;~ zTjl3A*lP{Dj~&lig6hY!-brW`P`>x=zpe@?8L?0jh&6+JW6#{W-(HzuNOlMBHAVRG zi9|>~{MiGocV{;oM`uZvM#W>JK(Spxm-o33Vf6nBfm!+yRaH}D znv&idhr?SHbYI*~f}96{FG;K9MqWM3{|z1LDq{XkakCpAM&%{NoJctRMs2$NipD7A z)~+|Sem+oo^b4D%q-S_TuNHSu{k~VIx6nUxs=_;7HE|Z>gjYre8dsGvUWV3-3C3Qe zL|^)P!D0&gqc=`-u~|uI|F7q~E6Je(a{O$=%Fc#wXP$B;tf>fsC)gd!#-6QLZLvNJ zt2!bz%twgO3I`)6Kc7L5RdGvt-Y7=U6wE6M{nHEbBEy9vFL!mZu5K`p90qDXFli7@l55?m2XH#As>s>n^FOL1*9`$Un*n>NS*zqHO=4emGx3}emrd15-oTG3<1ZLY5HLEU$6@ zlfDC}Z2F()5!cjCpT(!2h5X3P@xhH}k?N1now`GIG#6g?-6fH$mWC(shi%@Zth1U{n6j9w~Y+~`qhKKT#=YP)0WXL7*%N1ygBEy=UGw>U@ zW%*OwpNabzD~K#E8y>pW_!+ZiG|Xp?!YX^IT);!7F`pRw!GQa<`STdd_bW$aPVl|% zPVir?%-j%@n6dJCU7k zXY(Sk{xYk{>@97Tw#mf}aGY2aE3w!4NAv-=cntnEC+;POb=EvngWgAoge$2OZ+mus zcxn5%EcdG2(0Nr!N*cvZ;tgwA|Imbj+xLc`>)xo-e9bvAZw>jKkHY9d?v5=s$QyZ2 zL50aM?*v;&Hh&cxIPuKqrygB5^@;qu+%p=N_sgCaH=Wdb%ZZ;`2t4wxsPu?w#UlNC z)~T$*x)QUFSi!^WFTk*f32bszh7nKJ{e?J>G4UljG%vIJf!I7G8aL)3u3q*Y(s|Yu zG(J}7EE((uJ(gKqOdrxqVV-x$nxA{Jl=j0GO4v9EXJljv{&O@v=70Q zbjE~5#?+~QkQf$(lnqx`hdFX#U47ec-#nD2c2WAty`XZ0J|}-2(x6tCcBae0kQ31v z(&@fMF=E)Nv@zQIwEywSK<)3TP68W2UcZf-vRF0_XH^)gaK<*M&%7|uDo@S4`S)KT zeXz})$Kd(UHq||f5pU&?W%2JWSEoiH!~$=o42W9voNj_l%$>0+zeO(YH7iLrM7)1T zqV@-YLatBD0Frvo=^ozETZAd{|C2}^|A&53|KIr^Zt4}~ zW#xY=tIOijGjspR=o4mw**z7iQ;8K4?ulvKY6K3aD`T`BXbYOJ%J zm1?&b`-(-{hp@P>H-)5CXGIFB?d|@&OAONS5Ut-omiyn9Um*wQe7>D&ddS;k%-yE+ zY4sjjl1(AaMe!C>Ia+xhwVJgmdiDkB^D2E$_rp+SuXZKeq6ST`8L>{TX_MNMlHhTz z=?EKL#)mD-+4^%i`UPqs86kVhmj5YsKP|yI|4_86a|1S! z$ksYCTs@-yW?eDh1*(WeT{-!$1oicjMp*RAAA`xs)F;W6Z|%=LcpiTBmneO*dc@(p z`3lcNjx>S6{mX7??<_PXj*sS{sMCU~8EgOq7-v3*sOY99pUQCJ61|q`+F7ySAR>%gc1@K%_w~np8 zuM`RZL>A`1G#F6J1=7($QBDk7!bONuGm9D&u?2Wd6$-TB>VtyaMxj-K-=8Sn zB7_0O%i#Gpk3iPaO9sVK`H)0_$NXzYI0b+r<_3vjBQdA}7kz3UmjVNBxFiH|C;eaS zhPi>={P&=QT|omp0~RCOqKU$1jJ<(+nzMdV+d>7!TmUq63v$D^0n7$Y41l_+;XL2z zwS#1L^*z=VJfi8pDAlT~UBG{&iGLFjg=#bEvE`2U`r%rHvc~r0zF$EHQP!`T%{BaZYX>@l-M{ z)*ZnhQVi` zgS)mO1JW4ptI!5=(oNh@q+edn^^rVz-!xfQIt;#+AG{%={YSFzMTo0LT!-W2qV&^! z98SpPGFF5{k+Rtr8R8 zyYE#V#1y58eU=rP{_@$qs9#e+%crRD{Kf#kG!DJ`~rcDbAMEDZq~|qLyz^bzr`?Bp@FsBTOx6B@7{Ec zFf;q&TPO{dfaHTP$b9+7)Vonr%W@5TxF>^f*UUbWNYnte2Ey}Bch?V|2t<7g0Cn{~ zU2&4_u{~%&6vGCz71U(s}Ow|JxGyr>lP$^{gHxdQf) z&l+7E9=FJI_^%L2)Mb|qPqpT}sXMJSB^)e9am>q>)uJ$=UlWzv4jW6cJJ*6Syo&D< zthzB?H>SNqerX3EH8}a~*51p?)TN%TN}3kqe((1=pt_j4dFe z2Rf0;roTdH@oLuV{5Rl6Be6gveUj*6Pj~z__YF&UUKu(eA4(5VTX@0#1EPuA*nsA7ExOIpY1y(-$L!He?NBaOR3!q1N+TzPNMUUslM#8pu-0WOEWkyRmbLw+WYr{ zmLDE6w=EVF+HOAcW0T=;n}khBz*2}YOQID4@ZvchCEvxJWxuWc;q`%6w7QRrB&tR{bVf?MviYifus5?c0|JXhMqn0nr zYB@hFI5aA)y^)gmfaprsI=v=gUs_TTi)I`5h^+eqVNVE@kYT2}aznzV-U0Wa7!gMv z&UHwvsR|9kydv=|NPgA3kdsXQGLsj})7OP=2MSEveX*nl#2 zdSYOD^y-4mH2>K)*o=J*W(-RCaA8$qxSyv6yEpZl+CFsa9pzhPo~{A+BcJ>6@s(OW zG3H(BgcU>GZlFc1{`E4O1#sme&(kehM$JtxCah-8OlZ7S>FweR@4y5#R*_~e6ML&I=H9)SwphCAc#PP7DM;u~ogfN<`NLd|u#@bs( z02>aS%dY~I0kn9oOqS|`0+FYE81sAUOMt)^V?Ls|3{6pv5}Q=q0yfPQ4V9C+jzcSa zWrlz@Ca42NltS?aR+ciDUOE?*S%qb=C2(p#;`X#P$X$_-a`&W;LvQmmR4~8AFzYJ+ zT@FM0cjE$wft>f*o7exeaCS(n;fZ{&a-JWUY~+Q!wyYn`3Ne8*T~+Si=QIc z%%9H`LM;r~;~UR~^1?5s)N6)d;;X{Dfz78?KuHRWePe506c2Ly{DUjON5=DQD;6x{ z9o0n2IC5ImhiN}ULjt8skRb_AaSpy@*FLqVfWrt-l)EI#;$+O>TACiyZws+zJm88I zYPgHy8i!5l9a3QL0IUrZlnhPdVtJ40`2YuEgif@~xcyhmps)bIrUsEkNgEGhtDDy< zkj?-_E2Zby{&%3kiV2^cna_MnZBLm3FT$`YwN}@02j9>eGqy2&@a>}BoKyLFV6#1W zYWI=S34s{ESGkN}!>IU;#lMS)07o}@U2236gTt8r%f-^CzDamt#6IsnUHBYZR!ahL z9Lm31{fhkcA%BX4TT9zqbkaQ*l~-Cgfx2TJWEY*N;1d;6J_wza75`&P;HC zY>c6PmRv+$f%NskqH+tLidx_{$3+(;l<3K;9(-EgF5x9n&cU2P&9V#J*?LDb4wjUjw-7cUNSVB5 z#VC68dAF2$QU6^GVhs7v>3LgSHf^CTQF-?FL_EtF%*0`E4w`?Tq&C%j(ohO6 zO$So?QW_J@W@m!&Y&%*LwPoW6rV^7?njqf7fXl1B@m4Mv&d@BvbzXu4*Y@o4io-I? zSVXXZVlXtp`oW{5yK?dfhHVd;)>Rq>nWFqZf>m}Td1Eo$28*#(us3znpOg@cz7LrV zPM4a&2{#7K;ubu$5gS%i|Hn zl!0BC;qF#GuR>O<;zBz;D8gL&K${ zNlTU5Ye)+a-uTek3nexV^o=+T@v!32}p#_-8MVSNlBDyvhw@muSKxl_pL8HJ!D<{ z@c7}{?cx!s7JU-F+pDiWc@9DEGN<_CF@A3|Y&PZP z9)GEK)abY7xf7;p%kSQNni;^%)(vA<1gtb`75U<86ufR4UDXbHxK>5FB33!-G0=@A z9Z}(nas=NDB%h?d=yok`yt7YSn$9UTyi!>9sGweC$I(a!t0%}J8OTJa|Kf>~cWswj zx_(Uc))k~y`au@GF1@o-rjToTxxRa z`|McXzJ@p^TF=M`4kgDnQxxHH1ineJ{^ksU%*y$jCYkj5h3a!AsH3sZE*)rIfL_Yq zuJv3A&~q=QdfsIT#e|vwzT`NGa-mH!wiTf9Z$`l^yoWnY=@| z;bE=QXSH~O9;W00hTTb)-$H6CYD;-pK0yh+{z2aBkb0Sld63%UTc0DR3liC+Ze;nzw9Bmv>|7uS=odHY+A@+2LK)s|g zQu4$4{#ZFb2$o!u!UVLF=7?FIU!;#1=4GAEnN)}`fh1hJHoqUSylkf5F*pdIMq}t}RtZygMplI>8ot&0VZDz?Tlx28NvB;j4cR^dZ9b^d{E$ z1nAy)sSFIqy>0PpI!(l=j`t5{hW6Wv+U&0oRWeE^$ltIuMw!G84-M~l`t@{QM9!bx zeYfI_u8TT_Ol1nivnC}&gDi`Le^V6u&m*?xg*H@J?R$DAqCLO*c?vq8%Hi6pppPCh zhi6&Yx1B^N$RF{JQ@io|Y|^1@9Zu|6r_67Pbb-8I5X=MKDmeXVg){_2Pobl=l&_(tSB!+YR8QOpYV*R7%dk{OHd4lG3>)Q@wVh$sLYV77km(z^SJ5-X5o;1+ey`_V5cQ!>pdyhF_ zvXfloVU?tvz_Sp4ak$7z#%zV5+xA2&N)!~sE@afD>IL|iJgN7sbS|euF51|oTv#}I zd;Gec3@yn`;#%r?Nq6&pE>bN|O~koR{P`6-+!AQ+3#^sO9pF}O!hM(Bb{j$%mQ|JlN84jP_{^c`ZT4WA znwE`6l)hi57qfe_G{bHRZ$8#E^}~5JQT->~_Hnh|r|>o;vZ~msAhp9dG}s=()?|xW z@_dH29lnyfrDK_XCoRFOQXy9<78c&qiEt;gsN39`T|N7&eLg$w}Ju~ilkzkP&Nup{qFGf5pXZsl8s>S8Y`n z*)O$wTUYmC$D4A=myZGQy!07>zQX?lu77fC!qE?J@2s0bKRaSJZ;*Zr|6SHTAmlyg z_}PiMlQU<&McTB27Q?vB+~2S+-K0O! zc{TGeFG{JyM(LAikF%7Jp^!xM?Jp)HG0`2nPzK63B4y7w+`Bkr8sdhr{CFTs_2E$~ zRh5js#HQI+^In2}s~gC0wREldgwv|abjgwp4$_Kl*>vXybj(Bm47uv1tT;@8z5zT( zn()o2Wk@!b1;mhZsx_BnW10Xkjd$a&di)1uM=*xqp0WCzn8Ba@v49R@!ZO9X6oCJ- zH@-M&k~e2tWr!HXvS7dlrW!~+!5`SxO-58Ny5Aa5V}Y9hoEZmHYa0Z!|Na~!tYi#0 zn~NC&ItZFSz%syH+|s;yAKz&Z0K$};nkLcKFqm|DNV$ck22?Y|HL z7jM}%Ml0qPiFj8jBX2TNljk^aVl3#_0eFpH%~$xUqlvB?x6%P43&ep6EM&8bNTO%| zKJSTT0faINSE#qIe2?EZ!ru!(^#2~q`(HjI(1OOy7wJ5VJs&kFCSFzc z#x8}hNZOF0GEt%D5d#T(H}rI?-T?iMQpUg|6f-Cx)!y=c{=pXU%u5FlHb7M<<3gf? zm$?>Cu}$`tw@8y~qQl@w#k?}V@F;|Q8j}O3j9NmEF9HZ$#*Jpj$_Ma4%xbNK)nqc` zeOaB^L0^A>ii=M1P}3>T{4YgC_!IIc^>1C{H;UXw4TJ_KOF9k&E&X2T!JgTC8}?gj z#&GfEKoM{F;@NAtKGA=Ln&Il)61E&;?q=fEKQjF)wT|bKxr>LMp3|)Hocfe}=j4HQ zU1ToK4!!!NXDlP^^5*bGam9UAI8Df>%Nt^FqPww zIddvoqx|Ot!o~6Z5#yL&5(Y~c-EdKzk#O8ex6Y;z8S;hHuLMuz@fVe!CR$XIb52Sn znENZT<+_4z1s#n0Ep~iSlz$PT6Hj^U&%4p<FlIC4Ii`Bna0nsPqJX28#*|YF zqxly1&&%(X8|J|Vxyx0U{Cp1w79*p+K(}H~l~;ShHw*}6APBpAeR=XX7@OkD>a3?9 zK`sQs=XEArjRCV19;&XP=c?LSapIW#r`+Q%^VZfbQ7;oNUP*cTV)M3;Ev$4JQ-7s> zXH7tC^gf|GuYDFGQi9ed4%zLtn57e&vad&osd;<+$nGf6jlbEp2b9_^2Ong(J`m!b zpumW>Ia~CW83&jrS;uqq{tTIh`GzvcCi9U;*do6$S`FO(@&$JK9rjLy;+~%Ekm*HB zrAyV7Z1Yc(VO`xZRWXQU)XlKF*%Y)@bo!j&9>o7br;Q4$*@bxJuxX`Runi|W9H@U!J6cC03PJrxa!ImS zrki9A1IBzFd)TY!F;%QhV`0E=s?Z@(hgVxcF>Wyi6}5WVZak%p@P=_P<*FF1OyCA7 zAQ2Ky2lPKcy4G|<9~=ZWJ^3rY##lo^)Yw48bFxnF_F$OZb{KOnj~nXn4?9p#Z9qLy zck$U(l%#fd`gYYNAyVt7LYMBiV)n0(TT6B2Rn>1_kZgSN$Z8XRpR@;H1_B<9$Jxi~ zAH-OXY(DPl-W1TM)26bQVjj!mZaK#lvdTS5fswrLnIni`n+urR5Jj ze%BJ_uJGj5JnMl$@S^#lnJ?6(_F7$)i_}!tv%Bt?J1}*G;@mnzhp9 zpQ>0DiDH$0JPqZ8$p|d)+Jdi@Fpz19;*k8A751_BcI?64J@|js#Bv8YFz;ka6x1>XzSFe<{|T9 z#-P6{ZVPZzTP=L({s@>a?r?a<$oQW6sn^NLYWEiX}3fPW%NOJg(}T7?LS17k&Dv%lmMF1k7qTqj|_2->KDZNt`a$dFS@C3&5@ z9(yD;e8hiNln5kMz7lo_>b=!=LQdN|E9`OcZbw_C-Y?G973g`Pt3sE}5FC{NqmB=R+D&mr$e`sHRPxB)@1k+6!v> z>Sn-YhAyblI8Ay8Y**rJeMcnTo#v4S>DF_NNxyxXaMvUAwjA9H*(14*upn_(N%f&^ z^O~O=Oun!=+(uZv3Cv`_p)+|M>kIRuUy9dtp#W)}ll*GsrIcnmv?| zeQm^`MWu{AkuCc=RE(XXh9tX@JrpxzH)9!QzUN!N|Np!m*LnB6u6zGmwlTwJW-l2~H*J^R|#XcV9O{k*bC%-G62)CNF zw!QN6kG<@rCdNCbvD~;9PFUFGQQn_=7ZIO_n5^2PVulr83kVSOIuy|BBOzcB@gwiA z-f=n3HhFs9pw74pNMeWuC3bngYDJjq8A-f|{4kU>3nAWo3jgVi^^$%k?cusGvuyo- zuWtYO)B9&2M#)77F=usEV_1M%+{>gKAJ?nRhMcF*fZ^-T2rvUzc<&+bGo>#nW!d%e zO0}(Rp!2Glu`>AU>-ySyVKvyYdnK1qJ@HySGhJ)~Oi)LR9UHJ<1yzBX%ciO0%aA(~ z(IDjSV%W0Jh_>s-87#vWb3YI2=*ky)SgpwFKgWn(AECHF7^3MNV?O&H4U-qHgf;3U zEpjgrr|Hr*Pt@6TI3wHY!pa*l2WXd@Ss)L?T&uU#$k7<=w8CpI&t>Yoktr*?*gtDP-C)))$T*K+g zEiHLw1u;m|DWm-6Bq>%d&@QJ+_g)#Xl+7;FBPyk?`E@2!1ShgD^)tz!H5c z)h-`;>-PC8x2*6Y3|KJRkzILo!|+Eg-~0a<%9ja(*ma#~^P$k4US`766*5!0KWZC3 z5(&_^Pzf55Igym?^W3Yye^`A#kWIYmWU1;i5un^1g!hlTVSP(pd;n?vmxffi%gDR> zEP18WWX`~G;41qR>t?S?9cIr^JZLGRQ`B}(?le?y-nK#o~_m;6n>5K~(AZ6N`O zl!LDm-DoGI481GSpi9t; z|6#tsmiO)jg5&yNr|rS%h*bNr9`85y$oMzv0m+XfVAu6zUOoWL%40b@IUbhWFXL0L zBn0BcOH;(Nlr)Q&;IBA{-5)c6?7of@b?pc!Zy#Sf;1XCD*{! zFCr@V=f?I{4^N0)fsne}gtlF6P2xX^xsE#BNG!iCvBcEdGSuP7O`JYQLT9V#idC-c zUE6763wuRb@x~k85QvWS4h(>2Z;J{V+l}I&I+^E~&Zm`>a6~EEnabz@UD98+Abn5~ zW7yn%dd)NFD}1BC_}1mVb8H=_UlyR8MwY+9;_v-<#k>N@s zoPQ6K4jk&b7(si?a7l3@Av^KdmiDU$Z<=P7)cCNqL-O$oIzox3wS|7Sa>%l5+{VkJJ&2)KA)w7bE@l_CObFjAt`GNU2czh zQQJa{5^6EWbN2RK*rvB`Gmu7L{ zTh~r`$@HAvA|_qe?Lo^W_BNG$p39I^7D)tMDBB^|Y;nOaia+wNr$S9YOk9n%w%0ZOY(adOu!+S!f9J-J7@JLj+)o3|axTfof`zSjK_@vlBrV|~ zSxTn3D$^JTwF~%TV~L=pGCisw`%`{B1JY@5bxiX7%baD)w5un-YRDA{l3ZZV{`@L< zJMP3Kc0g4{2gHkW5PlCwx6H|CrvFJq@jnVRr8i*f+WeHEANuJL%1Uk{8d*0?S0`ol zYzm5!61y2V6A8n{OfQuVbUpgZxKjX$x-&IV77Crwy;X%MtH_nK?QoZ&1EMFsf z(hbWCvCv> z4ARtbY6tS3KY5!{9Q-=?dM-iOwAEj}NhXL*YI=NJxdJtMEXUn{lQw@*Rvc~#CgvqBW_X-+~gl)c_a)D5Hd?Tq|cM|yzvyxlEZ9=H| z!+RRNE+yqOB(6DlgnF}U8G-4~39)%^UlzT6WQ1Q2(%DIOuRvzS${Dud0kJUjeLQ0s z=d^njjZ_)DX8A31=HL=;^ZTmTz`S{>7hQL&b!Z*WQ@Isjdb@yMDA@A+VU1aA3g4yMfnLm9v5?G1G ze8Xcm*vmplqF=#JZk$XLcRSabb`NM=&HME;mojy!V!)u+}p3i&tFOW=&mGYiD%-yPul7{S^Vb(oOneobJG7&V@;4G!OP zn_psSJ1}k&Ae6&rGD3Fw$ox)@k}((D%ylmTNOc-z}7RmXu4~XQ!usvkA?ZI2gmS#Qza6CrMc`n!93?&GL^Dt86d&jmPt>gVcTxuq zuQ?_Aui_hT>)a~Jdm*8_kmJ><_K^I%ORrMpOK*}m|8JA=I{){c@klYh+yz?+u z>Aj{I+(;%EB-(~MGC9MWS#vzZYZW5pQoj2CUNkoL_ep(mRaW{xhUmtPJ$h?Dyx*bB zKBzWSEhYnU8`Y9f{V4^QjEB?A>FdUgk$?SDld|k~KCH`UXOI-QYd3MSuq#79WX??9 zPC)J^Q|_!6pcCr_76BRfOWaN?RMx;8`Ht`Q<)|Nl<_A{1 zcbOmShPxPVZz^0`932?uzMB4>U&aTXt)hP_SRBU2BO_fT<*Bc$1yfWt*tO8IG^H`O zB~0P`TBfikb{xKIXZ-!ElXm;eNI{ae+$yg3?F*L(WBaW7Y_HO3;-9!~QQmv1x6_k4 z54y#&3&XXBVBr9=^nWrA|9=LX9v7HzQi-j!a#~xv_uzHuRkfPDAFH=4FPJXNS>>D_ zqzzZnhXiF%9g}an9e?cCuHLvr;Y-_rjtB^ew-l@a|Cyn(F%xs|g6Y=M+Jir>&eIfti1?c^ny1%&jA02T9PEEpsK~89~ z%ikd*H`ycpGK--?tf!p-YqPE6PS3zK<57o-4+Q!vE9nqLl(yb^(Z@W>hvSr_MK7Y_ z_}6>Iv^|k~#oaEP?hE<{gu@^}FDYVlFP9WqI3a+%QhL72_f)HKkj01WV{?x=>+9!G zT~=v#nMo!7|LV1ht_$^OPS0&Q{GA<><$2nCO&7Ah`!N$AOt~X?ONUJYBo5rCfUhS0 zb+c2q{FY6ki}1bT4LxBM$$b^T(^y1(pQ8PZJ2&xgl8L)9rvJh7`*kiFuPLvkw+~FL z>JK7U%rpH_51)1m`}Z}@oWGyckt&P%Yis53wP2E!n@4-L2*c6X2-J}y5L(%#Wv@S z*S*fU^T7e@TKnw#6#Pu?i*v70g9V;th;#jar^ly9&#_f_@w12*W?(CZJ@t zNK}+nFdRd*wgKLRM3pVT6ztd?1_(}$QiUV)h`&Jw;4e=l8NRLZzvn{J)PG|kZEXMk zh)TV=QNvTO2uMqO)sbR{B@{(sno5D#Kk)^@1X6jFM@L08e+P(+AGUY}g8MuSU7Q4< zJ~j}07*Ux{Bc*GD(F*uW{fM7!!9#IWf^>mzI8>RZw4>^9uwxdnnqRr(YxF@%F}C18 zhE_N+z<-pC00{{tRbkA5PRr?k1FOS70=69N_u2>=&_DBUG{yG6hhD})ErpHCq7WQF z2K+wEf^_`v7O_?^8M{@9V&U;KlDzCGEB$&{@2#9Bd3A9G#|Z!#R;K)70qSqkM-y*%JXi+YyN2J3$I` zJ{&~XhQrGl9WxR*{YRN!uYu{&%rj+jnr6TlR3|8$o=n~;>c;6!D`D94y9FkZ#vl=n zY2;BPW}NXS_|}9AgarRISi7t!zO?9eT~+qBhx|k3{&gvlV;%{RfvavRv`Yma(h<`D z9gWAr=|GNNjSTrz_(N*OAc8%m`IGA+_YHC25LuhrAjF6m=t zWL}7X^lWqWmn3{AwzFPTwMV`Hj@vbU*7xto7G=Z4;~Jk#G{(Or9brHk@SdN{@s!O~ zx-^lUUZ1XU1((})&gr(D=v%Qs9-90!6}1EZWjk+grbadqYkcm(R*xtr4tkB_Ja7~u z<|AR{E7u9~GV+d%EHgxJaKXN_b~n}*z$yQwXhw7#3qe+frgm+Ih;i%_YACt$*_^Ut zrjtkt#t41zaP39!3-8V}4zpwRGsyGL-y=k&Z!SzP8xuijM8+n;ntXkR zT2sD0qWav{)Hetcbo)?ymNiy|!-ineDU10m63%V=>#KKaH;ltLP;8`1#T5_|aKEAm z9Nm2msA%9xj05Kk;I7718Tk3gouC5%1iD2C`XIPBdI8MN+l1#=-@j9-sZ^N-?+|tR z2EfUT5F55gGI}J|b~z0+Wo*n3HZW1wnsuAW{^Ayl?MxS&B9ow2gn>|9OM{#N1hdPr z%o-{Y=eNp!V(AX&(hKYUpxGlX>LOsrVqiPJz*$N zu4Y57X}zx9d?+IaZ*z(qc{x-`P%L(+#GUFKTUT$}7uX-jn^mbk=1+RdWV;f;!q?D( zYjJ)R+AE$pZ6lo^3I+1sC}9un{u&D*!Zru zMkl^d`%|&m94{7Lg~BY7`sxJn%Op=0qDGvs;oj{2gN#=cAE;(!cfV_Y%dO8EF&ZLF z-So71+S)|Ft-XC+dRpxkOi5-ygY`Or&7qYjc0tDB@>3tRj0o{eTFJ!`dPj~6Yoy}~ z?WVfn2xe-mmcr^Q+^wTIR|c)H;;B_)BcnfwGpjXM<4y|?X=DOihjPs5&zb!*?R)*! z+vI0@tK#&5*D&e$jJWeonK`{}0HI;UsHFG81lfL<{+QN=J&Gg`pp5F7!zbkr@qFV} zDa5>tT2h-Rs5wHA_D566q`R3IW@q(dlftAmx1$%46kWn+=`!9Plp3~}SU~gjrO=AJ z!hSxYn!Hgsd88u`?O|nj`z70TnE~Cd3d5h7ldL&}@NmYp%VK;fXoi<$$&aap(GKpTH0+CZ{D_j;d@q1l~aWb zEt6)6J?C2xwr`5+N3hF6#A2p6h;;Ke&8|AjC;}AyIcjnZ&B`Tw|kzZ^wCnu9p zp}A1Af(_CPY5x$I+s&n-C;0qF1yo;wlf^kqBwnYn-pZ`N!W?F+@O}32;=p5ElR;d5 zhK{VXT3&a9oO*3HeBLhgM95N1l+d%p;co@h;KgI|Ck1NRsZxWPr~D{5%zGZ_zEo#A4eb>0yDRVlAtXQwYrNe&na~ zS>{zT1_}a4?i6r*mY8m55GwODwsDi@)LpRAt^fxk;SvtZTlHBdTLu5+1bIp3yPJDy zSz=GUL8^MmFRjYo#h7^&Ajje450dj zN?+L`wuJg!t)7jCwD{xfj=zN(B()alcFHZP%_`DtBOAfKjbkOX?uA_^BTU6T@r}AN z@vJauf)=>4`W6;WxU)+y*jkIQE)C)|fZn}vv%KezsZfl%*g8CC4L(+HasLeBQdLj_rEIKfRqRi|ebBAUHoj%%F_J1wE0a zB#vX8J`kY(&aYCAnV0QR1}L)65_EP0P!r+npG!&h{&+QxJtb8e$LVe4lw|e?UPK(L zT@Fb9H}(fNQiGG#!a05SB({9}8a;=iN4^YO7i`;I5!LT>}bu#5~8#uEu^^uyxd3R!A`$(pHqud`(n)F_t(YTVc&{N3d$K# zCG#}Y`Zk3{neZ6Al6cw|gb>Amk-0lxv^9GFkCfPR`-1WaM9hqdH@#!xK~w_WwV3BQ z(<8LQH%$#~>7OyoyY{wpa(fHYBkG6KsS;>YA2xdPB$`4mo)|8^HQGS>(g~0|eU4jw zM(K@vB~o`X_?#ITh-V0Hz6Qsg@~HcIp}x=`x8mVHQzwkp_0JmL6!iIUQ}DZwxEdZP zhgU-}I<7m$3S$JM6ut2F&lpLa0uiZF8wQ++*k`Wu+VJ4H%dCpm-`peb$OSG?CO z0f)&}tKx(Z#U2mX$RcgmK!gXrZ8KC!YjLSi8%{m3dq3TOcYbQt<$@I%W~FX3hK!HS zh`Ez=SC!!EOX%KKdCqJJZ#i~B92#3}qKH*OIC%!eClM*6N~bv;GIgJ#GFsK}f<@T8 z55zN5nae#ztDZawpH9Tr3N<{0jN%Uqi$?!_RnhZxh*r%9E~-=d!lEN1HN#!y3s0WC z^vD-oG95!TGp@v9Z(k-t{tP~;58Et2_Z62Y!SzMz(r@L*=@BIkPAF|ZGb|eUkAXdT zlVIx;SS1Yx%-;YE#Q7ruWF5B@13#%big+0%;HAjW{HCU3NisGNRpk}$QTZC7?Ln_KF2h)x> z9le=)|2xfx0krLGL^Pi(OY_|%zZzdDK2-+Mt0>}P(=wDbMnW`zt*{-T-LCl6T%ug)Nj)}`Wqz6Zz_KU zK@O8<+?Wb|AitzG{ZSUUs-&xbVBg}HZ&>xIXTkFW(-T3#ENJ$pSEVLvuzb8! z;XB7me)mTq$$V?JFS1L-Up(c}FO@K)W3e?M9fDr$m`>z{skc!lm4k$?q^U+B+F2nk zCZB%yht(P(|8O{HZ0{6T%Hz|XHm;=D1B5v#ykD7guNG(jiBp-Eui+4Hy`mO8TY=m# zlHH}Zk|B;#+DH-KSA(rtg5DuZKW^hzmP|eG3tfnweXjZ4Bv*^IV1vv!rfG1#K0&^u z*Q-A^s!+b)pke#hx9^@Fr!#aYJbdu;k!{PDmfb(C#t>8`(P8w6(>^!CjPX&fKafH3 zSg^Qsa!*}K%Z~6L2&4<`ltaT#QogpP)i6Xr<^jSPv0p!>lUifmY_I2-GjN- zWRNP7YffYko+aF^rF7mpUWPV$cFWO7rse#w_ECj6gR`Q~gzfCc_*Vy(i{$InXOUc= zReomRgo;x1cz1x);4gUR-&u+JQS=UpOr0OT2jLs`GiEXb^A?Vk{+sK>7C-h}t_Y`L z;bO4El=8wiZk*JW=$HL0ijM5!K1-T`*LUTvH|G#xzl<@C2)UZLO@TCeENK-t9Gn+D zbbPifJLYXsF>kmH7cDN+bMaUF#HmouCvReRk%pn7T1OI(BTo>$q&y20jIYLjo3Zjj zRr75tykyC9kS}4(ZB90j99}jytreIdqHq(Rph_i_37t8Q|+Ujwv27#4Zip_a*=f>!mcys@`FZ znHQ1-UKX@!r8(pgioSg*q%CB#?(=f%gsk{v;f++{wP~`=pF}4Y5nk&M3}4r1#w2y>jddPGbd=@USN=uV$i1D(nj8N%3EPvzIz! z#+rQ*sB2Y8UmoU;Wr{vpD=VRd5v8BqaQ`iV__Z-ITzl7;wjJ1!EN;5fX`varY2rjL3o;DFe|JiZNd9a1 zd-BHOIX%-3T?Qx`>VZ+fA2@oHRNA@^Kvr>EV!*K~y| z;D_;WPWR4@i<%~77mqUtGLWGsqjGcqm+FB9PI8gs9q9I*L&rEk)E?4p9SDd+lQ$3= zq=iF3Sq~C7(|AZw0RjX7#Tx%ZsaP=pJ9$%dJP;NuP{oG~lYdGh4j@+Aki}NefEv(L zQnTZ%1`Wr6UBFE`;IHU_2WtTe=kQ_Q&^(HQSaYNR$?`*4HREIYF4(33=XJoL!MyQM zNK6CFS=!D2F@Q_kEk*o~h!>g%6t!>?(yq!@fTp)oCRD{eRCR}c#yA{m!w9IBKyqvg z_6I^9f||TGWgA=N`T7p7B??)pEfH(~rM5L^%@N#bOs&da?g;`gqW}AK+Zll1ooTE; zo)wzcw{6^F4uCK{VD(4@K$E7U$AKIPcW|@tf`HTRqll#iN(+QAs&?pkw-u^7bgLg~ zmGEWde=1`j5SNVG%!`lKsw{B)(?_e11s`I94=FQUq8#L%DxiqoK3Xjdj!6!vJbGUd z!0Z6TMX==0JN^&L+xcx_Qu46-q?+xpr-r>jN?EX!x?c;iy|~zeIa8qeRAL%u$3oBY zm+w-R0{EIGlu;9q`w!L4>H=p<=eM0huuCxP{$t1LZtf@R#RQrTWv8m79Up6dQn^~n z*B5w8U{}9)&ISwVPGV0+W^bz)9eUQE=KG=ar~phVlquh^NfHosBIg9dO!NH??d+34 zkX2u^_#bzB^!p^Bj?)kwGtX3v#e5y1&PfvW00q2@azd&ieQzRzGoE2ZUsM)#&3l&l z@14AEg|z*ymwhthp*6Xid*JkUl%O!6{Z{W%UC;~lPxMa(R280o!eN4vL-Sc4q&}8Q@TO7w=L2O**)IG!nKITKM^8mx zjB_hY2hB8h?%UEaY|pAL(-zyBdIJB1h6x2n>`{%9 zE4+A3HK62(<@+AkwTdSC=E;Z23!{Ha%mN^-|$W)n& z<+m|?s?MEvjQ_Mw;xQAn4k6( z0ljARr71;b^2lmoirYK(cbc-}3dS0Bj3?{AYbNP_uFMM7lQ{ORB0@gqA=Q@t zc_MYMDZMOb$dM7h*#CZT*tV1D2AXRyktdc{${4?{Owa#i&M}w^u@@BB+MCZQIS`8Y zo7n6H3H&L)Tbic9djG=c;*#?A#Sd8B1Z%XWwfWf- z#q8-X<(cD;%;sPua_*@_5!l$IM~~YHF;$^Dl4%i>LM7VBWl6q+@C{K6J1itONrvq| zhB@Cg&1hV?dntRN*@9i15CRbw?yV~UwbLuMVGv!{Q>B46#ReQ`iwdfoID={|q8 z@#wy5CU>^|!x##Hdt*O1jPHDoYe&!dt_S(njawc(JkHGiq=|OI3?7B5070HRP6;q! zh+{*P;dkIdZEH-vC4@1CH^`VlCV3HfDjM{6I7A9Hb8nE|p6ZA>0lGh6BnFD7H8f1@ zmoNc9)8mUlNh?@RapmK)kerghWg4C9}pA2Pt!PP1nKKes{J#C!2O7FTTYv?ur zj~B#6wv7Grm6xD8T%t9zNn^3#W}ZYGWA9pf+s8l7$B~kE9N!b}y4+T#3UGMsBXeIe z4xM7TPHNu@w-L_WnUf#U5qgv98N>gUvo`slOWJq2rZ!gi_wtR#Nj=U?zeu?!0zoXp z?_R|}IsNj1&c5$X-ttu&vacHQN4YQ16`N_Yt4}C3Mm2qwOqVa{9I1>D1(jF8-m@ZT zX7Chhxu7|R)VaG8s8z-`Ue|lS+g)qGKCSC+FZQO{jjP9TKNH{oif3@Ih{3`x{+9kZkIK~>D+}U~+JiUMV z8@u)G-e;%Kzay>xZvNTH$yR=C`&ve5^zU%4AaCt)y96Bs+9h4-MyV^OH2cfK4_K=~9ii$fRtQz& zqteMUHEk65YAEZp*iaek4M%R$%v7@-=P5I;-E)0>2h()g{@}73$G*xybsd@Xb|S3M zPC;LH0ol7opPAAogc-5WvV51kOA|-WuG=IqURChl170Fw{6ylaQbGS^T9(K1N~xKO z{@;tvg+cq*g|(uC6EeZ-rBn&=dwK5LoSwz*to8RSUI&eu#NS-T@bs4SAT-97P8)rW zF*-BR;-IQx+5GW5GRpbLoq!|T8Kl#nQfE&P46E*0P+*V^8NbiR3~=#R1=*STRKs6S ze(d`BsC&t&ok6vcsHwxh$|!jh!~>>B-WuhI;-53aZiXk51d|xNA`p4o>xJ?|?(xV) z0h^TY`*RBsayp~a-sbc{bVr zh#P4v)NuX^XWappEBz>){DT2wXDK#R#Vu{V|U47YEfN`*RZRQ;Lf@;I_0%t2YAf5Ck|`cProNiNlQ!8Ovbw~spAjn~C# zvzcet_!;AkvLB$}YYFh_virzcylOl`7?gq|gY!2@(b|GwOqUH?Gl5wHHl3Mn?cQHd zbv7Up>{ryH7k^qm?E-$0F1=C|n4nVcn11DLqG4510`x(y>X%VNjlZJ@6Ti}CT<#VO z`E5eQni@GS#R_vR5(ba!IizPf4QEFBQe_R^@H?(*h!SI(SV6;zps|DU}<=X5v-Gm@5YSOd?J=Lv}Ow^VeYxejRy_ zPxf9=Ic=BHh^AotU@^Y!c15CndERd?Oj`F8-z4x#kaiEkwXbBS`px4FA|C**@V3X| zXyY1{Sg&+AubXkVB_$kV*OjJIrzxiP{(ySj!~hYZIJP9?&vI_)wwbu1C~LmBmeMum zzbYF%=KT`MX0;#lRAUh^MgML_*{*5X7JOEU@uKu!&qg7K=_z5X)sWX7A8MGsxBJseMs>KW9s2D ze600oyLm;a;&W=u^?DUMs?FscZKJ9W=EaSIv$ZE1!LBZc1Bw2bIj^+46GZf0MvOGCt+M$N%utF|BhX3AfM3QnwE?j4^hAXmOf zQZJSHjw%*GyH%a_n*D+_{h) zAvVQZM;GBKR_73;AtY#b=tAGJm~{IbFoi&tdJfcabemv&^W`aJan-?Vd8|v+8DnO& z$E)Y>GoB(%MDHmUsVofW7F>GKen5r5$xz)&9jlA#g(~07biAdx&=`K>`K{H@sakqa zi*ot*F)C}gg4614L*z_wMW>WCt4znVI{5K6s2Ijln1QGhYgueR0_=*y>aO5o=rsMJ z*v?V{cG6Djf{mN^g+FMC4QFMcF9KUJvq9%3Ql6A<5yEsv7f`JS;q3T)P)P0`bA2xC zo*LnN!uQ$J>hntx4T7%)VsC1|R0fWwT!$XBLm!p@cy`u!Q}6mLD$|wHwj0jx9sZ)x znEmE7B1hADTl(yV3$z&BQ&5#!qiRP*6PD+S-&cwRpB+kI?x%Slvc5+ixEHiR|Rky8IKQ8-2bEw`ACUD#Ssu7c47+DUdqQ|Kk;@mD=OxZqp|CeC7OV$a-;|@2g zdRMxxA?&t%DJ@H8Exsk6P3_0OEs`iT@M*EckuaeKeeb)zCWv4EF(mE}x{E@?Knb7% z4@2G%4s5x;usFdcU%+XzIMLU2;$d3Yleoox?Z3P+u4gxYZwK>e{nDaW zFtv^Chs|;g9jz@yhL#qb77LVGx9}7m&bj|Sv(x1X`GfAKi~hss@w|v+6s4t=>B-P16xo2DET3KbC0ypy*0&lj6|ESH+%BdXb z3jpmq+66gptW5^`bKu2$y!f_l-<500gOx5>sQ(5pW&e*MF=wYO9CU(LzG;=CpsC_Z zD{-}+lJuD?*W^Qw|FLqof(lb&`d~Rs5gsYEoX=;b-I8AW!?hN=il>qzW*g$(c^7Ux z;0$zkQ7@xGbCxs-OCM9i-y>dzkkYc31Fb2zoKUvuYa>V79y1p|hPZHSCOp10zLG3@47 z9}HN8q#j?w#F^N##i=JuMFzB)vfDw=;!sg|TkL_o<1h1WVZXi>CDo-gcAGa3q6xP{ zC0%NUoaSPz`A}=uR*Y4L@}}`C#<0~Cx0?Ihbje>X#pACY8Sj4nhaBFo^El`a#uzUK zbP{b8>?Us9j0UZe3UGnrZ;vMkQxM^2!8PT73bj-J+P&u5NB547<}>9@R2DQy470|i z)w1YdhPvR65xPxIQ`EhsiJ!BH)QXFJzHIoPC&zTek* z>7@@Rn3Rct5HSHuU5IFX?az&Up!z2v+KF7l@)d4azUcU(jpgMLuIl@Uii{-#S0E7dwqp-{cKH7%&NyA##xL^m zOyhPMpcY#JyB`H&eOL*O1SUaX<2!T-4$k!N&seieXB~R`gd>Zs7^3mWL&1(1>@D$6 zuR9bL16aV#@K%B=-e526su@9Tqh&`w@Q|0_+43>kf&^tA~0Wj|~LO zqt`LEQpQK{A}nppBpQUg^Wo66_!}=PMuz~jaUPH*hpH|pUHE;d8!`ZRMXhphqUjg( zKi!ZTd#KZWcmk@SK*QEQn8nM>)Y2U@wtqN{>H>gLc12r(=B)r0Tmm@hgJ+rm{EZhy zY#vkSPY#1YKp{oWwok63CP1ear~xD3k5fQU{0aB^IcRP>;m& zjtcgoc{J|8xP{`t2Iv*$sN#9hpbopbG(uv`cX}#;#sLwQHsp3XaFkc44Zw)Va5B<6 zB{{z4sxN9VGAA1`O&cb6lv~G|E@&U>dmwZWl%eS|2Gvd!ng=)7fD_eWN`^x|#0x+ny?}J>MIg^`r{c6&vbBifa z8xYL6{%6E|rpE2`-;inJRqO8QtrL5glt-}Sx9PkJPYWxzkdEJ?5=H%}^(o(_sil5p z&vRE@{s=fMoShTm{*R&axB%_))_xeRMbKV6M9I(9`G+%UwtJqaXHzC3b5)m{uekJS zd)Pe_?UF)EXO?SH7TM>+qr2?qS7H@pe4d zvzz4?pIzDxUn!fNm_BE6km6n8VA)YJa!lKI zV*F#8T6$v63gIo_@WMHWB!VV|hl@<@K$(~3Dvdi)-2!A1jp(GgVR0;#7!DJdsW#Y*a_Y&XOtzz ziZaFsZHHO4cu7D*3)Xdxj_#DjGgqRGTHb$t-6d?M2ZSl%$Psg+mgvEo@{S9=r$RSM zj<(Z_=ygIrmn(-oLgoh?hJSdLcN93g=!tPYtVe(%*)Xl+Dv~@H2e~2{W{Gup+F@Gp zUX(kA?G|!zj{N4Xxz}U_n0uEnZ>`yG6$n*`UM+<>vz$=kJ(xIPZo-!_^&(TD@^=+D ztrYoWQ1}D83B!xby4{36mJh^DXb2(f>tl|F&&w7K{d$+Pk4g_ahN!jUDr8dmDNy8LB<;4Ah0p1unc1-r*?UGLGp8_0sa`BncSlXb@l~ulb zD8_=zF&#$XmA1uVex6ag%Cq#+t5i(P8f`dw#J3ya1gbzR#mL#|rF{;b4YQnJD%~s` zUW~ED*r#w&z&_q4yi~ND!C0uEP$r&{l_4@`ILG_y_oCQhO_^U%eKh~dXR(~#Dj*9w zO~?i@vuD}4gi(6^T^17`p2a+w znoFG0Be&5fhpNmhZI$PO6tSx_4rDMayq;|J4(9aMP?gVBW zi^JfxmANiff-_LHnu@izq+BdE%#aG<$LGL-$uYW4Sg-J3sPqqiR5OkiOa{A4L_{N{i^ z#R{>4tA6&kQDPs-?Y&aQ4_0`&^oTc}WI||96}k}Px;ClfSnOD%O4He2%iUQHUS@9+ zNnoC*VOuP$F|Jk4Hg?l!jNM*v&yWiX^)axwH&m%iOZMM9RNW zyJ1-jlGW)OJTE<{+Zi&1-k!z}XD1LCtL~V@KR{u?TC@Obn@f7G*>J5I$Xq)gY_mM$ z99!m}&*bdH!}iVNv4zI=x1@X1!)Km9!dXggk)oegerBF}^0=?kL!v_KOoYzR)Muzg zd?OWjdLr)6FOz0gT1b`gun^^)`B7Y7MKpNQh&pzaDt{|{;Q0rr;$3vGDAd~yCMkcN zI2jaI`v2U)P$(3mp-P&2xvQ6m@A7s3ehyH+@d< zilCh*GWERQ4f`$WFnzgI3l+s0il34?Z^rtgeaS@Ti0anz+Wm~Vn-%L$@I)U;7X63W zj|umGxIJY6B9?ygGaeZ8G*kk5^M3m^Q34ItdL}VGUHX<#Jr6ZO8Ptuhel#x~q2uU^ zs?E1v{f=Ktm#y5j4VTLT?&GL*iO+D21_Rf2BhbgTXwZ*+UKc^Y=>={ekv=~w1yg%I*pWFl8Lo2psSn*L{#rkLQF5eS zI1e?J&0HHPKAv%w4L+TGAA7wY@y0}2evH7)UGQ3$ntCKMhXnC-Zfr20Tr9d9!+gec zP_8O9&5ET?oh;lR4twTo;(2{3`~LIDf%v?zi7ni2ILd?oPsVc=0Ph+o&1D6o=N){M zXz6-VTV~?QjhAFJ2Ut1pSQeP(x-hdOY43+=n0ed-Ocem{#6BIf8uX%HBCv6L;u%vdvH8D>7uIX>U}d)&X{c%J|7~R<=6sPHzNHD)VEPZFXKZ4DncM4fldz|mv9(Dq z`f>z*$AUWq+_?PLw2;QTxQos-Mu3kL6qp=@5AJ&`k=L%@ql)S<=Tm6@GfLH`PUzal z@^DiYwMY+`-n4vfc0C2`^?={ELdlt;vRopV0LNpP_`-v*Weee*QFeC!K*BbNq);>i zLb0kq8&Iw6T_jygic5B43ox%lhYJ7P($$d~Rr|eDq6GW+culH$LU}Ei);X+!x$eRk z2^tgE9~1#c|I>Rm{MR2C6YnX0bSxtIHv7%yr1LF#SN7!I2m*U`LEB}3f62b0&909D zEZSn!JdM$a+G*k!>&@A~a&{^9vBRxDhSpC`Z?@Dvwu-$!W`P!woW;hBLPch=9o)^~ zCXc_^^|NlQf>oGLL|Nwrmb!#)V`9F=MpNQ6lmZ*NI@U_Cs|6bu|7SMJ|DQcD{!0W; zl$V{(U$2FRp+NOK_k*6|-y<5y1`6J%a@?}4vz*lS3q3%N2ga&h9L7B)HN@(+e5kGP zWGMB!yQ+8RvOnZJSK@B3J}Gf8!-IHhbnU58UXMHOgHJWrYOxU1RnpIBZD0kqURtK! zeY-R;qnIWIG9N#F&P&f);oI?9*YC56up!GOBukhD!%6(zj7L=8T!eQdo)|q-P#Glr zu^;RIl8L!yskLxrG)nU2KulaprcvpTga5CS0|L7D@jtA&lmNzaaBrZE43(D_{wq3_85^tx}8E;E%B>-bk!VudFjQFSvxfsR~2sQeoF zARO-bIkJyGwxZHKeR77roEQ+mkn#Z8v_ctPm!E#87N_H<3)|m--$wC6aK_5!^z*G1 zZIfYZal%!_LM2g=r_iznu9|eQB9-&N4q|KXF0j6}*{-O!`J6=#5WV(!t3-GPX8LKt zv<;J&+PL$F2V&Ht52}%AUpky}ZFu&(Q)$JP*+oOg@}uk65+3c#mn$9%&lWw&p8oOY zv9Ph>#s#%sS)MjkhDjXhS0;9)Q(;kF#n^G0ZCxUIPhs%q{A$~`)AyZ2kFV+q=HXiW z)XPiDKE2SqBdGN>G(GR^+zp=VzyKMjmP0Y(w=Tf+0*)Npv3PVAK!OgyaLl3iwhhOb47YzB$eD~P@Wq-BfC(2zbNj>X3OEAe1I%y+ z0Y!rX#*Nd9Jpv#;d{qj^ZhW7k*Htn2@z$Y9d*n%x1;_ZO;slmG18^SRF z|G#;S0U{U<#LRMjK=#!FkA|u|2T{vQ73?gx2-!COXu%Wn)tU_O@m?54@P8t_$U_zv4|sy zr4T=|z@TbBauCFA6%jy$i_Y6xW5RRJ+ir5yyULwF?pqwO0|F*!k^&hsi_YOU_W`3Z z2U%Pr1X0IDP_d`EfG0Zwq{Q0DH%p@0xmluYeGuUbC`DCNw=PFb^m+v8%?|@IW}-A# zYbt@%#UOz&+ADl%b)a$i-3HR+OVyayNoE0__PE!_)OVR_ zx$JpUcJZm=Ww{;a5nhgZdVFdydp$onbI<6`iqetPyQJDRLV|6A8oR|#NBO9n&54eJ zXI#I38fkUc?9Mu#{u=U1SIR=)VW!+>Ar_-Ng?`(z@s!FBe)COc|1!qzcocmLlYI8U zay;e&BQPlMw#=vdB3U^N=HiHldmtr-dz~RP)2Jy=0oG&9UJZmF6VZcJAX*!VU$sURd4t zK(BY>hC&DH_v1cQJNmIDL6RODDq{7z&uEUfK%tRE1VAA#%-c3c>@@jE^Qm3one3a( z>~EtB#B0vk!$ZcpratQe);EZ}6Iut}l3wgsh0-?NW_*^UmDX{5$;1+C3H$`K^P`Ar zLW)eJOs~jE?JE!ywj`D?r}*QJ?}D4Ldw2hiXz6ggz3Z8}!Dy8&Tr;VUYn73AuORYh z{0{{>#5*W86(wW(wD1XY<)9a%kG~dNtnG~c;k6mon#5Wp0CCBrhbAqgjtyy!_5BsO zj)GHmkc{~FVyL71pvUdNpF?3`wJ(0_PV}6vyst#i+k4OXI4r_>158Ee#1au5rJi@Q zX_fsev^_epQGEIU)63QPC3CXVrpKz!Z-sZCe5mFb?ap;<@M_q?(L_FR1--*pXxZ7% zl)oiG`{3(_$Hmay(OeT`tCNCS*0=dIf&~I`jLJ2AMQd-HWNS&wmc!H&HiqgEx;sw@ zUUF2fuyr&M!xpd7&&1`X=;W%y+;05%CUaB_?W07^%bld>KboZ z!XIF!6Zif2E8@>@?Ah~Y>`K7uO{|aE#HmfRqlZLTU%gz`!JUF0x7Q_Fzl&=;j3Zmv z4*wYd^b+uc-Z7gY8_KV2Fn4n}r@%t}X3IKS%dziAeuKO!C!w2#FH@>9^5mUwgn=Rh z1q4>P6uywr*2NWc1;l5LV=%O;D)f-#z23CNOR;WwZ?)wb!u7WJH1LCo-v+N9bY7N- zQ2cWN(Uy&suFlH<>KjJchb=MSx-YYsqKr}&qEGHqce5HQ$LNXSTwUawo{DRPyf&XH zsu#32-5M0c;+bsv704m-SJ^Vk;vxO%oR_4?M(WgZpq5@9^#HBe<^0x zwn$BZ_`5tf1BD1@kPdhte@eTS(!6* zB{m-v`o01e{55*fhn0L{Izd0lOcZ25786VTv^6!m&8pRM;Xd+tS9Z@(k&~%`JLAj- za=6lHX)mpUy;wY3UZZXM%o%CfW#Yz>&vhj$Esg->%6M&G#W9N3m3FrgwX8EHsXYbc zsh>Ffc&e+&J%L+ImRByO?31!t-&@mh~Pi~#%2e~*-EMsCKF-0P@ubR7qxk5 z*tx%u#iLi07<@LDqT2A0NM4m@5lhd<^*9gvkhKxEgMtcPg@grQt$$J#WxaX+h(P!> zDi~XuV;77e@dQ#peb1#+JpiAGP{N%^5j-v>I#Ma=It77$iOe5n4N(%DhORqje}TRC z6>PV%Ieba(uO4v=S^gNWU3^7D@m<+2yyBB8(-!knG7ynf=EJ#MO>o4csSb%v5mrTS zJ{N%}l$!K#Y3?rf9`q?CyulgXGqPXw;&%2FSV15xxj3&oNiV@oq@)mS?JlyO7>qa6 zt$M}iUSGXdCOy-$P^@(14e^3rJu!*_zj<{aUCcFq6+k-+X0R65r$KEUau-ex*}8ltNDKM zTPLoE$(CK>onINST_*_;KkLgDy|E!)ykKKqHOSKq|Mj!QCLm&lP_H6OjaR>8^ z`^*cTMV`l7o&6E#jhq5Z$m+B@Gfl4O!v!lr-i?a2@(gd>$eAt=#>&rQO? z_KVN?Fi9KWd7zDrGH%Y(h99O>_tXvv6G1@<5}mt3^MlYkUbiWTDCvz=>GI(8WN8sCv)GL2Op~^TsfI~=aqqV3s1($^q!0x6MY?q-c=ZEUl9KQ?!k?o@@8YV z!+2BY1K=Ur+4Bc5dCi~Sg;5%JE{k8sU+Hu@Bjk&1rZH9<3bgwCs0v2>#?a5waegu8 zKSNqplPZegh-kTNgR1*fX*~;xb90#M#;-h)M}R8gKJg~qcj~EeT$@N0rG@hP_tqs- zRN;IlB6WH7i~aihqZGN`UCjdIQ|E8mn+$_|E{)pB1zJGjB@30bY4pqUb03m?d;u(p zn8Q?gYSvL|v$N5*^Iq$`7hcgH0@s|2XzgmAE?)Pt$CC>%vz57w3_*Seb#?%|c5=~K z98L1uyY&yGg|*HpHDm$rMvWXN9B_j%c!bG^p%v0`t(pQkx0X)}YW7_rs@qcL{{GNi z3Nh=p?@{~`^Ijq}_EO%7nG}s$8oxXFx6?VaR+o0Zbb-f=~U`i1gPeRqsLG?hTKTz^?i$u2bugI{~1)T$`sxCU;Vq`&~L*bgyDDlXn| z-3NCJk|3fiCx5WCS)HwZvD|EwWX;1@3_oG+Xfe6sFjK;&!i z55H+3mmVE=Vk*C|vGUTYmE0|ZfS8x+hi@I-pbx-z{MDrY^6}IykNYLTgVRs>Y@v3gJ*4pn7JNG9+@g*K*?aQZ( zg=Q1~C|U1?>qHBZ4F`RZQ!6ZZRr@IB!j27;ybw`?u*6OoepCeW5l+6Yeanjq`a?bF z?36*LQ^v`VWpS5#L5ixvQ&1Gwld8(XhvZ{fU0mbfe2$HDD~q6X-0tQ4{x}$YB}eWl zC+2k``brbp%S0XBR#yy*j(_$r`}t#Khpx4?Ae>vh2j&xRJM=$U=`tTc3v;`X?-S>OALK0 z55Ei7N9Nyd0nq3_L@H@U3fkdTMrK#VtIHYj5-Wpv7jzcc-E z6qe84LAM~@q%roH{5k!D-d4UI-?>>cBbJXp#}~-+JKRrjN&6};=aS`Sy-&C=hzO=b z9d{2Yrk&~zyyoN~2X`)e=@0hShVytV+C)%8XZDDA0JHPrx7U;8@7b_v>=Fn+2diE? zRP_7K9uV%kS-gLy|7b}a+{g4L%^N{xZVo|~Xa;(;_pxJ9Iqc8O%^b(h{I|-@_8UiV zxd;xRISg{0VSjj8Gb@X?^=a2xx&g{Q>s$P^`MNSnHkzJMH+5Z5 zK`DE=66QrW)&11b)TdV??<218sbc9z_&C}Yu#N0aG6>$C3$5&(>25rq-$wYS@4xDy zJBo->F&c@akvMx|NP;$_hzBzL*FtEKot|FVZj9(R<;TxFtp(uBz+w?* z2>#(`R)MI@ZsxM)*Dqg$Ld38_!jUp&TbJ;-1YQg!AfI;Wr=khbEi2x?Cxp#HH zo5JS;l;pPD)9=;PCPB4sJ?VOoTvD^fvT<8BPlPGtK27;`cEi(B|Fk6tScwKfRsV{6 z)noQ+*S2OV=aUW?8R`Gl5A?06#qTJr#J4Wu+CZwHV~JQVO6M0ov>Pd4b{hBn%GG}$ zYMe;Hjk2{Mua4afL!zQirr-0MO>EvPj3otQ?=@SS(_g#betdao2WBT9+a>haRNS4< z_J>xQ7?ob}h4OLl3KWvaCFz~s8aAHfR1GQZpYX8hd^Z)!LwGO$@oX7HEZ;wnPnz8q z#~c;dhK~^MFWvO@3UGB(-dj>(_jb)pK>pHZ(F5at8~Mj3>->O`^y09K3qX!pUAg+V zR&Krx7=)D@5caURKc%Bd5$0R{&2xZURO5N|2rVjJb+G;^Y`sXM>2)=K3*F&F06tzn zJ3uz^Cdcl5L0={Yb+KhZUnWIgE;WE#Q2T)U0eJx-NM3p{S1{x#gb(7UXt8fcPMR2m zCh;8XRdGtDlyOxcc8~)bqQi^+%_Q{Fr*Sd~0fP8H2t+_4l2Et)^$&YOT>n#PWh4hU zMqnWZUf{~WepoHXUd(X`mxDg%|0WXx25~!@5RU#IQek;G&n$dfU#tG#?ZVq7RUE(U zcJLsBllk{Q?ZO;|&>U{XJ#Y>vXPj>^s$3v2P`OrrZ2=Tzjc((PoB21GK$8QAW6D~; zLAgJwO@G^n9GZw~KgFrM0{Y#54`6S{{ol?jH>hzXh)>jCbBiHmkzlQd3*d5KmvexF z{Z;OC4|)YeiNLkrunJu~-zU!ZAW$3}4Df@XDys+BfB#o%BIjR5!a-dYM|$0E$O4}k z&?mvy=xz6~-M9bY9_IL(!@&mi4aP0-Bm03WDzk+;5tMhKvAB!*t&AQl0yKGD?JomW zURv;4L+odbIao0$^V$|CImTzeSBBe##xZ#Q*LYqAa03rd-Zn>>@Ekg%!Q%9b$^U}v z0R>_V5dU^{K-(%Q*n|C(wK&T0O+VDWrN%>B>;sx^k&P9bA1IXRFa7zdIrL|s_ycKh z{BKDZ_~y2V`PDXse{*8do^#<4|LrF0V$3VB!F=)a8kI3G2inkPv7^9ja)S{uiP7x= zxr^Y-K}(1?D7-xEwghU==xbM-!OM&*-T)!8Di)nNtDbLZkq7++x+`gCV@ulm)-}GN zp8E=m*po|!)sU2Hotg*fB}~jOcjvF~5q6^+qHD?QMIB_$46b_1!hs?;Wazze_ovIl z`p(%YFB1>B)kh<`wu`c%HZ)fo30Z_R`)x1l)D{V*e4;+xP$=q*X|q^yhfu_sL)!8Y zQi*%hPuL&RyK_fIphYHds=OnsKe{jB(z5!YZ|(8AQWx|^Kgv_2R1d@y?E6%FAoJiA z>73DP{vVnp<=aB{eB|jZ@>@2vkZ*eH)Xw#1e7`TU>~Gbzu%x`E=!@OxgQxDB#=m!d z`FGb~uxESI)Yzb>?ej#_j_$lB=_~nUr#<$vTYvX5H@$ZDp{ksV4JJR^IM;MOCDH%`os2Ba!%C*J(^`lrv zZ>!3yS?7tMdF9>stcXhWFj6go7HHyE-yp!ZzgMMAukBR=g&gySNIrp zj)4>8ikYG(QQUN}eNxg~*jr?9Mqj6dojQO+tF4DSKou+gHpekE)`HKIX%0!H%HI-R z*NZ|=7e?29%KWv$CYGzHu$6`fZ~3KA?f00Ar99PVTzsqWb!w1h^bbU%(WHx4X*SZ} zmCa9)oz%j1&g*J~c=4XkUHxe;|ePbepsK zQ%(&7MaRM77V~h?g>j>TU`CmhegAs6n{8cFi=@me5%+|qU`|Eue(0!}ES$1O@6!&f z>^FALF&UrcESLbSGxO3(UYszvC9jU?tyht_CI)2iakUoTLh6`@7IiGdR2jw3#u@E$ z(O8eG=VWP|E%)?coKG6fujjHh`mZ|ElbTainDG~^YshQaRYjmJi)5GMF&{_OLYt=~FMsmM{yMfukVw>^G%Je(Cfl9A-seN=*k2vnr# z{x`^bjD%XKRu9H(b`}Qo7IB_8&>&DVtoehIzq_^xF>+c2$LP#w%ME7S58tvi*|M0; zUNz7=(vE_*7R4n;(<5P2=-;c=MJR3VpaS40}$)TQQB~6O4Ym6 zLkD&8t#)v6v#>!gd2dOGTd*bG%d#r6Und)-H@>CgmOxM#eF3HUjU@9hYrjP1?T^SZ z*T~Qwy~dcMf zF5J0ILd!)dN;zU|e|Ac*yN6Bd+EG9tB^7}aN%U1kP%DHVO1^#D=Y z7*1ci?gO^$bnm|tzi$5__8@n&`uU+L8 zrktI(&nmT3l?%U)yzs47<7ri8N}lPwZ$}5XEW=CGPnO8WO?Qj^=qX30ntaQVPPKSJ z9C+18s?vumL5g7hndt|gCEnV9zKSrQ$Ns{`YIJp|`I^A2g^r)>=q)b2)_OEHU?xW6 zOQ3e_cyHDdokYfn`pHh}uD5@YWHw8>*bbGcEjQiUbM@f)DE=M~P~Yf0&wV)-Y49zi zzJQts_X*4Sn(a#J9g(auo2iupK_xqzOO$ zuz@dK=5MG_9)(oMN<+x9NAGum{_p;G&TT~&$Niuk&63y`Ovll5xto?j;_CCCx$YRL zfDTduq3m*6E^kjYw?WJsiB{P8@rwh(;94UrI%O0J@}a3sV-C8Toumy$5&Y3!$-r*f zyt~Nj`TUtd@Lmg_{?K0O0*xy! z0!okWR`xfN#`Jp&B*ZOA!+M>jmOC=b>!5M#8p9X3V~UO_)5Km!{+TXl-ckh@&8K!9 z2(1Z5A5nk~tab$l$m|EZGLyrZsejP7(h!$)^jKbi*Q8Sph}yIPW$+(F|mNPgg#PQ zp^Ye(^q)3~G5JxkkPRA*CC*?6H~H0bNm#!vN+ID$L8z`UJtVM@Hg%ku+bPoj63D`q#^ zJ;Z)h-yCV(D|JW1IqzqQwWc_qDm5%IQH7nOh;3$tSFov4@o`wz@^v;?<$xO5+(SH3`>ld)oW#=A9F`UMALL{$iI1 z-)jZEPHTXvu&yq5N(Op_rW7diRo#{G@%g&N#>_!f8NZQ6KiY>wAP2FCRJYe$#_wbj z2il6H?#5YI<1#?f`C#DCmF$ep!rcl_`zizmqm=uKp=KK@tL-l{+TgIX_)}dUqr#gF zkIK&I)ef+LtAN;l9xmGaj5~J<0-mE!F!)0B!Vb6{<$uTV^FQ1A(?9i8z_nNq?_ueh?{}f!ugizY*qTNIPPAV5)emUODLZmew%qg_LT`4 zZYj-7r7X~!&5O{2Dhb!VAL?$M4tLupz5^gtpq_lXMp%--cg z?r#uJ*@zzYcL*7#R0x}e&wnpb;Re=VGy^>$MS+Dg*>lia9d z|GtLyBnu=Pzi-X@vfTZ|EWo6*59+wDazXl2VfN_zWiYOot^ZCt``(4Ix-QoLV`FRBKu1q zDn}cnHYjLr!T{dnGPydb*|JJ!t zGtscdUXlayY-~p3WUlldgS@RUtsYaeCjQkFT?>%E(SG^IBGH%K{kYak@P)#e+X=q| zL?>d7nq7;haOjD*E> z^=;a6;TqMui{2CzMIPKxk8n8CudJYOb(#5Ld2vc~q|0Ok-FQ^o)P zhadjW>_@+$w;i`Xvkp|Mui74a*7TJfc>FCPtEsCV%;FvumGmexq4|Lqh97xM29ZDo zM_Jz6r5e{mds7tgX*~8hwT|F&A(IXR|`Wt<< z7fve^l@ghsT7j{1dTP1E`V6p5Hkr_<%~pW$MPp_+7O#C4%YArzKS1~tBu0gx7Z3L~ z`_{8$_=4>DK6koT(oh-Nx0X+BnH_$fI`4A4a|*vLSCU)OS2W2i{mM0NX8f7wOYP2& zNU-AZ>*v?QTJ`0z+OFwN8d=DH1xv?df|Aj~S>>TY#r@j1y_9KjTN-End^aIk>B>K? zJIBcyT*LmF%J90h+<>)O`0B#OAUYfiSm;W)HyY+2jvBE}8~lhG{x zTC@C^PhswS{Jj9QECNpEVZhV@bM!E9_HsPbK)75eqfYz_MKU>XAf*mSeZX@~wFN_` zf>Ib&R2vYjb2*uWRH$(^Xt{s2*e}jWtbK4V@bNS^frlw;awHfIP{?p=EzsG*;^AP7z?FOj$5B6lOlZZC3AdTg zZRB%`>tD5%Gs>5`z1uqDof}smPeE>C=X&56IC-%+|MU5q-w;(d} zB-s0`0puvSKxR0nXrZ2)17ni5PZuT-d<-odCAVrjT#+LdSMvdnw_WJA7)i^2i5dl9 zDflQCh(O#07WFmoR`L1!mx5|(Y()Kt9yQD63v8NmG$7$_+u)1woHyraxsjlrXXHLG zOxx`{PlV#uQ$0_m(Y_+>_7x+LLF#C5B?^Mq=I&&q7dlk+0BQUNqfoA>fMek=yuo;` zeWE5D9N-2>Zv0dZ20;W-j1MGAR4;)UIW;`n?p^_3q0d+KATCaLrg4(&2Xuo4&^9*@ z>TZq!d=jZ(od?6otKGiCv0?`uo#e=td>K{eq^LnDtX{rC2XWmy9*$S((8YVBxa%+= zZ--uU(te$Sz*l{s_ntq_R>FA$chm#=+P=m@ zN7=mz1b383th%l1tgv}YU*?&TzBAoTERqgU)TpV8y{pv(_xtZ{D*uKmPU9K;)+uRY zLRv-brkD5pUNy=^%Xid^wdxqG9Jrh{Ml2ZA;1qGcunMVP(0(A{do4DlU>@8oLK~-R zs>rSZ9tG^B+Mz6uHQVdwZE<%_abtsQ0vO|a#J%s{?<(b{*RK13iuK?Fed1QhQus_+ zr!So{k;<+P5U4R&$qHE8uDkJHTf6A)#INs+v9kk{00(%|@AtFCDRX{|m~>Zb`#vEi zamO!*dfa`*q8&TZX0pgj!pCt2$HWD$-G-RlZeby4{C6S?noZzm@9vL8@moJ8k@jy8 zH#>=RisO4qv<;ZXC??k%=Dg|2GaSS~pi#I7Etw~H4%Oq$L;JyE{lcX&7yB3ehWo9! zThRc8#}5oe;_&6%Pl@vsfy~~7EouClJq>3ZUXSl`fFQ;*h7aZ3S*I7@NIc8;MwRKc z(?FN%9*g7&dV7y0PtICie6~nRX4M|Xd&(uZud?U6f=<7 zbbh?U79&CkX~Ht#cU4d|#G zkqbuD52p7BMV{N!dF^3KkD7FLA+NN&o!t@-LxW7+ce)2H3`0M*ztK?g_wx}MXyJxN zx5#DcWKW5?5!~tOv=g=rPwSi{X7m?rwTo(fc9--Y9!v7jr7q&GQHF6QeB6yq?1lswI!P2 z6VZD<-dIum%nU1^@BG8=YV%(3`T+e&vhza!Wq#;NOR2l;hSnZ-15gfJPbd+nZYtT4SzKv8D7{QnSS|ct8iz zge78l@G(6J zStpVH^JKp%tV16;lk;43_kg6Z^z7M(^OadkllLYxdyAVSuBg%#w2wv}%`mz3B8{s~ zSZs6mYzr|L&1bsd3z?-89{z_o2_7=@xf^oO`mC6k>*S zAl2PVb3bM3mjCBcO>Twr`aZu9_VS#M>%r$Ex^3zEBM!WR67hSrY=kNmvVv-Qk1IR( z&KqzINS}zzSEwV(Eq9W3<>b)r1S`QGU(C76I8j))HpO#ui2NZMuH-Va|9Wg1q*A0p z_!4LYD=2&U-jMiK-xEszhSNyC-=B_ue&YFfRvTm&;k!onkE^XeY_o1epMQq8qGhqp z2k!`D>DFLO`~XH}3ZUviPB6r;3RvCD^C!Kf>~1bw=A z%M2b^0L==kAkw#Rp3CBv$q%Kze!ysf?$L!WdJe>uS+zn1mD~E2_Rcuk?Ku<3UKiJ< zWFbA29bd{F@6Uh8K;Ph>g{Nr~46J$!v`imBWM^nBL_=Ur?3L> zrf7*Zb&|!CjZ*84juiQ7S?>+Do>J%PJU~*4s!LM)H5lV@wYa;0C1| zS9t5xV=$!_-Tf>11wE?gTldJE0Ua`0YHa7LzuJR}^<#NqY3w7btUz=YFSJzZHgIY5Wbx2Cv9KKp+l;oO0Fp+?GR_U%U0~H{eRr4ueAlo3oEa$=v{=6h8 zrE_5TSp|cV5FCKw`t2Y6qIR7P&$-D5bICO>Dbtsft-HkFrfqBm7C$okODzayk(93= zvuR?Jbuys1g6E}33XLZBL;9@JJgx?pHBCB zXjPA3Z$jr3;rTD~W-@zrct7mDVkVkO39P>pq++K4kG-C zdlj=*X7!1!HZZ7S%EhvI6P@<-#xo!iZU)3NjGc@@Lp9#~$oef0v-Xho-vT5z>+C z%@Rmi;?c^IEZd{t$s_UYkVp$!)mU7Q`S9U<5#iOqe(RbK(6uo~05LApVoe@;5jF?F zZmkWiP}>NHm|XPZ33pJXg+zXTT|IR zI%k2-kpp%NU-;D(PS7dYqUvEJeZYbTYSOvR2hV?got|ReeEpNPs6ME?SjU&sex2^w zEd)cSM&+Yn6jNhA(w+Eor;HezB$=&k&*giiw z9lkV1M?u;_-CnTV(MC!T$g;4oMfOT(b%=5P0I$jsCN8iL3AzSXc%@UY8VK7T&sNhnCCAfRS*3m2W` zpJv{hf}MJ8-_-OhZk6%E;*Ut3z8XT)7yG+reths{7YZr3w2@L8aj~%F@g$QoK&@*3 zui_3wfT;&P=@RyH-XMKN%(DjSi{*FWi)>@6(LHj<>{u}!11tB=0A=~F2vH8-x_FZa$(nk+r+c$WmWW0{zAua9>7{(
    RM@yk|h?5U}-ilQT0v3^Vkk{&3uk4wTjnu;2$!;!{4r1{R0Ww9FFoK_ilKTTs389 zlaoMpEdvl=up9(0or4+l_$@VtX)Wy#Bit`+slE zNe|S2)ys}CwHps$yVTN;-BV_jLs(=7 zl78@bvzi<}J1S!bQb(PSC2_)Smf)}$J9s9ZSZUD_E!)S-isg*=+=<>TQUFdC-Ze>t< zym?+Ok*|#M1tVVWf1!E?VG%!o?YUDoE}hlw)pAU>mI3`x2P#Wm4?A}wD#gam^k?U& z{4{@_Qsr5ch_U!vnBLp9!Rb0?a_Npf7WT4uey;YDu7cx66HGRcw(Z>@F)=S;2tGLF?Wp6f3(-G^<+M+%S9YbH-W01gy*jVLjl()g# z{Qmo0T1@F9l7q3n%M=Ua@VEYLfZ3Y>ofeNT_|L;0kAA0Sxq9)I`A-b(lbUQ3=P#H8 zpYs>qnxo^$iRi;eR!?$g0xLjDC#|PdqSR^=&k^soBJd&utqFK|Ssa%#C@QJqv>bz@)PktNf4fJB)uFI8U{dDjIC(K7;3sCj z0(fCA*gAg3iOn9P1s3m4-d65_0oofo#*rgI)?q=& z|7Lm)M+||F1eB3@83QU44qM#fpU@}L9`{=!V+Q!?8jrA#7ev!9h{-TTPWat9+2dCxVJ6boGXIL z(NS-M!2pRDoDs=FPL}1OJ?Df_{yiZaWDyOXA1>QUv3xFM2mj_IXu{H`CA%Yh3 z=ajQ>3Z^-41o9d=25yK4or6mPtn`Z}JB7;8jKxvT03+R&ok0laM_M}gf2fK6qauvx zklHR50-We^P|dj$3WPlWQ1oxiY~&L43+%Th*fIoqVTKPa!gBk%%;@L0dT;X&B&&An z)na|Ny%GAWlo|&?t?t}OctD$EiUo}*3eS-7e87DztGY@LEd|~NEK+2 z6TJ`cISW8c(Kf@bT>9zmye2J~cHCbf!AB}ahkOy$>V!*jn<2#JiouR##gohMJ=SS& zTxAX^7{8akb8D}uLFuWpq)(Bn(!0L7n{CzH+JL^J)}xbZK^T15`jb!f!6S2rcf+To zp>MGtpD0{wNOoCS{d6hTv8yMz!TaXo)wN?YIH%E|2h)f{Po{4fiiX*YSP_=Sbb`4> zUSeDfjw{KU6Hgq@u%CIW_?g-Xxp0;CCxhvDmT~~y`*ABcC>Y1MDV9oG+?j_yFj-{D zl+PtjrNGHGE{reUv^Ot=A!DP(NDGapMUtY)I^Y@}l6psLg`;nGOno_6X3#VR`iCFR zHGLas@Se$h{E%WVowllfY_LS`)to_|kXgEpQxgd#q+@L%v`tdPLRTV`%R=%hmyKL@T2)kO`_!KPC!Fm86?Liz|FEWnny~&?>-$AY@ z*J)WRA}v78m0#GMQw8xQkltCO)!+QqGD1nx=3dtB3orB~-}JN+$1(iS-XYYl>6=&7 z;EJL0$=A%XuH1ld2g6@mX5+IOP~E_=$gmNJspe&ufVCAaNSbhSplCx1EG%u=%8OPY z0*f&y6N`}8(&lj>*u8(?dDg3w#7!f&e59y-AfTe=Gaf;Wu6S$Ibf|24J2u|#5v`0# z-iOw#KId`mRgedkP_i#r8+OV`GnZ;1HL~@&LhR=fZ%xKeGl>!L%LjiHm3AmBew_+o zYy7;1w|qn}b(T6=lt3!-N5MAxn zQ{_uGXDb#XO{F}zxa30Wiff6|FDm*SlH!fTN!mNV1lusf`-ba=*`w>0B;|(QT%R(d z`^|h`E*J{nuB zm1t4rOYj!=3#!>tMNQNffgAdNcb)C}f-rq4c}Sy5bevI4UaTnenD##qL3Rq_=cdJ- zBT;@)D}*^prR}vlHTK-a{0cS+M?}g6*ei2B$GdrXG#QHtczhy`{8?W$b!)#7M%qfdu#Q+62SDh=IW5hm~!%k9ibX&Nm$~V8{jF5VdLW`g_(h$ z`clftm#I@Y%0eIBMh@JEHqJ#V zD#d`X&x5uRxYp%TgEnCd9{YnHUb#@P<|W0z1B+zmZz1r^(Y26f!oBSF1f%;OZ|%7- z7$$}ZO6eaS77fpx=som9$}v^5|Bg$)>BaWx2=)EHsPbb_kHpDQZvh55B#sU*wL3z2Za27BOLQ7>%^I1v!zMAwtGr(n`F%G=1f*l zYTU-^Z`sTZM!FxUY3n%^X?XU8O+AjXsHx{;HW0B>;;Fj7w6{Q@gYH%;gJ-blPq@bx zsPp7+j0S{Cep^+zTeDW%N+>K!Bt-F0c+nP@{)~Qa*3rOtivfLPS!15e zTqbeywEWj5jLTP1!?+I8I^#F`k1DwJg4S60<3)Sh7ZkiA|Ic_X72@Vt`DgQG*BSCzx3U|PRD%}F3}XpdiZPZjV;N>T*R8(K^Zd^5{B{01 zuiyDA)wq{y?z!i_-q&Zrc)pfSwF{gUqnozn0;v~3Xm5SJ&?cFMA0{Y8Tbvg-$H~-H z-{gWUO2Kwxxx9i_M0u^P@lE-VN67Ou3P;j-x!}mEc3J&Er)z&e3F>bsy$Vjr^#)LxnUq_Y z1a{boap_L%1fUnO3A9xv0`EHc{v==3pd zdgcA?@lLOl0z41_zg2&PAqpN(o%Ie(nT~E{erLKg*A7JOmg7Xx`m$f=j#7j+-hD&K z(UiUd|9(gaLmpiV&8(>r3&K9r-W0OeZr4;1NZNh+LQ=Byguef+(V6MYscHlEbAMNXh-Ru6`hD% zV?Tc6tpfE2-@(1OypbTCRR@Fd&T*R<)7hIU=`|X*zzC* zMYm-1*u4wcTr;CG(PJW9!wFt0E~1HjkML^)cV`M<%H4QBV9{=H^h&u2mfXP-RJWcz zW3Sofkx}3hsOu(%6rb9r`+|dG4~@=x3Ek>$aMa4n!segReV=S!3H288p?dD6l~c z+Ev8f6iZYV?;QC`1{0Rdr z+ib!?&sjTa7S7sKn`-y;1+fi>aGo9={4x1M5LkU-E02_Y;bY zvymbxyWC6trg>J%*82NRNe@3tL|J=u*G8EN+DF-|RG;DHL@)mK)4?Y1yMwJRb@BTO zvSCB`K**BRt!n#|bza=I+Bq`83h0N;j@)R-;*-gb69L+Qyet0bIl*9Tn#QqHpS*6$ z2DoLeo|R#Qm{i@^^e80i@+*{r*%cQ4pm%VO%pu9R;4@r&zrV)*CW6)5^ikSPA)N?U zkTifpJD_rQN}5|KinOE3 zt!?hz)p9xdvA_mMo8yuyX5bg1q;8Em&VD2f`pw!>x=1_Ge`r-QKUv+H-<_W1eD8Y8 zJwm(c?*9GF>718Oc@2fn`B2K%GB3Wd`h>|wuJVAVq1mHL-W>mi-<|U*_iLxrj5n5< z2w4oY7?iw5pQ^!jk>~8fu9c?-4|;L_z}luOw7Md_v|;IuiMb0^eR~Rx7M^5MX7P?% zi2t7z3DaAEO2uhHWXSnIEq~G77GlV4SC>gT>rUAvd{*nV?a0XnUSY4pNajc?gG~EQ zYmvDv5{4kRuf1vwNf|RUzx=CP-zOIHbMl9-->SzjUP_>{!RS{J_;&0ck4J85x6~Y$ zqa&ATP+PAG3A=jx>!xo_v&HWV9GwIot6!Gz7Eo!x8-8t)N9AEYmVM=(VM{_~y%nqP z7B)RvX_)o-xs3aeU`%^)cu~&_=SzhivYiuyA8q$uJp8KU(CYm-yW>g6+yhoF3d*cB z!w=RmR;reS-M(&m#~?l}&bnZHa`tS|pvvgow8k!-e!+hC|5^CT?v7r#6PwfpTW z<3}|MNoS>g>830CmQMdZxv=$Z9X^$QY}*R$a~{}>$cyQT{-W+(pnuN z7tMcm+{nw#FUozMUygoUn;&%wX>NYxX`6B^J1g1K;Hulo5x-fvqeat&KQ7tpcOS~! zVWBIS&kxH_gYl>Bm~fAdPs5(rc@efDJTx2?rGr8G(F*=YQ^*Vv01zaURylrt7`(t<@!^+fSwLGivl~*L!j!n3IL855G5K|Ct-t`MgM~QKzm*w zB4izety_Wrs?0)tqbP;{{JShD#1E7SLjtP*l!Ab&5TGqvZv_dN92WnZzz1=ob-A49 zdSV>V9{m(?U_!vIACM~ke+s!9p{o!aIttZ&07Vv)aS&2zRS{W6|3%dxYc2xFc0%ay za#C&q3I#-V;Jn^}Ou(buY!VQe0o2HZ0s^7G1cClP0I?eFnmWTG=VqdC_MjRB{1%A7 z0c9SO!_pvjP!yPW!Lu_e6zt_3ZY;1590HvY%K3!|)$7gUY>@1Oy$0=#S;`TB_jVe_-;d==629Ucg+ z-hqU}V$ejQ4f6*&yT2}7Fx*h%FgP})4^&}rGNB?w?B6;RqXs-@JumPJs9grHDV_Ww z{#OxKMM8miM?q+S09}Ku&+CKrw{V83#%+PFsBTL$7$3y!Y5|u$A;JXX|32BDQ3q%k z6&j*&0GGli--$v*7YOvGc>iwcUzg2(kfA7Cx70wS=?&F(@UgmZL}`RqR57tTss#1- z5?n1peTe+4&7950BV19g!B%Xbz8tVF^jMcix{<;69V^XM;t(5_TJW*x!-l}?bEBIO9^ zWw{tH4)vr^hOnR(1^pYL7wC&nSeSKGwu}<(=GWtgm>o!mCQ85b_lCU53E+R10mSnF zS0C;fnOdQZ=M)L9dAL` zn`ZS7#Ie-2Ug;1zIAMW~N!bvVc)8yDc7Al|-OqQPIgNOS*XONLFt>dvUp39!oEpi} zLp4%nMsE|!Y`^2>d&@HHF86YFWoITRzw$cie}>iSsdo09fBTxDztyVd{k7`Q6zOEi z*j*PBlI!-GBjeJF9$m{S%1VYm_KJ39e%{(4R;ZB~$>NjNUi#>`;4)a_eY?8n4z}A~ zf}wZvE8j%NrR`Wy?R*N)XW_n0SDQbVZS(V<&enX(7kr}U;mH}F7J)CDODd0yH-06h zo1Y?k(TxS`?=SuI?VWI*986$BxrM6C5;lTL8~m5J`Y;{vEujW-6G@_D6fiHHyk z(x))E&Hj#NRPMWNcMC%m=v>xxAD4$>q0)^`*&5fly^C~Exq{VT`MUV$l7QPTNcPePQO)4_+>*PERI!SkLZuI|#~4?jz*l&m$*6 zApl#%HF&@1Mg9xrHSujmzfQSZN)9o=gL}pPa5J=fiN6#)_xC4J3ur~W?d>&Uh4eFQ zqc&~h6X(KS42|0`;rF z+_0p8V-fpyb>w?i9~Ul=eX&8co{e%iU#Oqp>6+$@Yol^Pv(9GKcr4IODh1Q+p*E93 zn6kDXi!{C#%9y;I6jr(4q7_@t_cZn_9|t3YzoA$A+*zYY=O?vY?tyy3iG$zgZen&V z;tQv<^^7|#ELZ}J1Zx4&EBsVEBG*1hm&!SHb?bGaUg9oA^_WXo;iqlXu;bHIS4Ngw z&dc+anfOxm$SzrL{@=jRD7jjj_r3z2r_x+v>uFr>7*}v>(r>w>_OfE1FueXw%U*i> zq3g*rJ4stHo7O@M>@)?jsT&HY))!3k4a6_p3*D&l%x5ojHL0tYJT}?vcHt1>_p6QdY&2s~!#lT9^+qe-DrNswFJ}6C@4S4R^?o66 z8|0pF9&tGAUdIPA_RP+>|VXbQC>BnpbC+srK zKow?APbPo_%Lf^jDq@udPK)4xmIHt`mEqnPb48%y6U=p+t|J=AyAJ$B1e zN^5psieh@Up#@ASAuI>bb)?7f)0cbcUTNC8lX}ameno5SA2$q0piXw+!QI*=2Z2rR zLivdi8rE9 zn(|H^?&^8L5UEY{u;@DV(*5SghH(7GhUd~BPn?fG_+ZDxV^2FP>VWpaUu)l2O$`H+ zl9QQqz4PvGOWuQSi8EkT%~PS8(o>JN79xh=kak);TBG4dKazO+1QWbFTY0c`tFGcx zeNS%kAEbc;8LT(GEQliR&>$ioK39F`xnmb;Q`5roBHrL-X+0ceatvwaWVE&HA8@?q4}mqVc-J_xl1zWO-Ge zyoWx_=oWB|b+#{)@9_k;yr{a&GDjtN2h5%I^n#Tf9i=&4G*gQw`aUs^v{C+8BeHwL z#VVNvzsR;Si^R~9`9HAZ7q;kr$8^y<%QH>mPL9dUEgDHFQ!@4VtxXP8`yXvw!w^G5 zbCFRwulS2^OP|BULUT)t83sxmof0LOc#V@QA+jh<8M0_v4CEB?r6|SDUCoAdt3-F{bU#AvZ^mHg%?(4&OJJFJ@D2k+I}dnAkWIab7Bfe~G)MfV z`|lcxSiDd)j&~0mHpMX7+A&dY+C#iMw2O-goe!?Ea&q`1$!{0L_&w>=(I&!!*hk`8 zFwp=G|6ASgy&!7)g{}Oha3O9aKCEG)C>dL*i~cMsm~LAQ-i=h$-Qdv~ z;ayR821=q^PBT@DfdeX+E@I@lT3kFeOS{(NH7?abwpqS2IQq~KwLhNQG=T4oN5x>@ zmOq3CqZEfl-10}+B5jqCi67xLCc(@h)%ZQZ&qN694Y-uLH#IV^6|v+P^FEa4)5C=N|a<`?d$ymA2Vmcyx;^UWB=J&YP<2^Gigx zivGKLp57vb$1Cng?NlSJ=`SWeI}$_47Bq+v?N$?&XGv`5QiGwj@YXNYj4!;`a?P6x z;`Em7`=SR^PSKr`l{_D(d-s6OTVzGNp#Z_)z>}SfLWgOj^_F{jg^E?1hL9n3F$PDsZyN)@WsE-npOzcPr~18~SHv)% z&nYF7Ul<$!R$)JX(A1P7&a_daJ^^vl{f=r*WyVW7VXA8wTVDY%( zsGWHhX$TDA~@NN`XC-?F3_*o2MoF|Q>cHt#nK z=O4u)9u}B)gcF=7A3=yD{T9c#3JB&W~NZhRrmr4vjqCW!iu>hIbsJ)Xn>qp#m^s_zo zY-gO$HnhJeRXn#?{Cfg|v}MdX$HO5oHGZ#9bOlsLSTfb3@8a|%X{Xu(eMrEn-Qwbp z_(`@%b_2d+=)HV&9^Eo4TT&+V{P&yLmj%Ze-a~7l_jwUY z;Ac%03EDH<%{F$YzbD0Q;bB$D%sPFUmY4TL$W?343748u9hRvQGTEFObxbt#i?6D% z6#UfTurvW~ zJU-8=Wel!rn~zWy-BD<N36%~6I}U;X{~0aCr|{I_YjvXO67wn=NB#n1tZ z)}6i})9b%Q{QsvV-=(|Xw3*VC?A=;<{>g4_$bY(`qAd31I zr<;Q6E(sM29J?0RA@@k!U=Leq-x2Z{553tXc|?21X2-UTCI*^Ub}D4lH8cd=wPwsJ z-w7M;SMzE{9q+mEt6;D~M2U0dv`_G4-e^Fx#+^9c#(i_M2SJXT`BLimw3v^2<{j@X z?aOuHMl~B!KjyH86KP+918U^}CnUORc1A*pabJgu z$_B5)83nh)CSRiDQLi!;p7bdn`2*8dHfi5lIIl2vxbSjV6p}W0WnOQ|C?vM}`m689 zu9fz+kC8pL(&i)94rH?rb=BwRSV~?jmI4WQrRTm-eFoWw__GWftq|=%Km3Dira?)}dI_PCYJ6I`o%_JSJ%O0O|Q# zqc7xuUwd`8Yfyr2CSx|;R*wpQVwx%WZ-k%mk4nA1BuPrfu3=NX@ z8tUGZuYGPg^I|Z>uif$?JEz(z*%I+9Za)1U zhGy4`_OoOByKc79gpjhG(!i{mc*pN*df$}GgQyW3n)9!*-I}igMZp&buG3{6a zYArgr=>{UMmMs|r7FHMvMUJiaRDdE|08diuQ0V_;+yQ<~q!iH+H~+w{0A1Gl>q0xD ziool`(iy#s7erQAji=_i$+H#|144beez$WOjv+vB1teibI{)P(r4_aR$43f0s{gBx z^zVx&rC&p4!oLL=5Jp?qKJ^onp`ZRL*=Qhyk0|tyNd5JZLe&e?fa3kkCQ(y?6SKCO zzcAgdDH6(gng9`LfP5W=#77kh+e^cmWU=H5F8N0B%<71m;3!p_9b_;piM4@a%f4NwD1j{GAY+YA6C|YCIh} znn9K^WF7_THyO~eVFZyiRSk}DNw-N3bb$CJovy&tb-5Kty;)xE;0LU)2?A>uK|K+Y zWWs_}UosN-z|1?33$3L+)4KVo@R-oIikJ>q;&yiBM3G3q|3rGspEo z*_3kC1Gz6vu%M>D6U`FLzo*$PP$z5JuzXTH3v1gAzaN$zcbz!sX zvM_L9Nc7*DU_i-2dr((|;A1=fIYO(~yO4nwcBpm$zW5vr6W9l&bGvF1hy_>0+&Xy$ zj^uR#TIo6?d#60S&SKXM%ABwWvM_ad{qKXtKg}zy->1+%#jA4OrE0Zx@4|$B%SOm1tn1X2cZ_Z!SpMiyA;0ohnn6x)LuL4-{+Q ztk-pDoAgE@X<+6CV|XSnz57(r-)lKvI@c2S!baYT3dJXCk_YLO%OFKQR<;7H+-nj@ zfgc_NLdOe1w+{O0^=4wL>K`1<^d+mwXL2~x0lQJ?dSd8M#1s{Hb2|$h&`97sq#{nV zb`7^@c850B!Qa2d2nRL)@H!w8-(OLp&}-rJ-heLsfns4}b7@am>Ad{o4XdA=>#YaO z`;qld?bb=IY^h&6DBiVNPgtU6*=|WePYOaW=Iq_9v}KR`gC5d_kcQ9RwFeG39@`|j z6<0;Qi~DI@h`F+8)jf6Bc}|FE>y;#@lhD*P@#OH6AZB0A>+Sicf(=HGN`$Ix+FGzM zJxdq>cci-6lVLx{Um5m&`Et~6cl7_tIB7%v|pWZ6;5X2Zsoji7SH>5@o8pDW!cX(^4b`%L7tv|zlPBZwEWw3=E+Ir9qi zz0Z?%VX0q9BcXZxz)$RTOEuC}2sT_%zPCNCc%oP@d_8mVG4s9t%`%=gP~1fc>l zm-?Fe%gp5G>__J5RfVy`xcew|vyb8z%k194v?QN$kZ*robG^h&yO0J;IdYQvWUJuE zi`_gIZW<&q&!LdS`CG6<~AR8 zs@Ru_qKl-v*}njD?)jMK>TrsrX)vo%W#iR28wE|O#I2c6_rn`PEi8`O=OrbZA2x^! z+kC)HrdmS`Btxz8Q9Q%a*P85Lu3s8oIE2^0ta z{gbhtovuJZf==EW3`hdaJU5tD*+T|EMOf^|NbM+K2#{kS)T&6ounqprGG4S;! zZ-jWXHGl8}j{FdI87pG>-@Gb`%tmoIjigm*mG(LaU*PYr%vc4IA7D41x3dfj_QuitIO zYgL9JuVTDH^otZJvS}2YZ4(b;19{B+7IsbKxDY;7S-8jwI#E{&uG40kte zrxYv2QLQcrvMno4sB`$4i`aRW9h;&MN|iW^WE@X>rucnblOr%0q|3nrNl!aoIB;ks zs2C2otGfK(6lg_Eh50Z%%c;WYUP_nscyn{Eaniku{L6GckaoVh$7kDe(7URUwhLAB zmQ38SQgfjl@85rX&;}In(=En%Vc*`~i^rC#y}_j~j;tZhgdM9y@wmJLB&9M5pS?kXI`$b+jy}1Z0 zU7&Ld3qi6VZ#+xW{^_#D=k$%g$imNScuseE$iLy*JZ)LLVU@G+>5IDY9-W z*(IzxOd1ji;YCVIh2U(m9Jg>aorBDCSyqfaHDjw~49AOw;ca}6LLBuMr^JG9ZkjAk zG!rqf8Tex8j99lJNpa$qd zbR3wy@g-R78F_ZmyIqU<-2(&{V<`o^NA&h~l(X{zi?L zw6y>(Z$GSkLK0~lZ(7hC*dssRT3ksjR%J`@`XUMrrwiiw0^h-tGo$IhzBx(-6G=2s z3jJ2aBpYd%>m>sEyG*@P+t#f6(7avCC~@2EcK05TMl{L&xkXv+l%kV6n;9f^9kckG z+7%>842~G=dtJ|o3KtQjEU)gWKJb-9m{>fxpA^)N#=OWlVKGEy=Ejq5Jv;+_PPq8i z9YJG(uH?Gh)73&Dbl$n?3*L_dDKZ-MvALnafK7fRt~?O2-;`O{L(}|VX)r?O_;rSM z()B3YyQbS1ft6=VfhQ|YFwh_V14Qf23?zf3e@stE&~^iDdJX?IeTqcEc25kz56I>k?$y2tGS zmLOgC8#7q5nBMy?<2OCqQVmpqHqYsATiDBX-~g?u@nmsrlyr)jHsOWsFV2uIiLhqf z@7X)h^(~+B58Z)rTfQ4rS#rcOthZtwn*H!ko6Gk+1FVRnd?eaxsE{^%ul*A(++v} zb9`ar{U=+!jZ?3GJWL5W7|AZdusC@_1v#ENwa76)_e@wy*L-HTfXTz>yV2ux*(={lv{+P0EAI5Gxn zdNQxJ`1m8!7;Y&$d0s^OO^-_Sn1sJZDy=6k*e&C1nyZNIjwcelekHZyEZ5dcypsH1r6U^cj6PkYYk91`E6FrEv!IED9zJ(rb$2wAxR8 z80*zxuJr67B(f-_=M1;2_+VJNjK3UhpEyO`|S>x+ehFBh7Aaov$6eV)pU)4#C&~p+Odtw! z(6-5EP1Kk&jWXEKM=psTT8xeh9m+;J?^vQ+Cd)M9Fq%le6FY!RP|)aBQ(j?s_VU4@ z)Em4P>76`M3JmHW*mZvm{FkEUc{<d0C6DVCb%q11mctb$rM#bi5)cRQlcs z;nvJnW5L~~A4l)LF55I_v#~}YqOI(j(!7lNt*^9>n^tWhbzkkSzp23gj97^_rB529 z@hV6iFYT)`>O^k2QTcqBC>Q(s5A2inMCxqGFP%9(k2@LJgT06a=S^u;2?;;D?cOgfTb)Ea36l<>#AoO#Vj!aH1WP4h(LL2NueRqX$cYm!a6)hs=QJ!g1 z)Voo(>e zjP`RJs687RloMcE^QPBf+VD+S#v6|ViBYS(vq$f^CEPik;G+@wH0agQ96_Gp-hS;H z&m@&fGk909SzDyu`1H&DuIvwiwsAf3_5T624$I}@{akZe# z0B|3~KZ*n@Kmq4zTi05FFsc6`wmQDZKftb7?@*;@u|Vk9k}vq*Fjg1)=lZ67El|aO z0TNV~`cGt430#Vf%TU2ULlv-pdCNfJ9FThks1ATC0AWZ_itUiVKZygh1kx*=gI)n> z3)`Mj0>IQ?71m#U6OixNMHK^L0@B1Fmmx?v1K(Zim}0UI>F`z)1co^}0V!96Q54X+ zAZGJ-0xukxUP6gix#((;>(2b=DTD&o)=hR*b=C!tV-EZU!bcT)*5J@c5>O5q#}v2_ zLHj^ORCYt;s=|P0H&YV=S(Z zzP$c|2g;13i={sRpdvw=CgOZJdX3-T^5{qrt@Y_w_O3{iC_5$bvcH5R^aU^i6P zL_!#WKqDmo8$w5rI%*oyq^;wk6Xwuv$lx6S!D}@(fB6f^32ZosXI-s^^3QnAb z^={o0;Hdt(K6!zn?5|a^7-W$-u8$~`Kn7HMlK-1+5goPuRA0-#!5U{Dr{ofkJIS#32f_Sy)NJmx!zx0FM0DGkWU& zT~_~t7=ho0E~?eEq?hV0UTxpDoXgRWx6qfLJYYv?bCN?*zln0$-y z_c#lTzA)@7l>86WCo=eXG8w=>Vk#@~D~$t)k_hpCX>15(L5@iwbj-w(G~|)3^`O$CY#ePw!CQ~3jsI(= zjJNx%;i~mWB*L+Ox4AS*F$Q^PF8;o%puHEO1Q&PGqksr3$My8fqKao(Uw(K`&fS5Z zIgYe8{H3;QP2D$Va;}=$B5^M!t6+nGbd%(8%j=@HwYpoacj+#|KdT&zUtW2MQe=9l zy2pzI-po7_Un(3^$g{b)$gL*25$drn9 zef8pj^PA^7T%^e#*nEkc=hZ(jW%f%K$;+#sLqFU}?TZiiCQUn1*LJL!kRa~eP-?7T zms`|TF2W3^eT+S=?jbrOF8j;rQtjKLA(h?w%ZVeO7ctwoZY#{QWQo1XC-z5rUeTuJ zEbfmOvmesf`!E?R1rt>Y#6OF>cttDv{BtuuCaJt;k3Q<`#rWcgEVn`txebl4Oi8pg z&7Rc&ivTI*FWPMmM`m_fNIY#}2VjEUwM^EiN_pg?vIw13V%0DnR?XUKmeSSdgm6YD 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

    Lp@dPtj`7OLK`M>t`A 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∋6;SK5I8#oBU2H~12sbKI3 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ƏyW^pDw9)sm$fP=JC&Gd2EPFlqE{XM4m+^_9I$2F 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:+S<2F`6yx0p;odJAM7^eAJam?4*Gps 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

    c-rRlb1uw(k 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≫⃒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%0AAiYOba+LJb=4?X0HQ})DJv)ynP*12Mn5` zwqNRGniEh}2v{A+1?+%C1gJi(+00j_wM(sUt5+G0^*{!6UfxG`;6vz8^&IObFeNP}7 zJa>hmSURMvey(ir^t}G6NIO1pt-`jsp{D94q42y#`zM_Fys(9MXVR^BYO`F!Se{NU znD*I{_VZ~c?_5}$qPd^Ey{M}J+Zx*|JM#G4Xa%1c3)=r{->_bm6Q>Vk>|F6HEX!$G z`+L>i!0@3ok;npW_H-3y_vegHLQ%a!$45E%0UyDZ)XH8B$}~DV#2Q3)b$HY7YR}aW{_T4vyv6O!F!HLJ6r9jxDH-B;F-m#ruxq$B-jv&(CCGcjRus zBai#NU)K_2lgRXe$(@f8A6A??wG9;wcPjeI`^(8MSg>+p8u3p;E?tQV7o`8Ny|AZj zb`nwl9*)YB(I#f?DqC)Mn!!M0eVNs$brGI#gT=EYRC!$NZ0fg$S6vQk?(1?&%+pj= zIvXuD6Bbu;2NO@9fLXwohh{hCTHcf397@7*j+^@7-%w7=NzAj;C?PPH;UC335 zx$MXCZNonz9|5eTfI-0&QU68OA6X&Ab7s;7Oa7FQQ+z9^&63XBlfVPI2e?Rtj&AMU zgcy|L@`t$*4IxG$xv0KqM#HjG?&a+l3cK!BI9*Jf8Jz94K9o^;%CTn>@MGB%hsfaY zALIVw-h4Wr{B!MacVPTQY{Twp&BLhx*j`+DpPkL-i9xo0lIGlSIrJKQr>sANBz)BC z-mYpDAub|9iKxJ_w1J~8!p^aGp45h28yX#%?a>=7|aydvkZOlTc=klPNk}fhi^z9d~GWT9p_XpNDB^82F zTcN@lT?UVbtF41hjo5#@#>XA^p5oZ|h-VaAycr%WK4iSl#o>wu?)LVEd{?FO;t?v# zcG>S=m6e@8p8H1iE1SLSt3{EXwWRh@4jzT4E{V;fYz=jr0j@S_<8gs*1VVHNMP?*y zK&44C^i==V^oE{yX&J9Mvkca=vqGunMcpl(yljO^41U<}i4o{&1t6JTn71OA2-B3%U~TA9>KRw^k$K_;m| zTqe^&(mw^ln}Q$aCR0#cq#PAyxv7=klwQo0#5Gu$YSDOs+ z51^ZXfDUakUA||z@x*Wuj;!?wi8P<~5@Fn097nI+gRMr!4M=5_a0X%|K}yJ>{E)kC z)dzWB=e%J~gik^8D&`DO<+;E}But>UQUAw;ithiPgbFqJtg>ArQb)H_NNkmx zY}T_Gs1iHJ31m*Qar)sLZpz0IUw$tsH+P zyQKwU?C0wI{!7?x5%FePIgPfgUPA`tBd=9!!(5XBMEWS?Dt4!LS^l9*4aNs22xYL_ zNyRO32oiSrjIM6I8SS3vxAdW)|7ZcP9{++De%&wYi*kT<^wh7My>QW`w4q1nWTv$y zhi7=ckAA<_?PIwD))Du~y{JdGR&A=?xRywguVY{-hIn2*oAy?yck3fmY0GTz*@?G2Mge&|!qh9?o{W2{j=bc;uTK-VK;I&q1 zKG!)I-7d-tZzXSIqWVw-0s*$5-STEpou)B~esnq{GTk;Xa;+g;y>j(+9|QstgjUhm z96@@n=a6xL@9P&F8*qOWOQ{2Rxr%FJ<~jB%Fpz3`bQZ9<__(O@3>GT-+ahF8ujlv! znm>6MzS4NJnpn1*j?g1(3&lhE0W`c~$w99&WeM8(Cv777Zxo7viJA%hi0BGBAc_a# zS8ZU+p!OG|0{mx8`#1doa5ex(0~o|!1Rf;dGXrN4ttt>sDkf5QhM9 zgK)SoU$7{zelFtn=b6_;5(*BCVD*fS-rJ$_@93fEjH^+2*6V-f3*|hfbUlgo6Sgk(w`}i0*ev}La4i?s%jDx!d za-SNCU~O*L8sOM!2bo-h*X&xnEjju7P$3At{~Oio!8XVGZ@ARt@rR#h6D;pfv0v2^9`vwK`O%wLn#8B>s{a#X{;Np#_ ze$1RVDg`?5+DCYsbnqmH6@D$g!$d*GHA_n|9D!f6_;&=4f1giK0UEOJZh_JsRXcsO zJAV&0r6$2&=sj8$U&moF!W#yAkOi#HS*IyMx~ItlVW&JNOyzCB@y*LB%5 zK^;cYHLQ`eWx?*o2k+&y2P^4T1MLN8L|Z2jd;otApyF6ltdU=oCQNtBgU{w-n;=YT zhtD%Vv}14t&l~ARN%oBbE5n_by-{tGYdxu)4zsTcM#xw8(PqY-*dp4ZH1c`g*O4rw zN-u<%E;1`C)|J$@Y!)v=xKLmi)-Vlsd-Qm5!2S`>9af3(!F*TE$LY1Xi;?=K(y+8H zume4F@~eb)J>-K|x^7t}%j`XqlRr+Ym>G?tRX=a?-+wqjdAW)ElY(DX{r!x7o2_-c zRqpCPVL;^mR}6>(Z4#F!m2wQ(1|0`Auwht1`lC}mVNbQ)VJ=Opth|VG)t$M|tuS%* z7Q5vAKBhiny$XG#xxC9U(oiMIJc0Q57sYkfr#)C|eQyYn>N91tMumg*h=oyIUJM0NJWf#$`AR6Pv*2i{5;OKA+aOw3E8pL>LCtwK<;w6~sy}pp7CnD4ppJJ2Q6h-n<2{t#9Pp(49Sw zw}?Go7wF+OOE6A-gSKk0&u=F7FtW-QF?DeTayXfX{_`Rw=^f{(-i+Ai2nNpRrLy*vL zrz*%=7tD|;4(Q~0<&O7q5WXbfXc-k;Lv2q+EW-+Rx7dl1s-SH$$7D|`%fz3Sfjjr4 z4~adI6kKx~Qb*K?u+a}%eh5q%zX-FLZ2LnIhsVL&Mn;B+{_E+sQEez@9;M2``Hrr!=KAzp7;SkyPUv)kva1jSHv3KIG= z**Wj7hYEdO{Bm>da?*#7Ny@o5RfV$KxIAq88iOymY@n*rR5q9o{R)^clZMh48-U5g zC!RamBOjfMf)DkRR6k_i2{-c@uHLE6zb7(syi&Y(;n>Ufl_;Z3eY$TwEJZ62k;(^P zB-SHvIhERE9?LoKNccmZwr^}_;tsA730W8tpQBsl0@(#@;4@7HMk3D`_u?K0F;@hd z#XXZhU9nI~|Fz^Ml3|cKXNtRmF=F{bL@o&=wn- zqHi|Vvf*xa2oLB>s+^6XS;E>51)|Rb9r+klmpi0%g)0Rh742sM)GrfB_|8k}|RUqir z#Z$qW%6hrWT9@tTWVBuB@ApZw=bIC+fzY)L3+pNm-UejS z%|(4CbJd8ZnH+xn#xOJWdqa%n!2NM^5}cN;b?X;^Fmx*<~J^$u!_Cv?8;gLYoJcUmAx6j4N;$h zKzo|CWxkg;2*$3+FMiC+OYLfFe3BUvBxOqt`+nQv%1ui;KR|viTA>;y`-Y=h=E)a0 zRY?^JLb@b}%sn>_m-dT?<1AZO>v}Pr7L{5cN=E+zk46y+rJ)%9=sJOAuv^U6mcW_$*YTK&$K=$L#2lI%?vJ~8+ zxym+T%%XZHMC-seaRAD--%z@!Zc)Vw7mOdwZI=qx&_gK{=8@^wYE*;g2b!}Bw$n&X zW73~IUw7UR+55iAJW*}f1Gz6OF8jteJN@)2X9Q>OK)@7-EfEgnE&tIPdKWda7MPAoV`3C+Rr+fe&+uOGzzdkm=Nkp)h8`X}qoPLtrnneEn;ET>I8Yj62s?$& zEdm^|9w~R>VK;- zq##(LJE3UD7PQ8sROt4MMNZ@@FnQaL9S=#o{)>W-^K0d8wY$BNGfN>2VQM!|7GLTR z)0o_5Q#dank|+6d4{2GuM}_P62AI}e3}6{NMocl|*A7>fjI}4L00BXQ6wYwK`=XJJw1TC_@xhEMtm)v27vn^ zOg2ft&D&yqQbyTW-p4-M?QBvSyCuUGc}Hu@Mpml8Q^>t+b*$t~5a-Ly?ekswGbIL< z!qSXU#d!vO_4#eu>0QL_)TwKD!zr1b1EK{&Tx6YWIEIfIH94!Pg~!v3=_|cj(+cY_ z=zlcb+51S4UApvR4v(Iz7xIE-ri@I^Ls)sFzQMhX<^u;d%Fyse!Fv;;VuL*glgRc? zB!@iQuHsv zjVQgZml=@81q+9X-X9!;V}6_dUPaV@kdk%6%pTiJz4Ro{zsSvSJ7y>&KKijhu=#|S zO%*qrxysjkeVtyz+l`DL%d(6AD6MAN@yir}lt5zl;9yk$q7Z^68lYMeW_>4!iu!%@ zyH9a0c7TzF94@LuT9g}lVHrr5w{)HF1avIgU3ocuJ)UyL^wdBMrb4S`P+R3%WP_7I zk@40h2bs}cb(1Ptwln292gMAok8P|MozQ1ky;o=W>C$6F+8bG7?BcLS(NT#T zM&|7aB9UUV zf^u~Fliy}!%^5#*lE161j$~(Mo8Ny&+zv6?!Ov2`JD$9EG+MC|QO6 zkW~ImaIi6t4f(_NdHJQ>QzK>kaX<8?7gFp~Lvl+mQ%7fJhGgYfD~WPui*mkWsy!#- z6X$+mdT=B+CMMoLJ}D?DiCRWR`f5gcdWOFY+`-J@#djV3-f!nlg{M+v2T_1Ol*6`n zJL-%lIn#GSn04AZ|A}TcP?{QGPQ-u$V?pW+xr+3_p|g~Tso=~~BZon*4z?u_Bc1)n zQEjsGmW!K)&9t@vJ^Znsd(5(g`-yZoj`-r)cJygV8Nq*3Tk?nn-A|j5x%(oi(rF2? zXZ()CfM9C|^MDXx%BD!XGiJERsWhe*SJ~H;incTIFye$Jm zS6rAIDA1c|JxnSpnjNU%Xv>-l;n+G&j2@W~v9BrBN=T@%mmv%JH~4IOF}n6A&=rcw zKZ|yCc6&X1&@maG--$iXh5EDDPwV2#wf)5$~&O|Mi>U*g4-a3gd-6kjTkTC72(dEtj(px zbwc_)iO)+87fi%@cNN$%f7G*;2|gYc@24leQiQBkcZut6$qbj(XGUIv-g#b=G%{@c zIi2&+(nk`2N4)?%TEFoS5^3A;IoEYv$7uG-+F63`TfI2Jv^H<#7~#dIcLsgw`0xdq zD<|)Zyw71c!Jnf0z{ZM*@XKPF#6u_cOm>dt)ZYB*yD0uNFm4FF`|82#sOVg$3e?Cj zQ`$Mls~VI-h0xpmbCmk_r5O8f0mJ=IHW!8w^>Ucyk97|bQ!j=w2Wzoo&g82*u=2@) zNz1<(Iux)#CZE)Xr?(xt+S(B(?7+uA&vR8H~H$LmtxdR4$fTtgsmUE zseGBiY9{Pl&ehY8+v&UWF!c%(o3I7a{%5*9edl9kkRw#4RPcVkqJvA}`_3;@`j@c6 z+Rq+K7U#Ru*4=K8xUhf9*_tM+H^;1!+~@0KN@lMR0p(^f8193W6TrP641rNM7=g21#sy|WD7Ib>kQe1TU{?0ZuDKEIgi~u^VFH@Q?k)!fElHhRo@rY zJl)=uFdTA#1GOjPN@gzyf}gkJ51#=1>K5ev<|psV)It~7wvv8OhpTOLV>LG#JoT(f z&(Nq6R2jXuZ8*=Dr7cELoU1ALO#V)WPA-=3)$G6a@IO`sHQnJEP?P*oH#<~YMe%Vv z>T7>{+*bpum=IgK%ZmJwx1Zr1Cv^4?gfCs$-i0y)>FAC=h843R2csjCSUt;Z_Oyq4 zDUndS32QdUzb=li)BQ!!$pnD%EijH4G>yqypscoe2Ig|~jR_{GD%~t4a6_uzqx(e> zRM7`HX#Tcbca*oX*#A?eOPhRQ0)TjkH3aGUJ|}3)(DIJpkF4{0wKrfj5E2jIcZ_~p z2lavo$1jREW!?wMu7@Qg%vTv#1@;Qi6@BOG?B9mCp^%O1ZZ_igKz^r1XGA2y0`2|H z#YS+ro5sdUDRDu~>fC3YJ1*egzpA-yW9R_UK%oqL<*#9)T}XTpNa7QcUg}<}=6aLD zbiBydar1+#82y>c_?Q+WXKZE&e+G`%YQ9`TSf1;`)T1y3rQ4tk^%2IrAIZ}O)7=;5 zH;EUE=J`qUe87gzhYI_VV_GPY651ubr1f?q~ic(gS5Emn4XTii_+G58)XnX%R5(c2hVwo%ExDcfLew6bjRG&KLMkbWO$1e*%wl0w~1<_EegkfPq>Mm~@1 z$8b!pihep&-=r*%)KqRsjIX^(<3Hk)Q6YBAV))gFxvj(}+*rfgZ#vGWG7s$S$`t8O z`d;eh;$5M{tKgbS7b-5~U^TN)=C5{`Hn;aKkC2s@5&j$(t3n>cLq;=QQudqjZe2uz zvWTY>ah9=o$;^%uaRFZ_ZZfhFqR?}i^%?ID0Ztq2+ecPKwCp|v)}6ammfkuzHlLA1 z@(SOl{<^(j}Dgs!9D` zik)>^TQ{CpT^*Ka8@kcbukK~noE7XQLEYphemUZ<`1jCleZ4W7jacjL3|3Q$l2!RF zIcC9KO=}rHH7?DYx)1rGAp7F6VbYxG%Yl9BrjPCIUkEjB_cB=`B-$4%&Qk*i6W_IDIG7X;5=hCcKy zt&U@dp5Q%0-_ZVN_4}lE679Awt*)3m~YIpYsLiAp#+U=u+gg+hJ z{+&L&*k{>w5g5m^qo40Ohd;yqiGut@yC=1R&%AD&aeMh8 zYEeD(`;=WSa1Ys!gDA?*QERW0hCpX1O8txWk+ z{-U_$4k0KofS-$A>WYLj^}}>fveZJ12}&R$c>BibFQ7l^a0sZe~<^`k$L_b7lrf!oKXLKQ~;I9&);CGSB^a; zz%z+t3^+2V7ZDeHEC+Ff&l2GMj-eUKDkFmfzb~@4jyK5Cx5{vG#6v;M0e-ONnVE8* zygGRc{DLB#&~&T{?9Zr#)r!8EbRWe&%o+sc)dSyU&*0`fssB4gVF~5{li&}uK1yu> z=;;?K{qsl2CK*u#pxlDK>_x5LAqu;>euFhhAQm&x%I}a4O)Kw}hA@FoL2>WJSn|E_M$F0O4uzd=&Q(h*a8zh3n?NT zVa4D6%D4n%iJasA8FZR{iUxah^*{3)WUO+U3$mCv<{{X94jAI?c3)Gt*n)amz&$k) zs%+FQ%D(g7bLI+o5+~Pd*XFAE@z+HLc)nL}jzs?8&cMQcYtK2R*UaF%rrQ89UHdCN zVYLQes8n2DgO>OtKQjAn-k%4yK_v|bfePRa|6bra!Tbf_bFgN40`!by7YY9Lhlfs(U7SXXun*aMYsTZ^W5YQ8-28M9D7cFNpd_~6rn4KjAbjnbGh)x01<=kO0*)NE2r zl(`>=3H`N~X4=$0MpCUm7ymH|D3LqOcWL2QKI24^^Q0+^KEdJ2#>ZlI9$td(bGR>3 z^6M)CxcNV1A^(qaFbiY>>hc(|qXD4<<@}oH;cmf7)#LzHNsvrm4Im82Jd%9L=M2!Z z&@SwzPY)uMILVC7l{k7*%YKz~_&|l^@}AcKVNG9-OBX@kQ?BwHX&r3@;Vy?dtn((9O%9jwl( z_fwdvWI}HJjpYw1{%Hacv|-Aq0CP5DWfEr^xrKMm1?ZG(z_x5IYfK+$DQ^kP#mvcL z!gZJp@$D?~c7#_M;Q1CfA|^RagEVZnZmuv3go`CSBZ)1ONZ2W*<0%G^?IqDb@CaS!2d9*+2= zeHb&;{WyK))rPK2oWgtB(o=f!f1;Yf|CgxdF%mFkDD_zDB;6g$0vlBc&#F$^ib3q) zBnRXs`5GO56OoMB#Xt7Ra(TNwgJ3>PD=LxdMcPTby9_qpBz{KVI_f;Z-nnyUkWA1& zcz~ifkl{}_Fgk$mJ0XN22cEoN=}3AmL70Q7Vufx@lW%W#6k@mtcwi2;x)6h$aw`ocjVo1yB)N=V@gEQNvo$1FW*fuEtLc1nEdcic^RxLnE! z+mH4RNXeM!Lc)Sp*tj9$EF2|t-M(AnAg~rG4vt^X;NWr|pHuUYP_p@=wK_9{(>QoKVNAg;Lf@IQRXSdVn?)rmI z5e>)|1TBzM$lVlYI5j@tMB|c$_Kyk*BBWL>*?pxg@SLI@`G3^CXH=6>yC#gHVxd^T z0s<;cx`2Sxh)6G?R{<5IS7}O%qJV<*4nm}NLJtH10qIghhk*3n2_z)MZ{vI3IrGjr z>svE(W`4|C{(_J^KG}Oe_kCXtS6L-aZh`iBkiNDG2}`^sdd~a>Qg5)xvbETDqgh9k zT9!gDO1Z2sku`r8C8mAH+hsE}zi!gY{dBAtGJz72)8yQc$SnhWVHZG}&E_~km-CcXg)kms0Zhw2$JaC*f*21WA79SDk$yH{oOqFTLfavH z@p$)$!YCS=(2iwVNYBj+`N{QSl98%%SD05-freHXs;OEmoqdlcm)WW1IAMjc?V#=0 z)WiWn%>F|bi`@Oa<+RYX!%^jZZPpX&agI3UYp7;Ydl+bb#Y8){$B|1CCxLx4 z?-IY~9=(=M?Qseoo=l{UY?q4}f6GV+ZPwJbIIHU}iIyLV=oh}INO#Po!Q|WDrQeWq znGK>IgLkv77_*^U4YD;LHC!ZXr+ASVX5J}deDW&>IW%v{WUzI1@9JwWzpSK-b3pok{8jlqP8MJB@xk7-*{F z%j*f=S>7Qt0PwYZ%@80h#y5nKl8J7wsEjorRZhja4;nf|V7FWks(oS~YR#F)CPvXO z=6os=W)*0i>^wy&dE__Lp%v6sRCQcBQ2%$p5I0S{ukR=_eu8H5uQcfe+ZW5`iZZfd zBX727ZBqM>*NC@e`f`=Y(mji%ZC~@g87#n8v|#~Y><~Uk6@V|qF^8mUZE%NXBHZsz zx3Dgonkip&%{HCpK!sfH$c5b-9w2qncJ@p3?S_{XWf2FK`i8t#XL8~RvI7%7O^~6b zp%eeUABW_F2R9m}3T@5bluQUUc%Ih$^e&EKvZgLCEGlcUa_rU3SUIgWrO;30nr!Wl zt_^tCbAwr3bcPzZF#r)Qv&OrErQK@<+d5s3gH{3Fzl1t!ijV{Z<<6Gf@HWxY(uq)d^Q>+6wLCQ z=vO}NzoI~ty)|w;azR^8?vX~JxqoVujYhd(;(HN&naypVf5$i9Hf%@R6D&a7D~H{S z?EK6qhsxbQWF;${%d^%2CL-KygSE`OP^o8J?kjQmM*XyfWDb=1&@W>(B%sGBf|Wy@ z@TkXNnN%N=qkY(Mn92ZEo9k8!!tB4jgf0vA5bW|i`NYLzl16kty-K_#OC>MI%6KPS zX6M>SG3nF+))c-Sfgs$6CctrlD8e5yZ?AAq_za`ye^DuHreJ0xF0f`~wxmM*cr>vX zM&s=hhwJ{-hTZDwr1Z6fi3YT_#z;ua^Ta$jZc&Fg_dU+Ke<->9r9v!MSMJ$Q*(hpO zT2E&Z%>QQjHpqf=%qjuP*j-E|K(I`ZV~T~ zIH*-O#L#qdt_)`@hn7dKP<1g%Jv7ypd|0{kbm6rp-CaOt*7Mi zPBhQu7HvV3!qcTk6XTzibaGc1Q3Xo!y~cB3>dTH;kO@gE>X@&;=Eh4c!KkEdW@fA# zSQMBP794gxH$Oi&akVMaCB3}%+VfK!<4#whrtxnCVCR=pL9=24YjQ3-E*i#>qJw^? z8dqCQGnk+nn9D^yMA>S&L^q@@=~MDWHmG>rqLd6O^Dh0Mqscw}h63|BDG{N2dMZPW zd#K6>471Ak@t`gWZk%o)tiGOFZn#VU2)yW#_DE+N-Ugr%t@UJ}Y+CmLiiPR5_XnjX zImp2PWJf}QAtMU{p+ni^PgPB-P3Sb?ERk=;>mAC=or*q)C2iXufSbXs(H$LTUI z*BTFY8bqme;u^{sDfrbK;b2RWtu1R4qi(~R^@!Jv;rPgEbqMpebRj`T^dOUXq$P9Y z>?eyzRM=yhxMttGcx4Z6r&@XEg|sOV1VKiX@t>8`lahcv80|d#;(S(4EZCjJzxe#` zaLX%6tvU1Jypm8e#fEU^4m4h8%kSNC_lo{@PWs-EcS8=U%XP?#t#O_$UPu!@rUU$3 z1{7`Ov-50JTMGG%4h~EQI&$AZ)!%XUDPX3rHq3}I(;uc|+hFd!jj7+Ji-NvQvRH2& zH_9M|{*W~aMyXIsa1urDnnt~0w`RXmV=NMgL}Nav%gI4a)3FW^>Z;xrwW6IZ^8q4f z`dTL>6n{&U+Uhw{SEtCa8DYE8q9b};;jH29sKNq1B`#udm`*#>)Y$8mS{(L;vU!HY zX5Bwnv;W)f>BF(i+vzD)6IK9%Y|Xhc44%3QIihTgau)0YdbL4wn}eNt9r8!I7XDl{ zTsD!z2LiM&O^nC8Tn!YCz8^W%^C43~ZM?L3Zqlryc4iQ*tEDsiazz5+G^C*1e?9#f zb9)g+=1W#Vu%N1|Z?INp(kRS6rtz~=`* z(00mUhtvG16Zz_z&3`XneE`nu4rktT3nVk+uj)OClFS{2m$ZUkUr#L2C0x4`omBKx z;H!n8Af-T9_gU$nmAR0l3aPhp&9~UNYp3uqNE)Ac`uIFGElh-Upq^D{Ks+MKgKHN z|GMKJRh*u!U~GM5?d28YaRyhVpd}LZSKy1r4x15`cwYkPQJA&o)m2hZsJ4-qa~e@H z=$9`mQfM<7F$>G`H&ndzaAhj!EUnIl==`prjeNPdzZAny?w6$NV_4`8aC73tS^BB!=b~we%Z8 z;u_Havv&@P6Xt{yGDrX2nhXS|4Lhy_vl1|)Z(a^R-hTwQD{3fXhO0qZhL^z)lmCzr zTq&B(h}AIC#qPb0lZNKx5M22Qbm&4Py1FX%Wq6iuiN+H+lc8Oqx#^#LF%#b54<@|Hlh?fx4(cWNlZ`k9)k4|^=hq@%eU+h&rZtYp zhoUD`ST_P#v1PO_%fLC0ZzG4vj^$ad8I1Yuh-P2RE`2cZY>?fu`s#UFuS+oONN6`57| zw2t`$_3hRfJ%wKuB2~ZBer9U7sc_G)?g(l3@wjW1@z}qzI4$pf@huNoLj#!7BI4v% zNP4hdp-h5I?Qq6id{^wIkH|~=*@Iq#O|RmC_0q3d{?@ErT29hAU5l?{g(`Hmt^(;s zppHO#ykWW_CDFjZCO1cQQEyNw&_?$foWIY&@yQw3i^&h25Ds1E;-{iv%vPBDf(uLH;Wl{H@)C#>oJ#%Jd5;o&e*=qFfbd_Jrm*f1lV zcEVbKPf87{;9Hfi8kLo;hr8R^Z%Vl?u8*EM(sKqTt&?QsSg#AT+H#H4E7gsl@cBM{ z_^v$!e$Jx^@|^f#GL}(yC&=EC%l4=_vnp22O@iERz<<9(nt@qAtsH+CkV=mkiup2@ zYQ4gelU*hK2n@79=jgByYiGde@>W%z##aA*L>Lo_!iDrn9Q6xUYc{!+QirV$Nf7n* zR^a9KG$|t$^=Zq8wTjTXYUmcFy>Tts`m85BGuaH$EWY>=xS6P==U9-;C!pRp2XAOn9MZ_ zKN|D}Ji>y5@a_F*z|L^y0AVGdjc1fHgAng7ku2Kw&Vf@H-UlOeI-0%h9_h$YgyS^i zJt@G`Wd;ymI_zF=+V^mSgtmJ4#XZAyk|&GOr=}MVMjO6PL?PMYx)xs3+@>8I+|KBh z+*8b>=N2l_fC9Z2QuYs-mG_M2@xoHeAF^X+3^)TuoKAr5BD&VjXz}jFn4fn zo1DPrS-nIKxLCmC^mZoml1+`sl=+QnkIk7LpTVBzLO96)cH>K5n-=Ol=eTzazewx7 zpZCv>%f7&pl$w5vUX10H+sn+W!32UZ0oH+z+*$KQyg~)3WBZSovEg;sOus+c4{fi? zxWPIK895HB&COAW`wTDoPPuM|1L@3BJeqX1s=e=%JC5Bh%%6gA9S zS>;;tkBhsIZ=3%rEHx=9l_SaP^P~;34%a&_B@VJvQR-x?T_j1sCv}|OU@o1MO5ep^|CQYKD6@UQx0Tqboh*`MQp>6N z_@;?!;&r9VV*xz*zCl|xfy3i@PDhAcoWjx)-mic7j(6T+%e=Jej!3a8x$orl3>}B; zP7$n4i|Sw_n#{ufgCG-vIfEpy-`n=fI(^L{LrE?s?$kLIkA;T|qJA$PpCu8*#Dfe* z-?b(szRaPB{R}PfotpFX8ZV~L=#ZxcieF)fbWQW7=y%iKgq*k7+ZexrCq?-Z)@zJ~ zrb&0t1q9JteX<+rzm!1+@Xy~c`nLB=i))RelX^lE!iTb@;4hVp@g=&;p(+# zF2jl=gFGepiwi-Mt7RzR$T~gK8sjqI_?~A<8xh z&cEmO<-Te_rRh982Yc`(HS9^B`>(qVgWf}S!);9E3Rf(T-am(;kAoWA9kUfq4f8br z^~?4HunTqOC;C5RpgnwhxT*~@-(M+Gr>!!>8%e3hLr2k!5;w>-h@jM2IRXEaPCT;z z0-a#@>bRXijUZ({5^NX~HDybHYyL$<3q}e6C~0hT6c5l>mg#V6pm!4BJn_X|+J@zz z!U~%6BGDosg#NEBw>QF=Bd>IzsuIgTLiAlLa{FD;4SceJ@^!!qV;5H5rur8l1%g(9 z;&!Mn4BDC@a0I03=@eBXJ@AoO<`LlOq&1fbFjfF(`hs2h4-;-e?@~C}$x6!d)F+PL zK^PnLy1|y5=gotV3FclV;#qMFjh5cmK%h${1x+3O_Yf#RRV%aX!vBg#0RS44eFBGq zs{`--FJ9dLk{bX1UtrSH=f#64{{BV8-7~MH|N4rrY*CR*KZ&gFdsPY$FdLSY%`o}s z0lT>4>&$!~vvSaOm&rtt(&(M#=#8}pvM&243fM`Ce_C>*J^=Xm#AN%3dF4bUYAF33 zX67|Cf?5C|mgW|4-In2zIWgx3SJ?{yYt!31;5+;G4Eb>yV9-8->iRD~a6!#dd_4XE z;ofAXbB$x<*=ybg3au+nwhpNuPy4jt#m8rwy{`1B)#Q<;@>AT-3_=chtOG{&&FO$+@WzTmIOgVf z_-*-g{RD-)tur4Yv7(iACH>;_VW0RsLaN{U-r;qL90;RN$hp`bB}?^WRe^ckx3XXR z=S~zuS0U*b?R!EfG5SLWYx)Y38G120K+LlA6t*?}laN7_@-AZhLl$x4xSnE$nZ%qt z0*Hg>W)H@RvPD?z=Yv0F|2U-44W#SfDQD5V4W@Y4dO)o{?KL&w$7t`S)iA>V-xDGM zAa5q9uYu6F8SbSn^=2PD>H@yFIYKw zbL}uUXK)=9GJNE(e|z%!(rUAvUI6{|3tnMgjo?K3fZ3$ydyjJzA2+UHC?MO}kVRiK zvxG!Y<`Ha8WGkrT$Z4*g+kHU@6Y|NwjH(>))k>y<>GM_3RF<|5xxKOX;JWz@p{tYR zg&O*#M5)=!@pUA~bh!`o)#8x#bU#bbr(Rz}9BMMej*h4TMsJE$O{q9*YiJg9YdB-C4p=h9ou4us zh)w%U8O2{U*f&yyt%~2(<}XhRhIIiUC#{9Na& z%IVbt$xYFdiC&-X<^&hl)3Y@ze6|u+=E{n*&M@%Rx1{~HhOq-1`9k6H_joX~7YX~^ zt)QTR1WxS_1dF$(AX%#yY%{=N(ISpOZq46e= zk(v=eGubmud_3_1ShcSBR!?78Gx6Dm{f9*~@OKg2!LxydvoQ_F1=K=; zb>wrUP3}~i2u80B_rW{N@xOe8yM0ctN|)kkb{PtfB#?d&?Rh-)HdQ$soGAHzNx-ew zm0`apC|vBt3)f31N8&F~(Mics(L_~o>lj`MLiQ^c(I_rD?_R$xex&+`jMp!qi}(_EZAT(Ql#Rh0Y5H@;B!zmfwc_>D zQOs6qI%$9FnH_5f!xWs`#P9+?eJR>QLy2iXZ1Cs)EBckk4SZpTD6HS#Lo)sb@jfJD zSBix=T(9(b#ppJ(qt1r<_IND&S8d8T3D`z8gNrV!_36m#vsv8(Z)vN_FL>M?i`9E- z`yst60L_VCDvJ9<7RA3;hBK~|KIPu4=##c3RX%{p+9|&fIp(UhWxc0?-jc3wowqC; zyHy0&RZ`Q4MazW8@#u`Ath^f8I3sO{LQhn*GVy>y)11Z0GVV%A`OZQ@e;AcnwiJ3Q1MHFaV4ibj=IakB9zTQ18_5@#qT zmQgy?QOYFNfS?ma!VAd8-~>1qukpLWwq%(r&_2F=f1zCs4k9=F(Xg#5qfokY${Tw&>IApVezM-N( zwbl>%rH?Z(5vPy|^4YsM-(5452Z#LTR02k#OK3!_cobvc5M73}dgf&Rt9BqCB-S0? zt{4=UUl!7>(c}|PcZ)Kx%=R)9+sl%ACC{5{RWQ++_D~>8Jc}QvsnFY#f$!hruxaiy z4i53cGRtBMjmd8{2=onR3wb$Fw!Y4A*}7eI+O|C{?wQ-EWtWQG7*3uF^x)%N?e1&w z_p}P&(uvg(5(nFij$of%SX!1G0VF1_sdquI`|3rV4~PUr-CFK^pn-{tNqD@Fy>0fj zOnbjIN9`A@joeO{vhq86oD0IP1GVnx%lM_N9vFU#NVNuy!A$JjXpp#w_(ovKMp9AV zwjz)-=y)x8Ygu?yo?Fc+Zrr-frPHFoCHL%JQanE+FXp_za_D24H}?7(y~aZFH#6w3 z3|$0Abr>W$=qGao?4~pGRcRp)(@Wox>htT}HFe10jj8M=}vaR*pPT+S;u}QSaWcybm@S z4t(ENRZWfL3&O%VtIP07DRZf9n)i_YhSr?9rDcQh+N>&u=lrkRkUP4*6Ce5}%safx zgm$a_+Z`==f=MHCnHbiLCydnfGICQPr%mXPofguQPs+B`5nVbPQXOGezg1*Y>ePCe zvxt-)p1Sz)DNp`2otzxGLlq@*uduK-BF7CpifFvd|Al~@g>;6E{c!71vDoTvsXs!v zZYdzr$Bl!mw$7)wTOEuqu>>0#DIZZ5y1Uy^=|s}!uIXs=M9B&la9wrh*GIEdfq{x`RQYf-)}v ziT6Pr--H53>u#;WY_Rl!GE(;aXr9(>jh8yp!Tt75SC&4_B^$ zZ^oHq0cR!|Zt}gy?d>2+JbE2A!r(gkaRVq?`<&($2o?XNJ;Zz*=0uA z<%?u|7tGm_3K>eM92-o08l_{R>>A}r|Kb}e{4Ca%Cx3FW2&$e^X{2DLJp}wB{(~#^ z6wSwd%>TbcR?dngLT=K_U+JvFAoq3(EOf*{2t zOUU^&ouGWnSt9&w4R`Kr;(dKinS-lneVtD${kf)`uV@~Uja%?OIk~~HdM#cwuo)%D zueKa%7mqDfcji_M=EieSQ?yN*u5>I(T)KAFLc+=O!0NfwZDE~+TioXI`5Db~JI*a< zz49~BLwbcz6w||Oq^{D@NkWZkBE(L;q5jfKWaTDxUR&fK-7N<5t*NPusT`bweg!VM zpcGW1Qeaq`heQH5fkg1jK&V6W&OWyHKw)>yh#9BccKm$};8(%T<6tg5xB+)k+jdJD zIpOb2N&A9?48I7{GjFF{(WUm=9$Sue8>YYf%JL>BAh)i2WxN`Z9x0xz7+bF=Q({!p zrB1pL?DB*yS53Je-Q7u0%{3#>DpM?dXZ(H{;1beJtp3 z*hGz9Nb2+uS?gq@A2j#CN{^;SaqggXl~|qedlyvBoT=4OqHp0#KL0gIJ3n#ubR_~v z1A-@1JbaL(=NLBRb^?TbZgV=u*i6_gZ5T69=OpUQ@KLl@ z8+;rtKE_sG^f4?DqsO^!Yf7}K@9#{dEA~gTIuzWCS@DUMzZ@&f5oBZ!wvIQ7Mi{hq z-70exgF5`$NR*y$^AusA^hKOb%gZXJyE7B+TD0=IyPM*ZjCTYDPc2rzoY95H^wTJA zjOb)6q}GRldJ;;Ufps+i;q~zeStITs((mp;Sg1cKIhx3Uh>hPx1K26l2NaYoqc||b zZ5Scnup?5eOVI*o!V$g_gi|mxMZCgX_-`|KM1HU$lyvRMOdN(Eaar+(-h2JK^H;IQGut?vTU7FYZRiXkI z#*8{|E+3_so&;rw=~TGzmmlb!&a9cVtT_5dw{v-K+d@aiTj(D%rCe!WRJsHgGOf>o zblh!N*MpzcKY_NP*oNN@h6g612SFRlBT!s~Q^eZSEu5BBE3plf5W><+lik5d;g&wZ zEe?D;WA05!Pcw?+h5dsZokrzMzB_3ohcm>aS`V%%F1`Os!&T1nzThTP3T*>Z)mM@d zqz69Z=!Exir_lHLg1P9^XD zo=MBjO-tJyZqcXg9Nf63-79XG=EA0J?(|uBF zT;zr1V52gjGhG-@rnqqZvSVO+Q80asYL)C(*+b{S#@jn+=ozi__AgR}pOx=WHI}(JdXv&~^Mp-n8l}$K7C_u-_9(DPf#8Hi9>a6`=Y!t5XW9j~H#9GT8@IlTUw* z59${cklpvnge~ETO(M*DRQP_)??>h=`bo>FDWh*vzpkluNYOb8Qf;sc@fy}3192Ix z^IBpvf#obwUPe&Cj1C1QC5e_xo&5#d^5)7+98$WWP-DjbQMx2NZ?PCEwmL`;k7IAz?79jboq@Fqj4A_u z5b7h@v5c;@^}JVDE>V0KFtV=|5Zk;8@V-8cm>uG~$*T@b;aj8z&{mktTbI41r;7jX zEEdyauhx;0@l#Gy!&>U?ZHK3&Kc>hHVz1Krb0*xc{?eZET|rk{Hnp&UMB7iC^b_&< zwkn;4`>>->@u03TB)o*P*1KACu{$a~$6AxB=3`OgdT2;kcV`H-yv<^VuEp-TcpbOJ zxX(Ta)@X%G9{qw*>zu=w_dk~XVNC`wpw{u)S>S=Z9y4VC9MkWY>dD}BE2L;@u?Sc=4W z*N`Q>r~^~syOE~dnz3ma0k59&UwOg$ygg*SUIcvyBAp_}=#wdZi5QoM^V}n!Lw4le zw|!lKkpO%FcPkfKEgs#ml#D})TXhdA1Z%kpu?fM!DL}D1ukmUp4%WM(Cl1y?Slrl75Hjgu^!1e$#1vK7E;7me;G5z;N$knH+}>0M`U z{=ckv_czoP*Fc#DK51f_0A$RR(x1R3$$maSomf8YqlqSt;h@QE0Pp?4M;I`=gMgcD z;k0!BaWnCd@wEw_}~Nb!aZO=5pg#qb%q|*!DFW|jH7RFa%Lv^%;KS2{6E4H68cRVHq4yOVXlBN?Sc zrYF43?KX}6t*da?bug8FyJ8_6vy)kG^fuPhfq~7i)b#uOZR%ov(pCK(f-pFRP7@Tq zyAEE}fJdfGm}yr`DZUEFWjC)DYORk;<|}dWWr?kbGCt@tq3}Pdysm4xl0V}sK2E7$ zl;@kh`j=7n@7f^%L;N3z&i;#;vOlR0zae8B-L9jcBomgIhbYdEiKG)|yv?hrt$Fu` zxF%h~&i=`qpC!ec*w+xxVN;>84*LqfE;xiPF?fLW#gvGU{9daym^(R&uPQIyC}Fc{ zzj5OzWU}SXY)+Am*Zymd*8Q=G@z62`ArFTl%;O~C5r;3E{8I9%T1`^AkMds0Ge)~hti12>Ou_VmbP3%>yqt? zY5v7rizuagxxu=Tw-RIDzf@nfQO0h5gahH0_jITvz$^|+E&#>W)^j`)ka6Mq%>Umd z2@KZaM_^5#yLh>AQ6aVIPJ0hXpD6}$V(yjY=W`z{gU7N(2C!{?)eN6ODP1T-L zJxkf(r1FS6D)-uB+}P@7WLne{I-RRZ56LK_lzx!^+CMHT>fZR};h|Z9R_^@tDGP)7 zr2AC&Y+^zL-DB1$GP*SdWxlLUr)b{-I9_%yr$iL$crc7dJeyKaezU;95s@Eby#8X6 z_j&?n?ut2@ikh7HwoVMNv{<|CoHJfX*JHYJeWdDjvxbFm8~oQ(8XA1AEAh??)S4M4 zeDidqFGR|F=e#8_a89k%Tr8>JwOEPFS)R*iZCN@gVM)zKDD;dC zGfd{WE$IYGR5+A}f$8DvHDR(=|SQ zO4Fo!43J?m@Q)Vw(wtH+BOsuEnZGBPi>6(}Z#t{vCxfuzjE(k&O0x=BP-b!v;XQ_odeIfYS1mbuw+0{8OXU>vif1fKFp zzL&DUnB)#{g8j2Jy8yWP{tcf3+(7HWdAiO&<~gFW41wd1T$`Edyh-oUNTz0oG0Z{@ zdx!miVGuw#{I}m921-k<7RCt;RJ&0Bn3)4pk?xks}|mWjmfcwO0d z;~Go9Cx`Y8Bpth&UJP~_8!9}(UK^@t(Mx^!@hQDIx6m`mAKYY|D?_nQmI{6yv~Uig zmPugJYXJCS-lI3y%s;KrXdMN^0ui`yN9vDPij%N6rjA_yb4tN9)Nk!6d0X*gLPNYF ztJclqy8pY;-+u=GCwT=3aaC_4)6oq&`h+Aa%;I7dl^p;Bj`&NX6 zwhT^x-YKgftgZcH)m?!#Za|42IUymQ&U~dU;`(DFV-vtJl)gG$P@Z^AACvqBx5LO`9lWzx%n zT1m$Fv|Oh@KYBG={N~HSs;dTdVpei{s-|GCXVe!xJi)?Sui$6j7NJv zO4titIplLYbBDgnT6)o@^J`!D{$+YM+aY%bU#Ylg(=>HPO9S;2^t}xSLa>L6%g=Wv zPkL`N+S6krK{WQ^+|+*Rch_Mx%1LJkM9Y^D2sJvLVxbsZ*+CJ$vh{PW!2PaHX$g|R z?8WGv8E5%qjg@U{E>Aj{fl567gOl~5?I4Y5XyM#IW8P0#a^}%brK7O3pmLBZZDYK} zRL)A-Z5N({BTOY(V83w==H?|DWBKod_a2dshmR6(vp)Ja&Gbl^g4V~U5qyvdpm*-0 zm9h*=33(5=3_y+yw8PaaiO;TffqQ(SPOcnm|IPFJ-0f)q{5R+$^z&@~rffINZB2UZ z%z)SSl>UQjfK|52p93_2Qg`|j*1&1fu_@9BEBp`Ez!5M*_FAn|4m(j`|HHu=IXJp9 zVRRG(K>5uS#}suV4^}Fms@}xBx#)gRT(-#992ig6xjW{xDIbjtHkj?42$>iDiRtHq zbRRBpz2W*S@YdmV*v)KSiDzCXA>R%9z(-oi;N}A$w#E?-jmh)4Pn{%>lOSQfYvA_U zjFyGUu0jxiJCw~PbWS_Z5By&MGs2Gi+3N;PJY)xKAB>^_gT}(YMTtLt=TDv125#X9 zsx#M7j9C-Bx^RZ74GrGpL|r}XOK}u_k_c{!?umH&hs=1oU}@z0k=}Egb}z&8#-GiS zlXqbDHAM=Fd>yBPy0VrA-*0@!yXlTR_;~rv5n*R$1l2A!hY>#n2GOf0(0}_0LjVSd z9-B3UL({e9)W3WHFa`LB8rtKsKMk`PxXAyK7#jTjznCga*OCKr!glE$<}}GaWJUNx z>uy#fukdYbM)S8rFD=Q~7{tZU3yR~%kA2z9_aQUuN_KZHx_j-jkFx8$AC`?8J^qkM zQHi;L`X`U_KR=wNz+L>8SMUgRsgo3+WsDYoJN5fmA)mD0c~fJ5GBUFuTSgO&VVdn| zT4kykX4Cq1epZC^A)ukklrG1*S8i{^<2C2K2TFMO-hO$TV<-1hZf=ugmA8R)Gz@i^=~&FD}K%HF{Z>$zA=HHND zTnc=YQK1G&ZT0%4IN%m|p3{G$H?UB}u5X7{_|Ue=`#Cs0N-noJU=kYf@qBYci+_gB z-E(!`MVPvp;lFn;S08@>A&B6;{)sZ(uKzHr%QpAG8@D7LOT^iqgk)8BS zlk(v=4y8BLHvJkWg>~qRg*X$7JC#z^HYyKx(9;rz|(dAE3T>YVMwbl>LY$GlzXN*~ge zl4A`k)e$><$px6DeJXySG1Y8HJeZi)WpK6B*{3mgpeV`>XB>@@O5_`BgHc~(&CKuK z=y($r14~|PCV<}lkuj!)vs^N)li_F$pj?OMgn#i=AsA9v_)rIYIIq5l5 zAJpsm=SWW=9p(%CyA>Nw5e!T7)W^$=GoLpc>&BCzj_Ccxm36ho$c*;iNY{gh|;IFpylQ!Qd7jOk|vd(*q+}_nwjIw_#0d-D7HT z8lO%C^WCRBK^_?uRUaf2@l&r|x}z1Mpm10P%#JFKFk1tf*EZ57g0#FUA9U2Qzw z9<;RN5{(d*-2vxEQZwF-MjC7*;r&y8yU@Yql=}y^eyecAdG>q6R%X)6T%-L&}Cbt-D*GA?Hp2Q{dS z#MH1XZtUdd*p?DYU^BwgVkA1B9o*V(PzAww)&ut3ooR7WET!Yq+A((WmdT8YKHR9wiJY#}9;;=b5vCI{_Hy6c zAAf`T5)<7Vmeal|h13p8PpY>ySd6`+WT_XM5iok6O*1qG?8`pF9E`{Y!3ToDXnR<| zMqT$LoU)*5N$*fW??B{tdZP!k=iuVngJc#TjZOO^KBnZmBW@*1x~#NiY~oODT8FzD zyC53HPG-%0&4+2?L>xRMm0Vh~r>Xr4nPa-8mJ^cOp(Oce)hBFj!u^pKXTc%}ztuVu z_sYiTk%_;*?#(fkI=dnoKQJ(80wcTxD=0B&*>rpo)3M!J>wxuibN76?dGYp*7l*#; zj^!81JX@$2y0m6i${0OW&ctfTsNB=e#0tm{(9!VNs+_9;TMF6LflgRVRlCEjBNe*U z$QmY_8;I+5BYIrN?m5pT|JxjQ3p0L939bQ~lhx z$^Dxq-AVCmGAgO*&GuYJiusYZFGQtQy=i{N6DD?8nfTsLEx!$2slP!H_*QlHRcdu@9xqSc0t5%Xxkf*qGO`=;euY zd4t=ntd-!6%?YC{<`52yQaq<{De|(m@A3KEKsD#)heB^mCC!zVeJ!3Y;3~R8;u81zik-k-Rq>GY@enc>d-}qM1)9QmebIZM>DA1 z6eMV{t4Agqo@x=V=3g)YBb%tgW%aRf=6lj^TT}rJd$km7ay3=Va`xoWz3Zc*deW~7 zo0e*s-K;pRAu+MoGDdun2INn=iB_fm3L(rwhHsbKEuA)ZY(t)0TGVoTT zASpDvK0ja&{VK=sYAL7(DNei4+z}4wh(xbTqbabrbND`A+M6(HjNR@V)KieR3Ks9Y zc;sc9ct3mZOim=%64PXu8il0zOY5f@H(81_Q6r?QEx>9^^u^r4(o21}aKm-BUs{bR z>rVUrqW;-5%DoXC4n+kYvI(o50VbN-10xsDMm;|hEqg&I=vRlTTZ~b=y0tif8{uZ# z38rfs>OWR5G6xVw=BnCP_%dBsCd6N=&h;$7 zZhE8#8|tx$c-n3~G7k*1-W*V&;?t{qNb__+(dWhE#PdDkPaG^LXr&n8@8H|9(rp>* zbv2`A5YMR}>a`Pw%03k-%tMJjtqZ@lR_?R!HU~^4ciKMlB6`OTsS)9@neC3QE|Focif-12itzNIb z!J08MH_UKBqz(@jTljsQm{OM+Lzdnjo^_C3@avn_>`&~3UMF{OFlgm_yU+RDwtR3W zRM~M}@Y1aq=U%m%CeriV(;*oh z!-ze8!a%VU^01bpR3yvt@*TrO`Vw&dN->>Tj9?0r*w++ zwu(BK+i3_jm7B5FUIWDtoC;(QBC)(-NYPd?p<+x)QBGl}D~+~Q;xTUz)hs``-Osqyp%!;ZKpRAjPW)-YVLTnbiM_`9~ z#y4b|uk@eivrQ%>QH4|?>Dj1wrP*8t-71AL&;v5cU$8>AR+&N`vDC1)OFJ-~HWEU*5o@tsLb{{&`A@$0F3alwC3L>g9SkK zTQj9uDkmn@Lt#Qw=w*|wKJTrxsxXcMk8>;Iwf=DAA>{dQLE*&PQ?nubN+L|WiIsah z9T!^zENm7(e=s=nV)bDCHP=O^=-x}pGDhYZa>Or?xCSp64?G-GH^jJyI)Zy_@&Z>{ ztCEtTIyn##y3Q*?yZ+U5g77Rwez);ChcZHn7Lm?n!?F`2t@bp3Sb^GByy8lQt*jUJ zIZVut!QHdh=?f-gC%FpL=$E`ejXonP&v*Y-kG;dnhrC;i1>d(r1axhzS9RXzb)^rY zCHJEQTO{D_dR(^RE`5q9s1ef^0;j^UCooYv>swpCD$Y=H5Ix+JKx#@`PxP3A;G8wt z*!1kcVEQINr353Q8kNo(WxkKKjC)Xqg5Nqh+KM@c(mfzVFfl8;FMS%@E3=QVa0^qJ zKhXc~;@h}OUQx@yR#!FrtGMOG0kxSeV1leA6(NyAVw?h_iMvtVm*($(i^>O;dge)` z?(hF1KPN~%*?eY2i`ytQtaq24q-Ms^5O>4oaQJYm`>=1K_S(2Hxt)Va19Xr9UgCLMEa0F0+-n%L(jvQ8>k z+w7U}wW>QBDOGs2QR5lM%o#CWn_lBlC2J4!bWK!cQPL0j8~{t+`u(l=mB2DVe+2Io8`R-ql>dwQpTI zztQ4{Y7c*LUfDN29ew?KI6K!N7wunzEqRrH@>3q z-%yu4=$S=&G3Rl84TCK&k~j0%pz8mS zU6g#yIKqin&f%;YWd(YuR<)AWb~9@~$v<>J$)S=_>BG>y4Q8AQY)@|T|6}gG1Da~H z?O|RURuBag1)_o?O;iLFNFpL4AVhj6Dk=ifgdheXc0`0w1XKj1h87}H1wvF*no?_aBTLk$mP;cor^_ELW<1c|6Kpr2$`0dd8Z2P7@yXZ9kEx zzFL(R&8{dQg*5d*KifaX3Lmmk@_cv1UiaF-=3?Q9kEYsy=%jW!#?s`QsTosr#te6B zQ*ylFz~j?U1KRswJ;sQ8DGbKKSxlDaIf@TVOud?zBEIh!8O_c7*m|`zvo60UpgfPL zw?<60#z>NJgs59>tQ5BMQdEUN=AGtyx3Na;YG*8b6!a&hT#>WedE2+lQ(p($a4t-H z4E7{%eQU3u5v;pF@bJv@@22*Bvn``DM;-i4R0Bp2mT(W4UodTLa8y>7ENIm?w_Rf_ zZy9|pGTyq|PvN8>bZ?l~i~ZL7udUZcM6osd8@in$G=Hz$;5{*kqjU1vJZFgs!CDMf z3+H-WCAuQevkeHFKkc8pT+ky|qMo^@!SasSyQj)(m&p?K!b;DI+M~^k#LjKm0zLO^ zwzXP;C|Z6v!0+BvQ;lYG3n_~BfOi!0(HiDCeW;^nfh0Gd=+#D4(Rp!n`dn29Rn)!* z<8t_z+Qlm=odJ24N((*~LtE`OR_4trD;#-gcq`+nY5ly(9si+)C(!as)a;Y6UY_G_ zNFrwDIVLt}crL9-OL6e({34bjB^-ynbP-*6X$n8yQ+At2>9&X9z1iC#p|yiES~ALp z;gFdx&Ca!rjvFhnLoTawH6Nzn(f%G)`jJIfP7U0Lok~jdi08bkf=wese+mdy9pm^+ zoXhO|I_>$I{xrC$_nmRPeQfQd-9(~j@pdDaP{j$oh`hK}vX088x|{l0I!nfTHya7V zVzsYoscb2`0|#_tP6s9y3CQNhrXs&gY?+PArt@0q%daxsGXwAMhzL`3EIhhockO$_ zCEozs%Xcond9in`#_UEB)6Fk`+`H!T z#$XLSHF6+PnSRgA`7XbE=ZB%px}h0%eF(&Uwd?xAwhv-D2D{IB9J|mki6qyInzo^Z ztz|gC^;!j$3}O4a+zwwFt}F)Xh<@A=bKv`~J>2!>n>N#w((86ND6tHR4@=Xj~dr&rmykLSiVT+g|m=nLWNo7j3NL_eh<6 zKFn`o!3=NA11ab^*W)qLcQ0=iNj!PuYolzCZtlU?I0sUK@Z48AbtH5)F8F2d zt&C1?c;WmO;kaK-4GzzUVB5>Maa z3Zp{zH)`9a9L~TmPA1ldg5dVCgNK;%xv>Ruq*)r&;!A2uw^5XtgX9d(O8$uuzGew% zH7X_nc8;}_7F8;6ZuQLt=FB($kSpIc;#TG2ZmwhW?kv}KQgq+E|FlGCX+E`Qu13pH zZC~}8Ec58^%R$B3x$p~Hx;hec12u!(i|c(V+g`=r|> zuDl>rrN{D#U20*=@Da6gn>OoaOZ~OMuq^q*7S*CT8+4}KKHD4~(3};kLBggZlV_d@ zk8COc(rOWlV589tsVpxc9IGoXRo4yFp;V9{ce3*W#xtma?l*MAv@MUdtaVFyoS$#| z+m`hm-`2Qy(2i=oLA&eBjU(rrm&BSlpx5e|T-_9JX;Wf%!r<^BMz54a(ab^u3|*P| zjV2Xt-)m#|wM0cEzOK!z!SO|1gQ!7tzMbEbotH$5p3c^ptDT9%Y&)M@4GqAH<5C&m zzq|;D7JuyzKj{k;{wXn7q#>SKRMNrg28A~-ZRK@CU2KZyNJ$*M=beq-85MX*skFKS z?B=FuoVLMQOQqHiMAET}Av4jQypLWS=FsAa?!;SF%eg9XNrX)l zXhlN(#MI|5QMJMyVH>1J9z~Syc$Jwh9fi~;izz(>uHUFzi8maTwZ5RQ<8Y@*;08Zh zkzOXz8>)5R6*z9{INni9R6gV7??0)2DM{gAy?DKj9%bRg%TSSOjYkKdG~jn%ezb|>{Ot?lZZ@P`+$?Mk;G?$((8xF*M5RM$X$ zKOMW>^paKDX@(iOy#eYstFK)p8nMyN@5a|FusbM}Bh-OaQeJAOhB-!EG{W8R;&G{c zjG66f6tO_XBGoR(@iMe(;M4}Dlgm}F&D?YE95_(S^SC$%%QNDc`1F@Aqw{k@$Idkv zZ~JDvGa&BsjaB0@4NaN#E>hYU1;XMvxHrn$U2ksnsJcErI`_h0?i?^xu5i(2f7v+o zHD>!h4`NT(yKXo5+eaaSwz8IFKbtPM^rW{thhMZNtzPS&@otT)NoDrSq%b+qdj9b| z=6SpWYlk^g-0NMHc>6_vxhoUK!|@rP{pA9ho@IZY3~w_^Al%=*1?lhsSU;YmZ*0)M z=5VL+-h`58+MXwnVP0_MRtn*DO%e12r75`_{^KD0t5HEkSc%rA4ZYM&uHF^XZ(03w zpUj2>w^v@MH^0P!jpux8)`@-;lkXBLcNVAj;!@ISq4m~2R}~+UFZ`yi62x9JF-H61 z0d`L19KeivHBetcWMM`q!u8t*A0|wGOh}Yo?fNvG$m+G}>(Pyf*=}_5&FHnmyM^WS zMVG(duu7`BQXpN?yEdvfb&r`4yq(^5WrG^sgK$quq@qfNqqueN>2`WpN(ViNvJ=`nnnts3C)=-kw8h z#j!$EJC>A~$SWO~;6M;7o{?Kr*Y_Pf%xDc5^A&BexHa26o_NJ#?o75~fnrGHn|Z)u zwldW*30JA}ihvr=QPZ?`50(aaP^UF)nZfJMNq>L+1XEbss%a9t_=>q{k68F2{oS^k z#mHiN?Q6763uUq{yD5rZX!wMBt03R;01gCi4#1C>h|hklo5f-n@E}HBp|!;%Y5KsR z=bMRoJ5$v<{U^Q0Z+{hj80{nSWUsx^^9{%D_GOQ6H)K1Mp4ImkHWr0B9;(^{MyFww zx#u_T{d&%~iN-RTQ)UgNrQK7iu*3dd8pc0!H0@z4I#2rO8&ll}pOxr2t7D?y7W{C3 z+x%5PuF3DU|78YnXT&qnxLg1=rEB&$GlVTYZeMMnCzbWsB&HSmm+VuI2-$M?V=I2Y z*wJGd>2arW^U)NnC9AV-;j+wT={jTfo!^aM@^nblvdIjz=3v|)a zZ;?1Bp`iL~cNF&3g9KbtTo)M&0z5|&bDDY&a7uA-2{^0%A~Yq24QwVC(ca!tl3so( z^q@d$_V6!Q@Hq=6a`RAkua*yOR}_$AC=sEx9#J(vWOdI_Jj*8Z{O2_<@5SvX&IcY4 zzYPNY4e9ehP9~^@ntWUXSM4=Sub3kp%`S;JQ}vW3(&Z;*Q0Veya(uAHvv1sv@uIg+ z`9N=4e$3>-`R$iOX185*v%A5tXs&e~FjcFIc#(Ncvk>+klVB& zPiddgbcmUlikc+$>35L}_V0OFk|24rWVOe6GFf2WD^*BjV8%HTH!vjsk5cQLH-aH|15X!GH?wCU^(79ELvbna|NU zW2b6r9G;XiKG#yEZj}~yUd|@5gBgA7@_R9D&6xwlAdSm)rk{guh+NF#^(4VNg_2x2=sI!(XwQc$Fig^ z?^ED8W(?sI{5c&ZWwb`4naX7?vM=NcLA~<19nbiqA=~M%T`9``tO~;?flY-FP}3^} zv6c7zpg=B$(g5BI#>M|Wq=3Ql??r52eDOCJ@$YXGv3QqAGqK#sdHCp#0L~CyWke!! zEWE4tMc#p{$_WN75@=dto;MpJ@pdR9VRt5{dj$< z7}vy&$TG_;2J!LYIo$jkdX=X25@qV^&HKDn_U~Y}j7O0qAUrwPR(GWmGbfZA7=V;} znUwn@sRB~JohO#q;UAR9>16VF5kjtm`Ac5Zp45CjWUIoy$-d}IN|?PkAFd7i4KW1J zKy&BmPP?H=!p@>YfO#(f8p<_CCT}v*Ery0h;neB<*PybpYDwq(kSF zGau0l=E8X5DIKf1++=ZP@}(fsQmen*=b%oPHV}%uP<-dgK=Q8laG<>o?=d?T(H)N# z=mne!;4UiV%eJ3h(jL5tKL(jOfctHRIvkAL^W*qcyQzvk2KlbX4I9&_r84OWxd*(x zY;;E)I1v!vlX)JFfV-edSW=$KSuM!fRMNbp+`eqctJ1jI-vA=AA!RGpg|Pq;Hku)9 zHb(m4;ZaI+u3G@2Jz=Z}j%3z^iLB?D+iIrw=e$YRWuiuF84fl^bG= z2i|C&i+a|BJT@@)H7}j^(qP%|Cnr?vFB2fM*Bgbc7m*0IFrX#uNOb|!oWrdlMh(#bkGgdR{wP;y0ccvExA0QpjsH#sdk#&gsbTRUG`BnWdbA2}_F8!jPHdMLOBsq~RVSFi zfM4`Fc`DOgY>31*N#L_QVy!v*oR#;h%))RySMrOECl0xa=ML%_E32$F!wx2Ry;U&f zrNyR;^Fn&I+1nd)i`;$+xZUT8wBRF_h?CE_J-495;{j%M5DqFtC)kT8Lgak%e)&_N zWqMweb}k}p5gz`nUrWZ4WJ3DxGvbGN)9!Umwo_f6RPy#NuhSX+!|9PYY?@tMV$Sk9 z=E+?6@x#+Ps*O8xu~`>f>KT+!Tw2%)Bm;hE zV`fshIKtwAKDy(AOjXo_DbJ9YM#1I#oiaPYaCBF|bTIEBJl`EfKKZQQIY;35>ok9< znZ~n{dd9!|I^Yqk$$Y8?*RjZ#LvPki;DPM`2n5CCjRcDitLBQ;T|Y3j*i^xJ0xt@E zQ)=A-@vCIH>dm1{;Lklj>-k6=-oKU=SA@g9vvX+UvM*j&{3&qUOl8>Q z?zigMO-qv#i?|Rtr?7&0H0i{?*b-I^ude@Stb*lJI;6Ej)L!A zCX7DXJ_J8?6LD(9mmAf>uu($zp*#WLo#YlTRdQ4G#Ku>~>lRZ|;xdm*+qAko+$p2^ zXwREU90iU(glQ_}4FvFjQU+uOG_~9(`2@OoP1sMszti1;d37~Yzcu17Ybz^;Qa=88 zqZe10O(AVY6^qHdUM%p+CK4-}WAce$&`$p?GwAm>96~CV{30$QdMLr%HmUzW9{T-| zKUePl8*d@$b{y-h@SbI)uuX6vojA&9_X)eW#>ih zIjoPaimumcJUatc5x@na=M^?mTIC6oXg$BJV1bbr_%JJ~e7<(tCV#BA#* z`_`L;5Kl$J5SX%1M(8pTiG{C1tGo`bQI%HY?(w2|Ns_3JR3n7>{w;PkOC|ln6eDbF zZ;e8zg4NKjILW|u)M@MZV#6`rMeC+XZNwbp&^y8uuHUOS*-zV;h~rX+P2eXt4d7d$muWT(~KqbRGH(xG47Ig^3)XtmcwPX0OmJTeE$cEJ1AWYP__R%XySA zZj?*!A4B6c8`6`Ww_b9Rf$<7BO#F1Fjv*QIgl~C=gw4(Adj}Qu5u^ z!8X6~cJQrBMhYG`rgDPd20sNJlSmdq(Ce!L{2-LPXsh<{3%K4!YwY{Tp4rJwQF(Xi zE!^_E+mbbf-sqd4Yz`A257~2qntjIg&C)V2yr&^kcvVbeG|Mb{9r=(o;QQgq8C4nk zwZwnd8VYg`F*Ey%$qCVpaY(^xPUV;O5Jjkz+@2ALH3QUJJ~I&S(*abBbPWgefWpx7 zPl0S07qAKMx7{;)cR@`>juW&@y#A7LNb`V@Q1J?TaKODC{X$Gp5c$hPCBKwR&b;*A zO%iYxxllfx@SGtqX>sR^8TF4-?f|7D0zSwHY@Lu`S|7rYuR63MbX3kVOZzL?A*j5K zX5z2IpnUHY6!2cbeqiO8L&3dTt=r6}5yH6bcW8$1KZhvtFIU5NmMJx}N(?(l{v{Da zvuiC$p#k-yCTXyfL_hl~VY0$e1a!WP^)_2QDtrqNE^rK&lgn(_$Am8HTtW9G| zE%@cwl~*nz(I?CJdQN~{sIy^>6yH*XexBZUWkc=g99)_K98=6~py}>X-Hf}OF0O-wkW5T4woIq(R*im8CjT0PfP5E|{NN_qYt1LOD@Fb!Ca?{RmKCBQ2;BZhiH5%~4UX(LfL=`q?5tj;$vStU z-c-}zP`Hz(ZIB(_eVtcEO<{t8nsP8^WUSgN;p2tk3>!?$Yu_%4?k}l${`31iEd0yj z_D6x^%8&Z6r*}6bc(CKKpde23dWT8m9$e0m#~(JZ&#OmLNOW^9g3@#KV3P<>I;!EK z>xlyv_<$kojC5=#vE#!9o=l_$w@G734d{WSaXw*Ykhr4h-?E#Jv`CFK#4Xzp<@=b{ zVL_E>ThmdWSa--1pmFB5iLHuXh{2HWF9%+Ude$8Ac%&!)hukMa^AUJcTe)U!d1RmQ zQUL@p0~@bSSIRKno$ti`MezIAe$pRPEH8XB?|=RlmyI(IC=4ys2_p8fY@4zp5|*%fid{M?>F~9 z@huJp;t4c4s_ag9T)= zpn9}r`x791C)^{y9ySBfC$B-iMmj z2lVOb;MyksB(j@bN$1flq-ye_C4@`#0y+F+LGWnkXY{)smNJn*qgJ}=4!oh1*Ts%@B^wgYRu3m**4 zHqyGMvk6;-NycxJ??}MRVDoEeucU{UiYYHNC(dZSyLmJjhXE2JEVU29!{+&_uyK$BF{PK*{sN8jX^B~5%L|!c79Q8R|sGb*&Xc$7}<<` zrJ#eyd9Q@8rtXaY0r^3{R26hawp1?JQ$SFNNO1zI*GPWDvT>f*f?zTewqPL*HX(z^ zJnX_b>jd88CisMY$;*E6#W+$ao}sQZqKC1xT{XyU7jBzhK)UvL6>Dz?Y-q-$u~Xvf zCZXHyE;MDf-1rh#eo{8!25$`yGYY+aWV~N{O6@MuatSg8u&c4AE7PTp!Vlrke+s~@ z$eOQW7ow4;ON$BY8(2act*X=g1m#KFJY*Ck{)U_J3t(h`uG#IA_sRnpRTV7L2qGnz z1x(9WBuQ`nC;|q7EXTkWLH_7Ukpd!fQ&ow9`9yk14>*Q+mA~HiX@gNm3Ty)V4FLt` zJ6!&wpz|Lu40?GfskLo&`jKfFg!Jcjc6RjvIoZRI*0XY(^WYTz{<~U3|FcS1!eH%9 z!k5N-eLVLi5>ZNv5_rEMmvIXo=A7A%`Nr+kidX|Cp-ziWAEe%B$!=Oj(GxPt3Gkk+2|<4BHzb%l=chm?-3ii^1z*@$I**`}mZFmz0WQc{&57YQ z-VUQpYGU*`=)eS(K~8X@73*Sfl^dG!CK9iiygQK*fE2{&8KJI!0B;4hGe z=sER-v9q%YRJY4nv6x-PmLaVjtcyWAp2HhBT=#0IKTIC;u>}p{MiOGUiadcR1@Z{N zpBD!!9xMmHy6Hs0wPTiuUb8HpTY}l##6VqC=Va5OeTeNcYsdLXlSbSFmQ_&9I%e^paDib`>g*hO>U`FeWOQX;ZW%dhz{{JW`B=u%+E zzJ}%c5_($01IR!(o(G$feL8cIt?!gV%Lvq13cD#cZ@>#g*6Whk<^zug7E7b)m`M1R z@~a+&j*)%#_hOXF2yx0pQsn`X&-XXcX7MMgjhT<+{T6kXura61E^SuU9m0H|gnZIm zj%UmMPN7)ji#0n(NCjpwghX$6pny@*Qn~;B>~X=##s~i-gR38?=65S~6pw2+SaO!9 z`^pXeJ2Ukkr;9&3{xIc}hiy7NEllao%S3xU8(4 zRcj1yCtVE}@{9IqALZQQ*%SA-T@8U(zBcKhTJTOh(!X*3Q-!^lMahLu$IMA3rP>Zf zsBhzsI{}~M?rg21PEF-R1xKTWaIz>LU(_2Odk@4br#qIIrLWF@WTgkdIFFzT_h3Pq)t?48<;G=S0W|TFc5km#cqiq z|CcVXU^!gf>g^K4{oRR&mnkmFOI$S5bA{_jmKRUsu}GB5U$35csCH@xV>&E>SW1x9;LG!;h!T zA-g(-9V$UXzcsAWncA|ytNjSv#pJ{KJ+mKJW}3zw2sG%Y2<$IIO;w&41kVAqq|N-w zLn(XW_E7tZQF)A}KJ>42;lHtQ|G{!lo&@3vrokM&??O)a<+R-LK3=zXWfbFa4|lZd zVNA<4MDkL3(K#!>1u`Jbh$(G*e=_!%_zubJGD*zke;MhA|+%J3Gw-O&oihu8pPAua;bK-W=5LSi`|(;Kc{OG>Ytc=VX0JV5WWp z@BV|;JzI81$h_vTEqgCVNeL`r=NGtQr&SMSC7(Y)X|0Z0Wc)T&1QoCJl4u8^KX3P|DUH2f@!sCyHGWKh%=ks^FgSfKO7U}m#UeWG7AOp1$kCl zb!Mj66R7B1w~2ZK-dVy3yv!i~EfmHlDiIv9?pf z>ZJW@{Nb$EbO+KRB7QEDcY(B(^gK?utV*Bb)(3U$C?e{1@AeO(#PtSYo~2>c64NrU z+fR}!d{yktbFPMed~^S7X?BP-8KLAQB}!)KnF*n(o4OCZ`Y#q#{@{OQDgrEby8ov@ z8)^!a51=3k=n(}WKLMRJ&liRWS}FR-0Q_$rJd1~>yFvI?Im+8}C;`H_FEbfLVq*CD zX6Zc7$yVVYJf8I-HqQGYOp0^aYL~3~#n!Tu`Wc84Uc_+kTfC0kS2UOCAfnS!oS=1D zZ9VPt2XSsTEIFB+MAk1gIot7^t-rL~;$`wuLA4Fd5p$*;_kv z(Da_X?fxY4L7J>|1oshMO{sFcCd~PUiG~0?A0soDe25gslPkChu`zykL+WnnwemBD zV{FXe)Xlx7YW_wZgX$wa7o%&x%UH)AR4903JecmR7x_TxQtF#3cUKwAHfhKqnVbb{ zcX$$Fz9Fk;8|qvI;imbN>-3`-pEl0bZgOI}p5DHe&9~1et*VwXkS@v&+f{t;%$(AP zk777-Z<{eD4&9D^Lm0ZtdBHRFf5tQiiHNs19T8V1@c5n@ML8cP^*Z?x z{<9Z%65ES@>vt@myN>iEeMwcy!}0cE5s}Po1~MfbQ^?Qp4U|ymbyTH(;i1w$jskCN zZdd?M@B(}wXzWe^V=5!_RKC_&yzwNa=V?C`kp=5^4@ek*d}UNJ)U~J1Ix$WL!TSzl zT9Vpeeb+F80Mw;-C*T5nYm(K@OKu9TUFKm70}T%JK)xeJFijoR(ut{!&It@lVX(`g zj6ukAp{lv0?*>ei=gi^SpQqihZZ%jwumv=(pT3V}%5=LFy+ej#o`cNRK8t2n{$?Rz zMwq>tM=E(?>y4&55b4K2DP*dcKSC$0iuvhlIH-^WHWNhn39WT414Pdk^nU}sCw&M$ zjt%nF-;0<3I4%9dHRg|>-GAkj2}%>ekLtASx2c;3A_WFpls9#2=TNT&zdrQ(o+? zn^K74Xt`fR**+guWt==2AxamWjZY*)BuxUC_t?H~dtw~h9>R=1V>^%YZbK2Klrk87 z4pJfxw{6@pzWU99<2x9Kt^l(UZ@j~kLHo7gh%fYZ>g`)RYoav;?p#)JFGsqwuOMJ_ zr|X`$1i~z86Ro-IorgNYpp1gd+ySxE+sAt!7_ZjX+o84hJB~02PhQI@oTtC)rv=R| zQ4+L`b0Z@s{FO}y?(JggF=holhyks;YH<&SoO4gTPDy{Ap82|_we5U!i>{Q~ekn;2 zvsSaVllP9hj%R=0`1tW_h14toZ^5_g)eNlNV(enrn$_+Jp;NfP1e~jEWSq+l+ZUnP zS1%dJzKS-Gou#3Hpu=4rwY%OgIWPOSHNP?d0Mn&)Tol8~aR>YB2zIj4Z_{rlKx&5U zK?r*7c6q&w#ts?mB964$q-3pTeU$iqogFgsJR*0BXrGsR?maJqAHhwBNd;zaec%04 z;QTU#K263s(X8*1asU9sZU!poSD&oTWe5XMhjkv^@`Id#yX1l5pO)4UBK_PqOYf*c zZN@{hdrARCUYIOql5Y>z>1m#G-h<>HK>1``DN?;6PLc`=VuVS#rZjJPa@lJTbpMLM z(OopVw#fIrNPhgjoR-tvmVM;paE&5AyytqM+dCdiFVm<%3%|M zk3)e&*&$9eJM+UAP%02QyItQ2XBK@xX>ARh4n76O7p>^HqUo#~K%RmFz_%&z2SmR) zaj_myMd1+`96t+4-vT~PuHz-sLHU?=>OH`ez=K`MI3nLjfkdSrq&*-z`|E6B({C$K z6MRMaVeiGgAz7G8UH~5ry0~H8a)>0mBL#>?i1r4-(x|!Z?hdGgFBm|e- zI;5XF2Zsz!x6{$+rj?Yy(TgB(=mgw!kyVZ=N4=yBF3<9){Q&*Sx_CABpUML#Nhnc6X%>$=)~!E#&|xFA=A%SdU7a&(BS<+ zbgUEo&5Du*sE*712|@aU*Z`y`zw^KU?IT#a{EK+M2Wz+75ySgz)AF9>zO$vphmUU- z{E8~BezYL-I_8G?lUw7@_8Oa>D9|7#QOWFW_OGNLC0JA`dAi#{=KK==b>E7AexrHK zWFwPt*>kJ+lGC%);dBV<%I1S;&$H1dEkEmw>*&3ki>$on5`J-R)zAltH*oX7z$>rq zoKqXZlNwJt$Sa?_47y`8ir0;%M_Eth{@5nrH$EHXH_)rVpG_x1L*jMliK!^(@1I-| zNG94$Cn_~(2QKl-F3!#KgOm?#wGeWk=L0`W<-D1fhUu3`@#aDFOwE7eF^`3D0Zqnx zTq-tmgY5h@84GF-2Lxv!McWS&T}kOPQ2Rw!p6N8dYTA3*$H!OL<@K)f<7w*vCe`@CI6;O6$T3veV;da9rzNsMkuQyn^(#`Vpa_euk0 zm(@KDF5Wd8kX^iBVwO-s=C_ux$F#Jv8*p9e6TGzUvXXJcmyi$w8){LCJJ&W!Tgy>9 z7<83d6w>mI1TcL3yn2SBMw~t-q(;Q6d?k2$QmRfz z2gdH}YW$X0V;uR~a94L;tZ3W7(Pvwo<3jE5ms_-BQsQhoyq_EaaMiV#j&}P()kA&V z74hD>n^CG4N_Z}+V%m9iqH}{sTCHj}KYjJ^(p>||&e=(yV`B6m*ES$H;S}hGk(5fC zxp^Y2jnEL=2_4o+ny1Zc2F&aZyFPf^&I2J)WoT?2jW`n<8uodSW3*B%w;UUrKrC8% z&5icrx4@=4F>=cT=`{9}ysGz|Js}$)`3T58g6ou9eHV0-M34=+uqw7A2ibFPdHW|3 z9-)+ALCO7X@uvW1h7_k?7c^T~UY*O+SL%x=`F8dZiv87x>9Ef3cMc^ORSVZ6Hsua+ z?t6!)glR=NY17u;ffVi-Q}$7e9z&r{<73!uhEscM92l-EmiZnzTiq;Oxohu>54YH!O2W1c5_ z;x&wwFZIM%BL|Nu1%HSnedQ+lw)G*ZzHloR6A;DBQO{B}^IONQ%Y8l;==F&TESHAu zKd2M>P_yLey8aIyw~d9UJ;$$G^?w-LBf2;N6TcU~<7o=c+-J-FE!$*$@OA2zlJg9v zaJ0bzU)elc>^5TqwgFx6CbaEFKOwzOBP{e#{#DKNIBQo~e+CHWvEArfBFS~qw6$lY z_R`KBk-o(vffVh9ef~3PwKwK_HW6W9?TZUKKg=U4%D3jYgN+ralBVlgp3{?lPcNA3Xhu3n)Y+?>c&) z%M~;f{cXZdG{a9e-GkgwP^mK8cej|AvH+*_kB@dlpr1#or_h|d7$gwiVgViI z4({yN*RK2Hpsr)Nk)2M123L5=gOi(avbUF^MJHct z19+?PVTUJy?fP~EbE_8({Casd2L$l_HuO&v{0+=2T7PYeVoY`V4(n6!HtfJWEO~+t zI`2h1gDAoDI5+El@bs<+4af922KX#i(AcgBhMBZpSYjY#{S5)qvkxu#R>>-fuXkvI( zN#F_zZqE<$arPkQk2cmN|0x?OM}5}>+%td`{K5zDWO7E#d4}BR90s?{Uqs@?6qk1V z32_)CpwwKSi}3ki*DVIldhWNtsXl%NQ!`CZak1Ziion_jj5T zoWiQYlRw=p7P6jSf`c4sg&)TE^qc0h%~)pQtFzD{>?WYjMI-k)e_jeGap&+-o9bI2~Q=K}~l*0iNmU>@I54)6je^lBNw`h!4; zkLZrD<;&2~@r>^v%Sj&R)9JkONKSA$@XebUouTc${ z^d2YdH~Rd+h0jVe4{YPeWgfD5Y=g-9x*JNER~)bU`S{G(S1r8OtSkC=+y(>-Nl&h)#>tVq%LAFl!V=ULtt&WY4t9!y5> zOAWzqU7s>OfYm~t7P}a5Z|OA7!mvMoEuhK>mb?^&?kVfR=WC^}E6Nn^;RVOp^mWPR zqG{y;JzvGY98NC2=*wd@l}PWBZbt8|=&}@EEI%U3$oJ*d7}9Qk(M)$zsJ+Zsv#>2l ze|CXcXCA*pmCg=%8#o!nWYJBe+A9_3qmH)3((Z-XH2)J1(q!+{rQ@DX_ zgl4#ylza)=K=)&!jFe%4nUc;vYFqa<%_HlGJ}jqyP)Pj06G#6|JnsXag)Id5<%=M? zC{Fahrd9vFeSgxxZ2dAenBI%Fxnxr;dbxWz9nj61N;-u?z4YXcEl8bU&m~2prUOBo zPAUK24NaO>7&$A0UK3y!<@|akEs;M56j#z|e)0lPKjJi*;6%TFHq_(XT3*tWjQ@8{ zhQ4XS-qUgIraMWkLp&G>>xEDJz!AiQMd;{A*27AakJAWeJC6y?!Fs*oTtnyQzZhxy zsyvV+QwPel_iF}e(0t>!+h?=6#FbL}xhb8xb!ThWM6u68bB#7#sTE`<6`P^&@Ao)O z!rvV#-Ix|LY4|Y|2u~)Z#@sOAB(QzK;{h8aY90;n0yw6p)fcmPPxC%-_=Y~~$9OCW z6``q$OTn0~b+=`K$H?i$9>9fh-!##vG7&!k`A)y!=gFlK{Df{2Y7fOPHoVE46k<;p zliK@&5V2pr(=xs8l={5AWS@(ab_zIw@$(Xt(!8 z&@F>jB{OWGO`)!?3P&x|M*itTS7T>0U{b;STu`WGT z>~hch08jxEbb37&KTTac=Q2m=-(*!0c#Vay-1X?yNA{+&d0X+<+c!LLJ*#zUOKrN| zurB1)S;Qmgm1&jOLYLoum@a`b1i}0@DV6l&XtEScofAKfhzhcu(=E@D9gk@3=0@oi zY4EmRnmXP1x#Z}#m=HnB#Gax~)zyaL>$|fLc5XR(ID{p3DW@y-I7&_sZ;pRX%==rs zEs##8_cQ+0D$qMcQ4J&>KMmB338y?hpJqcj8*?;0^8-2%hlWXM#8g`yv z4=GBXIKh0uq&p|dF_TKo+lpZU1xU5iCv9j8zcmexLDS+r&W)L~(Vfn1MYd1YZQPZw ze0nz))Z!j9?-^J9FgO^J>n0s!Y}jq9oa*P^-$7DeW?#hPOnY&7GAhy5#_{YPF7%Bl zpz)ScRM7lvzds8NrV{P&LITw$df{H_OTY)H>(Lt`c+_ zKk@3uuB49P%OtkXbiL-Wo*MUHM>!%jP5Pg&;O~SNu{Y<&MRTKrgMe7H>OZcF{JR_9 z&lU~1H0c>lu5$_z^{z!RxbGCBswMx*Q_QutDaWq0FGz~AI~!~|GcN9s{uCIm@#=Gl z3fmtt+YVFN53-H*$ykqBso5xpAdt7VjY#pm#lysb?2qb z{peWZD|~dC(^YOj^i>`zrI_6|J2%{&WTL2|SZXzQgarDq!|A?-kP!#^zrBjnpL+~bg$NR;vY6lKP zhe(8_r`9<86g^wmIe}Vx%);-O=rQk&XhQ`BLzKZ<3*ZZW!oF^FfKJ!~h{2_(6Yq$<9To$zLWz4VE~`Zw`T%uf|Q)XkIm6pAgDj*eb^f%%;yoU#Pk_TN;aD!5R2?~%}xoLnOT|l3VHwt zM|SUrLEi`uH~TAie{h%aS24c9Ss*%%fyeM6kAD)`Z}kL2ij7A-J57LX|>HZu|s%_CP-i{NIvR~JymLG-mxin+4z;!8Tdni@na1zl5epFd^!p!@STE|T>3DjGP^^EC(Y<6pB)P990XqE&ukPfxw-ByWoC?w zP&4BDWWVd5^`sVrbn#5$Q`XCjgQO60UD)J_X2TTU`kH_e9psl@wu5{5YsQdX%`gy3 zg)l9u4&5BBLrlf9SX@DdClCghLe5T4m9moAxuG%goE_{MrY+>{{8$SMei0T%n}y=1 zYRfxS2u=s?5#7CJZt}$T^BTPxU}1|DyxN*&kS!W(wJN7@!G3nto&AH`JvZof6!HmE z0Uu-SV8zW`1B|Av_Zdi}xPo-gDe-o@+oUeqU7Bl0cYo`jd|Ll*1?=Cc53%en@V5u5 z7oa@*uX_N1)sO|tG=3ci|KQ1`B`%E8Lit@B5igS5qGIBK|=q1kmT=$ zqlD=Z=Xo4&ckV!=`w(dv5LeH^Kd>SiyD`0lY0@%`jh*(?$$|m9zZ#CriL}WD`fSjB z_hokkp(G>bqp=_1EMXesamYQK&g9)*602Y;rp*D<#dT$=pkr82eXO8NV(rH~4D z8%SAP9K6@`D>_JhXf6mBa4k>=D$+X*XQ? zmS?9T%HtAkg<_l{V_TlnaE`JHwI@l-R7zLiJxT1L@Jnh>rBeg1&(gSjavf-4>g9(H zU^4#ojQBtM2I#B-a~dVvk*K2gn$Q6F{J4JsV6q(8&57F&ns{S)kK}rc9WBOEXM(fg zE(mExD~L(HR0aK|qh=5MD|Hmk(NOucWofRIy91L6pE3!&bP-;Lq34KtA9eK_}g_NwRqlTh`^RZifZ)?0c}hbF6aPHF%F6Br}ko|A;A2ifvF~<1HQb0 zDS>#~K1>206wKnvs~p=M_G=mRPtDf&Td?0SACpO4!%LV}q$sHi@>4+Xr@%NC`tlU9bJynj|G21iO8MrRbyF}G*Wpefb8Fyy9#z=5% zQ}K9-?&4i8(E>27vgf-5OESa4x?6q&`-JnP-6XT_J*1~22YrVTW8k3|K+G#yW}EHP zsm4n(cJ%Nw)W3&DjDV9j1_P8m9mq7yu0aWMuhj<1SMqx1q^>clkaGZPdAn)R0F);~ zXA41a*0H1O6|zgE6aJxNS;J|XQoaZBwfcLa#{AAjLh|A_%dR%Ywvn4o%AM-OC~(Z4Etg%hI86Sbh|}@|B%7R7BrZlYlcbs zQ!J}zrum$%iurtT)Nh;v8O)i!Gy6X2XDQU-%xy}d@EZy+2Ou;q(JfKzYdlA8`%<-E ztfQxSwwor)=kkE-sSdx=TGhg%5_=I_EVdG%PK(Al9Z{R~A-&p{mCp)omEia-8$Dda zfEJA>bnxA2P{Yl6-s13ZScyX5jm^P|$UbNG^nl5BK_*&z#A`qz zlvxFl`(UtPo+1U?wl3CMkZS6eEQUG4t8pUeH!Xo&{9_Ev>n50SO%WtXEnhtE#7GI% z$G_?;y|QGYr@}ngBYZeKt#>J4Hui*q%kGF=@wwB4{A0YGxq&pF1lg7 z?6*8!m=tmfeJ^aiE)}sW4^!POq2#h=T-PLTC+dizt5dhaKKF!8hxzOg*O%Qt)}3dR zN2Dt%-pCUkyaz2#i60Q92i;($-VOn?jRWGNex`mhKT68}Q%32??t<}$Jr%S}(fc3c zeorcYPc#4Cboj46rWtx)02kUhN)U?fic@NK>QzccFlvZ6eeqLwv**U+`Q7yM_OQ2NqJ>QwU&Vf1Ac$J0iay@oE-lAgcl4de}GIx zkple#W{I5-$@f69#rivPIgn-dqb5t@T6*TA9TZ582Q0UT(*wEw^;&A8Qlaq;k-70* z^6BW%-Dc>QXTBG|bDym#I_KWfnlDd|O^-QWAvZei%f}A;(8coPT2~};Gwwd447m1m zJRX$KR-vJUkSj#RV1E!jj;=w1jN*K#7}!cvpXM=Q+J&#j!RcaaM)_ zGFEYCls>s#GLY-O6J`?HKZUyS+jj)O?U0M-t><;jeR=~ALpZvL&OZe@sDU$WIYC!y z2y;?fkdm0B>G=Z_h)AL^g`HNa9)7ip>e$fE*6=aYB`136sab9EokmL@aC)gw?{K4G zy8%M`$=fdG=5v_=U*`cfdlGahm81j39+*jyVeB1=;Wk9q0^eMuc`;L!PWl3EZD%3X_eqYW< zZupSva;f>Y*y{V)0q_+MAlJWK3#=lMk+76{9suY8rqvgiz2QH8_@*Rf<$IF&nG~RJ zDXrH)GDmsx;LyCBM}tvdheGrJhzps6;|ytrQ?cD(UcWkj2=@UA9ft>3!6A_8U`Bg6 zpP~ie9B`G2^*ZlLC4UN(fY7i*PxJ9=fD`qw`!xGBN1WkgOeGssoijr3u8H~}7{-Hk z6FrGnwT01A*H9FiIG;_23I2|r6{T0$*nngE6hRhuM`K4ZaXB%dts$dvoyd=j=x^1= zO@kp9C*u#K`&s+aVl007ejFG^K1JV;Z@FDt7aj0bthf12Hz+v!NP*MaL;tB3M zVP-Cqk@+3H1lsRp2<$+O4_J=zF%rA+GW5AIH^#4(;~3-)ja~T9SNl(w|L1Rq3@-aD$PcHI|6L9qcA5a}u)U8D;bA|hRg^d?2B)CkfHC4vIddl95cZ=r`45a~^% z1_%M^9i#<9LOhf2+iUG_-E;O?Yu~-b9pjF{Kak0+neY2PzxJ^IBIHWI;ocu+XqhOB zYm6UJ#rBTMYZ)1tMwKRM&b?-WQ$3E+(Oa;$whBpzNWSMTVUa5uJ#1IJtg-_vt+WsH zfUaKf*~fr&61^Pc+75ssC3~PRV<(B93c55M_)Xm%uTT$n;#`kbl5h3UtspYXOdEddSi3IID0HCFLEZ5GVd!7Bxqi_{n94QgUafK;JQ@FnQn?0Jw z3n&l%-4Y_iGLa{egtbD!cOL97llFzZ)I3fim!vpnnitaG!-7C|)I8}rpyGty?*kf% zRl28>4y5fTjUb!w`ycDzCj;PB8lXS-Q-rk-)$yrXpt4ni@r|@gM5b*~Wr{6sOiv=DOJ3bXJl{WsdsK)$*wWA9%36pO!^|N|O+K~}@?Kw0DE=$C;e$fo{5?QO`*|PfuL4ol~Do$9icq2G26w=;7p>x9R+l|0XZFhJlgJ?JFA&qU~3d zhI;SlXDLRHUNk!wPRW|K7AbX^L|Z~EC&?Zzab>(tNvx@%@?9Qyz8M}rVVqZ1ZlqU; z4D{mR&TY3?dE@#CHkBZ~Wo_xtgFMg0Mjst-B0oZdOrDlEHr9T4FV%Fr=8bv@aK`~_ zg~zrr2g=MR7pVpI5im2!0#gQ?IH^dWoEa=(NvgE>j&4)2TudJl+^jJQG?|iv(kcAb2)Y{QT-xz){2p@tJr9Fh&YuN{d zo}XVQb?WeY*W1T}jJejX`T&jMnAz}`C)+Ta!?TFZ^{41uJnv%Sf$gzT0Frg2Sfx>F zaDX+7;DNYi@-OCkq@amB1k!YD3edv&+6ddhmpdD|djx0~Ak4?Zd-q6Pg0oyCUapRT zlRbS?YiGD+vl&3f8LeQwnt^%YFKArW_OA3IqNDj^gG#!$cidKZ=r93RZ&0vv-Knpl zJppLA)>WZBZd*kI*6?rdfOunH{8Ul( zPP4#{KCF9fE+?aVTc&)=F|wwpvAifbVTw@cH27n%EzDJVAuo5~`Wc8`jr<73u-+~R zhBAoYvLyO!vR8Y(r>ug#DK{+HY3Q_ckKj5};o)2mC#^dtp*uP~;;e0NHuPv@bR_;M z_S4{2TjD!~Em|P6;Ya5d_P?mi|9Y|ilX344@;pMZ`I?40YGk~E?kYwhf~tKa4OkCZ z{Zu@vAOD)Ce$DC90&nxevD=Gj@!w=$P&qy|*j;-943{P4{vOPZ>E#qY{`$yvf9Fjv z9062tmU2I-T2D-j^@a9U=lH9cXpD^?a28WWD>B0)t27PNo6ib$<{42Igc_*)CdY--lA5c% zMMhyUQDQ*R2SjldApmmB$5dyY2sxe^p6&)5@G6fFj}gPi>3|_d7X<|hxwT^i^T{6{ zAEPz1{0>e4jT{%SPFF;*vOF`i;aY2ktik8f4q8jjjC{2HtaRa&)&guJfQ-&4Piri` zm+aCm%}6@1o+qC!GO2-RW_^hRZKccMp}-+DfmoYo5%I1524L_L$UIPUw?4U$Pj6165@c7AyjktZNB zWgL6rcS=8lhpXrlwAy;X2{*lM+9RJ>~R?MHzXMU)gs+7zz=7ZmtX=T6$dm|m}kQ`Lz#*)!DE;LJm> z8M9b(Nq#7Kmd3@UeCKmO!ljR25=1PlH9AptP?OY~KggedDWX;}5Tnub{iAT&LV-u} zS6@7o`qSRe%HruJ#4~eBbD@EohR!ls!8%sW}H2_VZkR8vl(4D;cT! zOF;;Xq_IE&Ncnebe$_uPXi7?K|G=OH01~>BI^xcs>bRF?vi1K_{R2^I`u&~ke>8;! z96syMOp{H2s*(A zd#@{>5psnadCbj<)o&r&*AgR^_jHkEhyqd4U?WR!&CO?MUvJ|h%rqvHCA8IvdTm7} zZL@fb?ed`oRY)HWY+`{7)M5%Ita7GrW~7zRz3=C13NUu+cQLSdqNt!z9>e*j?H&Bp z3jB{`xXAS_lsPPI#YBb5G!CkNrS z5FYQx;SA6DO_qZK-ZY4T&wAm(46t^rzdMi3haLDxt(>L$!wxiJQ}V1id7H@1wUGD~ zl8g=5Ni2owWlN-uOaN2l8(O3HUQ|aORN91AtHCY1@xo?5s{)=Xc>z_$n;*~oIG?39 zfYf}Ti=vw{>88jPBlA;77~zeHRnu@O(v^K^kJDF-w9P9h_3&>p<@ENNr9KAJttBua zdWz|NX+AhG3@fjrx2-vMCk@KKNhm#b&5fsZ&W;}Hefz8|*oY2sq_pwJEYhf*jr7jAwykCYr9m=WKy{HT~w!#y99jN^auZ`ntgeBJW?I;)ckV z>505-i-`7tBrr#llp|XtoJE3qeAQ%j`o!7qyOY>PWm>N}uF3A16{q`)d66hB{DL+W zS0Jq_DV}_?tw#58+voiW7b+>t`W*PRHR%aam7ybyr6|QGg`68}VwA@r~`2AhfEmJoDP5f&qshR#g z2>%`j*&RIck=+$6#Hn}AG^8PF-Su9`(3B~7{?wzdE35NPHFgQF)05X&4lf_%_ehcd zRGK~cz4cb~ep*$BKT0=o_X)|H?GE6!r0>~kSz(=AolaWctgDg%IW_&v>USI3_Dd=3 z|0&IGyHW38taq5mXG}TS$mE}^H+VI+n_2gD{d-B#%h%T^2MUX>+Yb5xdM-Yq*!E0P zGuf|)fE=0012oQ5nM24sgQ@#ohOyT&N}EnmiL_o8kI+@Ce3#R(P*IESY1M43DGV9m1yoe4~u7ffaS#MN(j6pW=RY?T) zPZ5}CD&4n@w;7GmATd@W>2q9(f+iyhp$zgW1CsH?zEHJuPs@uFo@z^$z#L@}rrO(9 zy{&lw6dMV^=DvrggvotDCd6^hOVXoI=glJ{)iZnRUkCm6SME(!6{!kvpOr0@q}hVM zKhsG*o-j3rq7wfU*0nH9@p@HcQ&Hjn2NnK5)Q-M6Q(_~@M2%s#d#Q%=QKXc~G3OJX z%Aa=*R%#qer(yO2kx#(=Luj`8$v3x)QrIr&sIekgv!MCD3xT-#NsDXDXIA{zt@T%b z@>ScLf`3uRzh1}(RKgNQ%6BeZzOZ)JT=3+v#b#FV!-!zZs@ll8@Sw>&B3Ath&F%O2 zpYJ;l=BMk`WtmU22>-F_x8njRp!y@pU9E*gBckQD`o{^T<{I&B+5X9Kliu+Z-uIk! z60Db5#^uP3LuQUjazd4D3Uh+XDuvdg(gz^y~F+h6l&7YVtsfWC;NTTImJTc zo_I_HzjIwJ4{?|Gd~E9_PErVE_2oinOldfAHnn>QI$b zoJ9W0S1D;~uwD@E`&qfC+ zUtj#>|HJa2k*4ZI;J;qJhqCpnf5w{LX}aV6d8H&gG4fm^!7ED|Qi>~8fpwSfYdBF& zRPsF-PZEx=`q}8JH6W}tR#C)8-n|MPa>zbUaiDlEDu0i~yKohr$To1PbRj4scFxqR zeKOWbe)0=+)NOh;H#3rB*t6dfQ}{~Zj&mlshuRG76A5Tq<4!s;q~+@5gm{E}8gu-x zoJmuW>6K%97jO5Y*qyvgWQ4QFz4g_t@O9SOskixgX}K|#VpZ-w_ik|1P833-2HW`s zsBRWrJFCDiU=|#%A3c~%#Z8N+4nv~cd{Ns^e^}&Y(s7kiuKA#I-Uk5?8*;1){2hbG zc%XM%w@Y)^oPeLqjVlsnZWlJ5C8(C4-;D{+T_Y2t8&LGZ^ZX_gGWkxjp1CP;=#6XY98V#4b`*?aD#~9e!@?xU zzKzVj2Dw#B#LK7`5xNbGz}QFl&0rT@SK1of$mHo)5DDH8xo9 z%w|*k|G9htnNJ1ZRu?E~Mjx}ezFZ#St7c?qGUi3CTw2(NpiTBqOIQF`A<9@&<)&%5&)F_8-xg!$Ri!Iv~PTa z|G6YtF(9t{-gig$!50g5<+5Pnk`grFD^2wDF_qWr`?~*Q;Z6EZ!p|X*geVD*SH4w!{8S^bvNdLD9_;N$ZK~ zPMtwP8{JJX>)t*rF2l=*;`{whj4JxC3U+!66~nV{sNOb&xhCZ5XT7-@P3LxFSXOy` z9TU*m8{9hQtc4z3wC zUj!uDPq$sufAXFV2(elmh6T?Lzo^z!^^rZ-5o@N%wgIWOXGBn=IzbA!Wy8~F`!4VA zU~x`RKlDgTuxB8wS%4%@^qTZJx3dSXsfQvZ@=VP3yaK$KmxYtCl}WKos>bmTr>1C0 zZ|TUDX9KPS8VvFY@5G20S~9bP!nB&fqfE@(QqmD}2Z1_dm7oup0-=9^Br$I{WNvJA z(BDYj@NMXXGUrNMz?&j^O?0Sy6HHdY;2s0pOdq88f;(O@yPZU6=5{M(M z!xI#j1fWx9&j+t7$W5p%<7T4P6-#!1lO-;nM41BL6KzO%I$^1-sc(+d?b|}4Mh?~= z`u^vx*`?XM=cGCj63bRjXZXxuht^Kvdnx)?%-!1@A2H*JQ6Ktr$dhbm)N_HjT1`rn z(9mVJ`zUmO=lnpYX(HRNEXe27x(TM4@`4(t>93_=>1K~yle7jG$E{E6ePd3A)Jo#F#H_Y!+0%X<+9`3=#9RedWx?aLK=*`ugYZ_y4}d z0P3I^4U9IY`M7_Z@qJ+Lmj4)l${b`#fdKrAA^;s0weBL4*@oCS^2lhI_?T7&DVajvgr>TiiP zqmgCn?1DJ|^xiz!;?`$?nQAz609LT5)p{V~2GA}4=ZXA#puEzQ0O%1gz{3ukn58C( za@q1mi9BAfX@)WHw7wk0af_~Tq4u}`{x1IS_vmkOyYtg0V;}SLfOZ4>{<4bf06bOr ze;(ieo1^YO9P#(ap;I(K;F{%PJ~EC8-ma6E&|ui~4DT3Cn? zSHZQf$4y0~sZ&g9Qb>=yFpWhmf|6qQPvEFOi%~aK92N!mDgn0m4_+DbS)S4a2%X>3 z|6?1#UUmX8sZx`QsoJ6$^-cc++}c=1kdM9k>6NCpdIAB!C8Oy;VL-o~mFLoS_H@U< zKW*j%(&P4Lvs)^YohuMP;9Z2SPoa|*vAu%4ed0vPOaiSWA8h3+D&MW{<@#}Q8Qu;$ zx&-_|o_w7dK@W(Rp{v_%fEhtb%0s|D?*|Fk1z_?iJ`mtB)#HD^jt6uQFoeF0r`n5YDeahIDfhPbmSL|Yu5WUN{yen&YWA#a;F=+vhZf+NPVu_QlbZ_?o(Ra z260C2G>p;oO0(R_DTp>&k5?eJG5WqB=2EW7C>(nJCUcyq6WUbzDMi)$CsO6Z`I{_0 zTpGE%bfo^ZB(jsb^zOn83G@+A(zt`#Tz#M?{yy)E&V(dC{)q+usfI31n;&V*^O1`u zk|3wNJz$aDPkU!_jEC$r%zeKXDZR_qa6FU0;$jF4F0GA7F=}a{&pS22@OO?sP4Ae_ zgO_E#CmWw#EIuQ1_{7sqG3H?<`)NkSFt90y_Mli>M+}d;Q%0 zEo4xgU&r4k^!oqcBQ6t0G~LVCmCIso7p+E^*PW6kx^Pw zGFBDm`u6_UtoET^{^B&z@O%8mU&5$d6iQG6tHY{pP91)oN8r}c_^&rDLp-fQURghl z;W2mSaOu3e7NNAD8mLQgRkoZt(rs1oSxT$NCUqT#p=4*=sKI_iExzWJW%riaY-8mS zs=T^}B!2h$i$LgW>qY;Vm~;G@xoMWqmFkvf>Id)0>;G`2*Z`+AUzV2hchj@fkxYD6O&eummSlTl}?2eCmCi{6wLecSiAb)?igidU+2+}yM{L1F@8kF0Iic)8*No<2R7I{uD~BMP*h zcQF^nbE|oY;TNSuZ0F0@Gm=d#iTXA*+kTv zbkh6gJsi~t#BWVjP_@uH9PVJE;md-AwRO$+%}Ik|r+JKYD3xjLQd*Fp|G>+|6&b$^mpM60had7u96B5MT6mOYmYl$TAs5Z{Af@&@TNK4}3bi*Tp zp*kyOJvi>K`U*tbp*L<0xdEL=FlnsNw6WMOpXH!C_$e--eX}Iel)Z&|aoj7CskXda zr%g~s3bnJfsj5e}DaNVNDQXiW|Hx}6Ulb%0ll@+kF(RPqFUaOdTJe7(o8^#4v}I~K zI-=SmBZJBy`KP-a4`eC0EfZ{Wq5`ya&V5RHM^-nFtx7|g6iJ+3O8TN3+9<2YW(%5} z`tVJhn4_G2iXCt%<=UgpwWpWj#ro%^e1ht&n6+$ZyekVo8qVJIZ~`tx5uPhOlPe?d zkbJ*$C2epVTU}nX;CW}NfyQ}Wf>oTiHfVdkD4mVHTHuALasjWd-2hg+^$orUZg44(o}f&{H%=@fjL2O!p7C3TMbAj*Zk zB=T&X8_*>lzSA>Cs_a@}>->)ARnmf79AP1alG%A_5`nG}<`&Tg%;zb*p1%ticq&nh zcx|A>&Mfo2W(ychH@#DiM%9Q&5;GB2jK4fMf;!|>^w!K%f?%Z2Q_t8H&O|Yx-JcH& z8uprq+*2-hQH%*bM>idxkSQDRo?va}0yA~w704>hEP7b#nSQ^e34a=FT zBQ;d^hezRJzDypu8<8(v6MG?H*!CvtjFO(#N-0DWtg;MgS=(q=wBVw#iOq>GE`D|U zO0Mk(sjJuWLnD2;*Lc51_9C=dSs2m*EcO~amaVV%r)g`+0Hi`jiI}-gT`_$?8#h5- zVK2-;)!MkSb1;a1CCuPhP{mWhaETZ8;b2(JK<&CpM$*JPF6@|uvku+*Q@_rv#Jzz< zNGCV}(B0lxUN-l(-!cxGYIu?|FX%MCD+!8Ed4ETShQmGlX>iz7(%VOF<2?zoiz?m$ zqQatGEFUO3gvtm+iyQ^8t-Kq6RWtFK13!Ik|s1^?pm%Aemd7f5p zTf~#4tbK#&0R^GHV~aNn^(yM&KCfF)Uu1~!!0@N$s8p+6_IwFbWk)-^W7Onz{`T3FedD0$!vU0mtQ9h_Zsm!oGN}-pH>%ilGsa7JL zE}I=7`b~pDK~0D9uR1nUU7A{u0nCWbup)E4QAdAf$zu2nFCRLX zJW@`uGd-@E#aDj=kb%rY-?#yIf+Md=b>~7w3jJ%1#q4jEX(FPY{q13z)t-|HVQ;S| zH(ju_yz?#Yc5+1pe<)b&m1m^mji@AkGW3T~LFtnqk zgn;8Yb=^ql^JR}zD?0w_p`k%t?RI76T-}h1+1fle;(zH{$kVNl=CL*@{U+;|_S|Is zMzUxY_vmQB8bQ4sO3=GQ|BXzJ0T_>G{zeT5>n?ZoKwK+q}Cx{z|R{!FYXXq4V*eN7-6M$~}wD zp8O`N5-Hu!U;e6vUFs_}6^t*=>zv!sZ}gGYK`&J395_VFQe0#26&4p^j#)VptdMYzdr z{_tz1{x>wp5)6&)(v%Lal|UaC&s^Xt8KDNrxNdj(zQfam_F0p_hlvo6G;^wP)Ci#z~#x9fS?(C+_ zvzdES7Otu{> z-sRCz3QTsno5T?WsTS|~ruLLkt5A}5Ex37B0JS~@W`ifuyoSmUwq%M{snTPQ+{T$K znCb~$Wi^q8o5g{PC0nIUJ%gKT%v*cKSvd*yhK9U7Nd@e2J%h5MApv(?5K~2>X56Ll zE?6NW^TEDddVRf9N+B9$=Vf19a4cVgmDw=?nq)cZ*O$};ys#Izzh?3+rr4ZXT*vj* zdeh#w7C&lP*53W()m)fI#v3#5{UZ?!Q|m=E%3u#X2e*Q5_CMNhfLd(OL>tRCA_IRG z=6;F2qowu%BkduiWu(X9`m0|$`>Le=;MBXqHis{Mniq)mqlyZx(?Qh8AEr|*nBf^V zcLl`?uinZUK|nRCrO4vGxxq5pY;hA;K(<({SjoA#NlFh+tQgp^OWx*v4uq8 z^x`|alj8t@zF(~*1c75SzL}NjLt;=u@qJ5sl7`ut?Q=r6>X}DkM@F>=?#e+RmqfZY z@9kGP@D(O+XHvGI&8<58*6Gv*l+0G0i5%iV#f?{ zQrCS=JCneSgu_yT69TFwYn1lQv9Cd{{y`O;@CDml1LK^;h!h^kv)u>5yjI!zVToZf zW!i5!6pyH2`}FQ;v0uz$pogUIAjWi$Rmk5k3)k2g>21q{h{1tvQYRJzeYxRS6dB7` z=Mng;f4*jG^6R|0S)@^7zg2cfS{mqCKBEB{e^1uNV<`^qg0E{4tBi>*WX#H6S+4ma zNRH{fZ|c0r*+x+w0FIZxXS6IB6?x-BtL}nJgE=$K@U8E3EFE&ss5BUq9g1MjO4c?%Yq?s?E<#^MvL|>d@g3spQJa#8gW_*GU!S z)ZlEmh&O0bH`7`tL2m+kmely;XTAy5sm&TFQXH6E$Vu6pbN9Khou?A>sIMqNlmOe0 zmA^15LP0s=M`DdVQQi%m2g5BzZl!(1-x%~k$74oZ@ysNV0%@q3yMi2LWYOngO|&&P z&izS^$}6j=Tk{E4I@af8IgDoF2b-?bjKfAeZth*b$i^+?VK9Vy?GMPr$j^2@_l|uRAxEiu$fn_uFyXU0lv;phX{r3uJ^GRZn`+b~-f8BT zv?nSg4|2b=hfyyqjnjD&`($_clUr6-K-_tw@zY1Vzv0p@ydM0X=D93eZvji<DQ8tyP1{sUo3wS3(nilTGcB0D8T!=%ghmlkIr&N$~gHZfH zShs9M*W%&L8!XWw)_Db)2rR)V0zq@7OevD(sf%7gfSG8CqYvi*NEcr z_5^rR=ib`a8mEH^Y-n{^$~@vwcWQ=7#N|h4ET#eZYN@;-)N$E)s9b5ioT2e)td@40 zfq{2a*SDXcQ*2IWFXRuX>Wq#^U6uW*pr``%TEo((N15`IM7_1XX*jV(r_Q2TKoLDv zp@ESwC&MdFrZPW-OP*|E8yR*P$ZzI|T;etGHe2&yPj|C<3OtacYGhk<-4Yg!8Kq z<%Q^Xj=Zkb`IS#Q{OYX*I(pm(Y2U>zervX}H7RDtp#J1pi>J{f54PSL^G)kr8%-_v zw`hwu7KN6bR?Y;zGvlZR*8BDGAtOI5T|n|5`-g@HZoCIH;ZluGm!yjPK{?SsfA+Ty zgRYyr*mP*Qm;3=v1v#SKca-6S3l9YSCKG1NO_|T@GAZ0>%wf5N9;hzIGj5ze&dsDK z($m>snW|#Q&oH_=ECbSjob$sC>W}M+n1onjaQG1>NyaDY3cO%}+xtGYF8i^5g%uy! zZkgZAx?}F>Y~G2nQrca~wda|C7`|#c3tn2OB*x$ee*t*|tTKp&=B}oqRlLi7HQl&_ z_}bLSd)H;|0@`YMYZ{yRrg=W2>(?^6RTb~9^Cph<`kHX5~Uh7y&P~H?sc`!uab~IeKSWby1VOT=W|Hy zp`#8bBjowd>}#Se*^junPBWnVzZc;Xe{DA(il*H70%#5FPYLDwMWA~FYbFP4TOC-9 zS)o07h-s2fbLDP)wRyrtu7G>_4~_=2ANO4@S$p*@)j*93W`L8~ok+EPHlB_$H@F6=r? z07JQK`i*r2JFecm26R1Vqw`|-by8l+!K84#^bS}9%{EjXXz#~Z^7525K%rJ^e7xBa z7pzi;F6bA(+Ip$?FMxGVLMeLBTSK3U3KSk6U1!qgw&_qi#}g<TbZ`dQ=!bOfH7>+{;?eT?(OUa)lIxGGEWek)aaB=SFKnr97w_-QlK zzt<^zBCXZYr_wJozsJVo=3LM7*$4VBtT?O<8zYPaV>}C1GlFGp?tBZav{dmSPccu}0SQG7b)7}q7-YJ$Y8iLB{cFB}!_%-5%ia5{&DJ}_rc zZVn`+O3cf*K40rRCX~BVIyhe8GIR6AO{RvHdvM;>Gm{AHp1M^sSW_t)xu4FI@~v0w zQ4bAOmYl_F2U*q?*;}B87w&$^rN(Tt#;>r{$v1jokjD)<;t{G6YBkQ7q8b9Z?Lo&B zV#+O!PErNbEdP00%+<95t*WYMpvA)B^2w0h#!1&k%N$3IJu z$s8`~QPYZL^6+x#AKn$L+)J_WaAckqad8aq4Crz)$jj*c`R2&hI=eV0^@67z&!Q(* ziMP$mFiFECWbt-a8|+{|n4}HomJxNQ{{~DdK7wVwPhCxpwgl3DHO!aX-&*s@#CVar z;7rB}CyhbxzBv^-c9uV=ySN)CY{94WrHfOIm+@^^h*=Da%#c)6TlDf^*s~nkvwX6n zxn6ndf9EuxYAp!vi633u(Q{F)l-^!6)!YEBszIA4(mR&0Or19Xz~yLZbfRp*g_iMv zoNZdGy~L^4P4{jKLj|Q;Rdm4@)&ww?l;)<>-C>XG9`Q z!=fYAfVU(%#qdSFrvF-CPW}hklXC}WDMKoDfSw|3vtocF0-?7OPmCa0u$?DySfL$> z!FcIWW1ISLF_68(RG{0Q^fV)H-A!J@$<)Le_R^mAD>(?}3Qb<&Kr@vu@ns55P`%MGp{h>#0I=40x>*q6iv^#J5 z4>i(8TvL(08l%uZ7uKj~VsNc27sWE;wst}RLhWA8l##IzVkjkSZDp=r5&v15Lhsk> zerVWN)_3ZhX}%Owc(Bm$F)e#5La{ z92>V%KJ^Y;iC9m0HKc*ws)fZO>j@Q{7+T5m@!WhKSG=U}7{1E--10C`B`Rb|;*xqG zGNf!y>X#Mt!~4O<)9~*$_!kaTt9oS;g8dN*kuE=Ux@BJ^y~s6kH(M!sX&z5o?bTpA zI5x)~bMG9dUg z7mzyciCqz4>n1;@;Wxcvifj&=PPuBoN{_Ae+$p2Wl1T9rg~~d`5{W|0=&YZ8JvFP1BFUGwEmAp*O%ytO%mc$6L1-st5BBt+6O6+SDWC(W=5p= z8rCR9(BH z^ViQMytOoVK_ZSMWzXjA?mv{Y$&3a8|ukyx9fz>3wkKNveHY09F^b}38i11p_nIjzah z)mBt!Z#7~mL>O&%JxkI*L=^F9C^KiYbH31aywsfeS%MWum-23{cqRQ>o>r5T_xMrD zF2>OY3GKX3TK64mb<`hooH&^okUwu~JFLvqPi4J^c^i=1ZE-u^B0e*%K8AbYT6bnj z$FZwU;>Y!#HN2KdEI`!>5m9@e9=X$B-fNgGH5ExL&2FD_e%Ks)!Wq@QDE#(PKz2r_ zMLv&6B>&z3U-t9X>mm(hIuuc$ZMkE%33MX>EPnJI9PBwXK@5uZz=a|gx8HX!yskr} z&QLise3o}J5fljS@lIdm_l3~Mc8-W~`bx9Q>U~x=OS`Bsm&~AH%%W08acygo?FZ?5 z!JHyd4i^zY2TXNt0%DGI&*=SmwGWN?>)C!T0TsADca5oHzc|_mGs7Ev^e%xBOhpAw-QNt z|Jp`4MqX7>PEnP%TFlK&IQw~9I7e81c8K%W)uG3956KZ}r-JyVdXWXnUeidg*vy76 z1q7titgqDl8zO0IGVK#5u>oyM%|j+G%|{9lo=ST@GykF%Q7xaw3jQ<+#o-)3J~IlQ z{9G9OlrgIgw`^xL;?o)$JS$)d%#m)2-|n}sl@8&r4W`;pG7T(6Y!yzNK${6rvyDvx zfB@5L9BfTt4w#@eTl@jy3iVPO;bQXVn1+UHle2hkhgIeGFs15OKi*wc$8y+T)HS>4 zL;*0Nj`&Rph16?MpsMQ|_z7+o=)TvxJrfUtlzEg$b&O(o_O!Mf7lRGrP0oLJR7<6n zyYqxYPw(THmVAj*w;M%hq4aAO;lry6uQtxC+V3Ei;jMrjpe^fYc$dAH0ObtymuhUn zVkTN34drpdw;8sm!TiXdg*9J2#U+|2%0NsIx7Fzw!m!uI zG;*@8|6tsx(s9E$zJ}Yf#|eaO*z?39YswyuCvn72ge{rt+ZJS9>1k5V(WyIoc-w27 z;-_2IlaTTZ7VRYqJkY0_`x)zeti3L=A0x6bUtp+E*m?jIfh@IFHakI)o@U}G^*eL5 zOID>qe%)r0hw$_2qN_rv>hsCJ$$-2W3Eek4gathXVjM=)=rF^}9zlRxD{I>33^-5? zgig6uiPc{gm*!8xo2c;SoCT;`W|#cq3>=2XuL6gHQ*dOwv zwR-89)93(!fiS{vGS1P|(cQxWT%`F+UN!2UlcMpTQfEG4B6R8NGyR(n0&99Q#@;65( z?H}@!S*P1B6*AbBZ;==a-S6<)a$S5R=$at zwr={x+vz!OmJLLA-*V$gdOp-UPpP$P;xnP~c~Bm8blcQErXhAOU4XS5ldMAG7&nTLa3|JN#~5-N#AR>P`>Zya{QPJ8_z(xX3_|_^aW0M zfJ}-6XqV$`#5jxEo?xCx%7BO#3pI_C^==*LeeA%3wOd3w1M=qv?=!ubQI+o$+Ev!d zFQ)E_Csc=Nau=|?dH}iyPE9|l4_Y=Q-3H_Uq~#&P6nGMWL8thwFUJ!7nm4z9lU)S= zB2K3hRy^pd0cV#bRldr@h7@te^;i~WWCDSdBM-!M9DRHo zwK$%)0A_1d{xCY)n*e(>VN3&Yeg43-4~mC5g-x?LIwI28t{mQ+pE7vidl|Y(r0=1Q z?zP_g)L3o!+`R0_Tj#us@>*eGUd%(D)t}+nF$&u9{EsDmEwFtcwT=~nV3KKT4-cCB zO84+IgK!3%nxZ-J-R5`HDmIa#*)Aoh>` zPaQW$)U1KTG&f_6DIQRx@okMvYd6qadk?PGhiw^_UeT4}Khd29I>$~hEIiN}99%v` z-IQkIi0Ptu9Z(>nV5vP~OwOjCeJ#s>#7vz=Edim+Nm~wKe$#qa?aE+wx$2GLXjR(K zQc3pc`waS5WzV<0*}#-|AFD$_o0U@Y_BImems^|VWjOWm%vhc}iHN;{xtgXi%=mZ` ze;xDE?0403oE(=7d&uIILH?4se55+*g}huQ)w#sg9?>!574x>h zeXD024q%`jTT=&WVjS@Yv`5BB+W%or!9kIf80CJz@F`&Z;!6mb06^7Z+_y~BQQIiiW)r;sH!licdU-U zf-0MFc`r75PC56X)CJ!$+_wPoGV5+zv!yWGz#6Lhfi}l z$!q>imgLcg1rQen>~w>KD=~OuV|oJHpehzVRdoy}|9}-GgqqJ*+_2)d?9h!?j#5e17Tt@cZQ+peNqM|tp+j*)HiTG@R9r`T zr5C_1TPzR+8>HE--Ar0qtDF}koCs47vB(c0xo#G!vUJu!!%oA3ec|Du)KZNG4ux?wUo<7w&Ms2>nYf>yr{ zJwaf=I_GSQ@N9cP=j;-Zk_NdFLZr={*X07_*1!fTG%d702uq-MHuq4U>dGLiA6ooX z(N8Y*fCgY@-jR%)mZOw#ta#i-RMd0 zjWpa__k~#d{CiW~{=p0XSNU=zz|b|G`^QMiYAFMKA8miZ{aT6TnFx8Q1HPew%dsP| z7n3gxM4$DaRDHpgVU1IUTVK@7NG2zhvb>N$sI&}JTm`|JjR`Zg{w40=f#UwDtSZE7LJa618JM63*FI+J z1vJ$wK!{*PKXX)oMCgdpfykNt=6xKdCVII1UWKCULe&ssec&itp>5>3lHS-8P$u{q z=mNXp-IMo37OTJP1;|WIj;pX^&RgC+JqrLvRsGASK=+niPkfZX?%tvjDV;;Q4PLXc zkyp+BZbd>6SAt9bbx^bXjppb%V(vYon*821 zVeE<^N>O@Lnsn(3gs6ZtAyPsWg3`MP0U9ONV2n^z3=eEl_bzF1OAN>em*XHOQ zw}n}Ezu=i`{xcT}h*y5k=r8bm8rJ?));9R{r%RVB@xc+J!~A&#`5#mzA{)j-G#Q8HG&_t~ zKyK@VRl8mB24a4j(uWO9wAn`ZhDFwdLY&{yo!=>z#oe_`><6qTn8-w!kWeMef}K|T zQJX_FH~8y0ZFz9aFMIR4Q{&xojmYA~*}Xd?LvPzPpvJU6G*3x%Dm^B7MZ;U&R3b03$B#;WdkXt5kmK;+{m3Qj zAl`wOZGriGHK{CP3m~!b1uD}uN*lUwt$!2xh6~g1N+F3Yd)f*o8d&@Q0=v zUX2PV&*|SoQ!Q})luoJ;zz%!tX}e6IFKqP6?*JEL**K$|ZP6B&U3<|l&D|PhgUnf2 zEc$=0IGWZJc~nPnx~a#o#@ae0j54ZJd^IdwrEXrRi@1H2-YN6zNpq9m7*%;cVEt%# z#=jh}4)9-;C7Sto5|5|3Q1z8a&2m0?ty7hPYtzo?=slsHR=#rv)n%(spt`D;6DsUS zb~c{Mu&lmQk*NPz7pQ|417Lj;>W*71imlPEB*4e5cWZFcHERnJxnt)t=}b;(Cl_3jNxYs8@xV&nWKNf$9R|FIBc?JZ@$_Dh{tg|q3Y>~tGyi0HzZFn0Wa94LA<0z zm*STzD9ZA*@U!9mkK0P~ria`$_0MEfF52JA+(SIU&_SY6eQuvnoPTI0QweOxAr8)d zEp`ipZxEYJT+3UWd8*g4#ts{86I$y-i}jtgf|)YfE+OAfHHe$BUqC~G&tR9O!}3CM zbWOCS18xs62$A;90kztAuf+z{5GA?O*q}0f^vn>jpXBn`h3DaIV-vh(Cw?u@UTCWA zv$`g@BW8C^2&yEO72M!E0n=jTEeJD{3^7Hh^CKOcNY}`-&?ccITWifmR+W#wU2u;q|d*MW&MQxeONoyJ-6h>xcqWAXKxXcs^ zWKi)=^FuE7&hycm2^+cPc^3(*jg-CssV#=(Ym{%ukcAZ$*YrTOdWA-|5w_B(M!7bl z`;im+FKQ26Hp+%#n;V5|-RpfvBa7K0l69+DNr-M@{!9gUqrG|nh4##0I|}9O(wpur0e;8%OYOYq7uINA#kI{LMd&MCk7`J)~gw|JxDN=wWO zrjcBWg&FeR>&2()1-;!1#vZ+^?h$=;K%`c2$c9P-W3%NEhn zqI_UgX_+V%)hBw@<(zGSANtL1maFdlXDge{VU#t_=dVW~iWjw>-UzgISJ4irEqe3y zihx_h{X;l=U+Q{TU)lz>aAVy|GEF8LU)DK+i%||PO*M5?tg&swF*jx;u^H*oh;!;U z3AOTk7AgAm)_r|C>>b$GsyK18e6g1@-I$qk*uE#a3I2F;P`vJJtK4+h%q05lX317j zdTwGq+oYVokwuC1L+vXvv3Z=lGPi3Z!(`rA{oW4qw6Xml7p&BuWF|BXRc$B9P*!l5 zGfKXme6_Hnap!775J4}B>-4a;_+ZG6;H*u&uUalM0u3jd9Qtap!U zMH#ul$;IcNw)E#k(#zwbs7%?Ev}PSY(~Zp%s-^$i<_3_&u=&9bW0F+0Y+v8>NnrH) zw2Qd+g4gVe4fR8Q4!N40qXO&vFA=RV%=JZYIf=%mK%wP5r4X9%Hp1}pADX~?7WMuo zncJoP=?ca6bMj`tmA+3i&8;FqXT-g{tBpxB?4M?av!@w<%cC7&-Pe}G{4x~8V@vZ~ zEi~mX%$;IrG&o-t@MG)~2~q65dqOqHlz^nTSdbv>#0;!|&G=>2E1Q35wXej6Cga&Y z^E$XiO zeMLjUk%rNPf``?RZSj}xaVuGI`%kjVZI%^m$3}^q!RL7%J8jEI^xiae?5}+kt>1Fi zLi>DKW_T(4wvxFEFvGYA5M?W0kN`Sl=z=XU6K#e&xKeKsJ?CHI;~*JuKoNd_$0>l4 z_CGD@o^X|ig0l1aM*qb9E4^()hXIsn^Y9v;>15}b@%H(w*o-i#>neK7MQ1%GpF1p^ z%(^K{e!Uhp0>CwfdQzjNC^7g_H*U6Ps}T+Tk6i>?CL{S`H`Zr1zq=F?$If_L{{L;F zR~px4MsNnSzY+WNq|iZ*M&O922pCl>DQvArV!O92l8zp}CzKAxPadQw29K5ZZiLCx zx%eBNM$4#06(=SvK6>sO#>y-FV(`|&6tm^{sgRVl;h=m|@c-%)u>n9%lXBYSt>dGa z?yhuVLs$}Sv|iF+!lkkHB?|FCvQe@R1B&^pA=1bcGN1+H8YCGp|AY-^`asL zcTnrKxsyE&jv6yo{L=2+e1v6ozqs%&VJTAa?dOtWN3E)nlBew=F{5@L)6~JQ3r{y0 zw^R5*q*S-fSduC_;4)EZqjQN0p#&9lSskx1B%~7reTN&*33feql%)(;_?puHjNe-j zzVrONTzO(xt|8AMR7Q;F?CZb}1bYu1^dw0Ox_opn6NNu%PS}7Bi9r@R$`r}^j>j<# z5;buxhTKhlF22P9%kst5^0U>l2VC6BkTLS1-PSbM`N#K{+sAEX1LpFl?{&$q7Fygl zWwXs!NwA7BF1%&T0YU;fKTCt2u2wPD7D5j}G37=pI8aA8snI*JbtY4eoKf|{t!!ZC zsHksn2JD_OJL%B;0H*gzx9cPYTNt8^IlDiin+xVYopi5K|F){~IT083;i6!4O2~(4 zRHmBb2FIrk*QIQUPL|D+`1~b!l0o5))*^6!ChdX>n;#wY={2&|9e2N;_ZU)B7W&+0 zdHwUl2H8?yjn&vB;Yi<9+T__l&YX88EP)qWS?}(y7EO8ArrYTVp^}m*?QpoSeAlxe zK2d*q6__V%WWZ2&^ufHkkb~n3CjAlR+uI$hKN3PlILHckt@B^93zbgB{xOBFW&=<| z70TrFN%$_xjUs}*zqWSV{`o71H^Qw)l(R3|^~(G#t9xd4rWlXB-IK?&CGC8)pgny< zBgaOTi{{?9#OETaEVmWzsr1*UsQag59p*`QjQ2*-P2%(N@9t> z|C^5S-#e2VCyj+(?-j<~U(9K|G6tt{?mQV4zYu$Gsi@$pZb{BBN57b^55Hb&+#Jc~ zx?#HE?H!Zy{EYg6bRh{)uYJ)Sqw#Ky;>tVbL4p+u|I&)xfkR3eRK)>ZM@bE|JO_#!;M9IHJBLrg%$Y&Lyip4-*30rpzdbWe;18;d1AIJtI0a5aqdeiLd|mV@n_@dk7%R& zXR$|59vCx<`hbq_P>#KmMd~ctl(ebJROsZOK2S?F`c3_zQ9heZbbwPgCei zl8|ABy{PRgA)q5zevkSdc_F8nVdF_^xANDukk`aT>D|VgIBamR^9_^VMKPN1Q$v`< zpgcnIb@scSk-3_8oh-oW5kA)YTN37up4IRc0Bm^!v4JkjOJ;5-iU(q*XG+(j(vd4? z=BB|FU^~P8Qf*I26LgI1#Lp41`Rr9E=-N`1=gxv2Ebb|5;hWR<%lXz9K1+g>xb7?w zv?Xd5B5H2{bm(Pw5(2GO({#!AFDhL_0k*#cP-T~(%c=a_p8zAlV5mbG;CVu6S7|(? z#PuKB{529{^i#&o@=BPe#S_HCLO&&;n>E+*vysL}UiEifeM&EFYU1slg^^PH#E#*L??%LVW_ZE7~?o2a7E9wN-UgZ=V3-B5tHZ1Z~N9-ggB zcuJi&0v0SEu;tuX`H=U!gOcS~$jazX)K62Y^JZ`6F4Jp2Zk)++7qxcdq`XcJup5~x zE@rov#W*^rLKYNalTK-gUsF!~-fj-FDEQ^$UcFfn$h!%zjt<`LKSSk?Ao*@2TG_YP z1gUjIN|V(QTfhny^_k7aZVAo>ETx?@=!4c-51(VORlof5n|KX>48Gf z*fL+oi(J78u{NULmBt&->a}-g!G3kSozbB%8=XY;mnW&pQ|hR$nX+pVyVfh~<cLPa#-V{BuCVKc=1=rl57X_0dc~x&pHH*~B>qdu5-nq2`n` zy98Irkv3+JaRx5Ztgr=*;_9s{Myt8_Sy4Az199~Y%O(A8I-jR!-L+}~FnXl#$tWzD zHub)HjZ7?KzqXh{hXqQyQnV(%Va=6?!gWbjc)9+~55Z!!C&z_z zfN!L^`HoY;9?3knEnM1}9a`d0msf#Z2pP1owTVYy!7U*r8x}d! z2OL0cyPKj^);auQO=_gRLB#MykfV)FFm38L1J5mCk=t&xc8P zV{&w{mbR8+zCd&+mwCaO<7vs}xDC}Gm$|c-2FF$;u~X8$zh08!-cmhwx%}E?UHeI9 zlpZCcJSG;|r7dWz`9{4{Wr|`ON|-g#>s>;zq)EgW{AQ zp=Y_fzS}v{#SL7!x7?Wah+bzF52gcwQ3*-ivrF~*U-8WLUrZZLD$HW;>W%0w&V?o-g7Z=(qnHQr0H5<5C~5KiG58`^xPK1SW8W2m{i zke+dWO2ewl$&OpIoUQWf!wYSWE*SGFxd1OKSjG$&C+s=!|>IH>!^s4$ZRu&?t1cP>QGsE#MkT;YyW5=YI;id5p!GBWwJQpGFb>p68E^65wTo@)_#ovm|%ig{5Ytd{K+TU02}`%(nns?d_DB zu4gXh?jn6C=2Yw18&ya*1^sZWdGVBj+!v%A$Kkcs4}I$vQ`7N{O8H0A9=>$1r@B&~ z^gv$@cB@Cw*9f~lGyof37rvRFA%FbJuXc+9Z-qzr@9fG+L^-z#JUQ^%n*BNl%aBU% z`n|(wV7bk2y)0pFM%)jEf4L-+!AyRft$%7Tt~Nn*ZM?HzB88+y=~Oc2J$U7+vkPd( zIgp}P!~!>;n-uRNT63~nfZpOmHy5`seR$5}YuVlO*Oh`#_YLa*>?!`5y(llV6?3A2 zp9cQor24l`6|QRc1IJ5b2!+JWv!djz{C3zdaxJ8Hg6^M z+b*QBA4qhR^Lmyu!QWn3oXmFeUKY;@%uo8FRgR$1C8~s)jQOc>fMfuLyA#aqH{J%w{kB6 zMUdG?vQ=*S-=VgFH{}E%tmv#9UD}Q<%P*?jwIt7C%_k=^pBt2N&i>dLsMHHFR4p&clFW%FT}%BaQ~UZ# zW(JgA=w3!MFymru=A;x;ZPE`@2-KuDBQG_ZrQbco8!z0N4(sj0Il^-b%ITA4%mbUM z_RlD+>T<@u);kqkCz60gzR zcuvrKH{vyDJJu}@+ZXaJ-~r`9*NUT~FX7bz0*Z7|orfkz;rzJ zq*g)VY>j=A;WI~YLf{Qo_cu6*eY-AH49r!2^t64~k0ibaty?6ejW#Z1-{pc2U>HCQ z-|i{^9v^NL!;?;f1J|{grs6tYtZ`Fg?W?-A>@==~d|;++BiKD65_-G!s!2wLIR7#xYYGro<%MfmSQbVnTMux1dXLJ7jc2 zcC$BJe-qb=Ax99ev!e^D8e70Yc|X(R!m%i)xPlpDk+W;Cl`jeVs@l8(k|CW12?nwE zJah-+uT?uL`yTAslO6&=!s5Fipn=YG0UBukXky9B)q1KFF{9)~<3j!(l#1ZWY*5m2 zws=3AUi=}(!OIKVqmhVB<0z7~9h)2pPvHh~2?J_$QhW?Q2^)UBgkH}<=K@9E76$yb%n ziZ)0*wUs^4wmD}|B*+^kcn5DAsm9Z`T{+pGRNO#ceW6Vy=$z->41NwVN9d@aL`P` zYvgrC=@4|Om@IekW5i#anc(y&|+5;h-5Q=B+2j&`gNbT zhd41$pk5pARU?G~?Dc>>stGu~;`o1Td*aP?5g9k#74Kl=W$hq^cU3MYWjfhDmS352 zjWWWF23e$Ij=DhnUtosWAuL>1p=YpP)ozX$f$&@)24Iwu8K6ZO?m;B=%#_Y@vAw}l zgGdgQ+vJurm_u1=>(+Dv)Ns_rb#$7cb_eP0yyQNtCaWL}rDrSZ(oZTdVN?yfSp~L^ zF{&m-W>(k4>hbH{DY-XRm$grL8MU%T`6(yx9sWLH6l{{5bZ(aGFf*VKzrMtCuETjs zLt-m#)<5uJfxB*GdqHkif=+=`v4aqeO=x^x=-&(IqqyB&W$cbDaDWU9laMG8@r2o4 ztFK5Q?#!+YO?HN*{RN(doJ&%a>|SeZAyVXUU-L@%`ZbsDo&b2TcfMlwMJ?O=9%D67Y!PPjaK=HJd+O?;TD{Dpi;*Uc%x6zc$_|^{7d> z_pFb<9=Dy=ZnKPETeB{1H_$i-V^LwL*2TXrvd6DAN&fPq?ZAi?t%+7w-+TU75jEQ_ zwd}&spBV%e+%?eCeSv^qWD>|v!lUzV?`FJA30;{CQmM&#sf)su1r$ha|}VKmO+;z z02;isK()k3Hz=Rly}m)s@;xqX?jl%)V3JRHpE4jwOa&O4_oUnO_=VYco>q z<>qE$w==FKyxZ!KyLXl~j81GZudHLkzct(|5`LzWab&3P>*&M9i2k!LjJpNu5H{z0 zjp!Ja>56aWI*<;kQ#k+@-S{z5U1~^x8T{&SUU1Ym543{a3-P2}qnew4#Q2U&W07?V zMlUUW#f$a^Bx!Mt88aiJKBBGlJ6---uqf=&`mcSaxAsm-Q_3$JOeU@>zTrLthJCyM zmy8O}yiQ(OKJ?uv3tj~m>tm2mKke9ZWBl&jr$7MR&UURDq`_Nfu1mf}OHG@*&{4?l zRnL0G<0hlj#%uG#|%%%7jJYz^}1xea-^ zCRpMumsZmbN113Ry2zB>=g#3dx~pQc4YaA6-Wg#PT#26VQs!OQ@9X5w%TJzr=_~WU zs6jT-5Ww-<1#tY&*ktt@(9vL%3^?*?m|u%bP|ZrRC=`eDa;Cc zKOqxT?PW3Du0QHZn<{T2uvZ3hcKK!vlWf<9awPx$P$B_^-86YZz6E_CZzbZ(3bfU7 zyY?g>N@+!tMvOOdL}B+GiU?i@Fy^|3qRC5kxoI3rk_JAxF?>DGIrO%{=JcuzuyO#V zZlhY_VpJ#0E|8FjzWHvK^f$8H0yX4?BiNIDdQ4?noT&c!_6d?hme8J+MEw2*VXz=S zZCF@?ZH%ero&9=}PeH|2f&&WMI0%Qcn#xE$M%C>Sl&Oa?Gn zN1+lJdbXCz_tKhY7c+jf*5b0J;_WAi;j#K`lNe$w}OxMUD4cJJ;B zM8*k6EU0FpARhaqs&%N3J@}ap$|iO0L)`g z`g4h~pp6^(9RIakrV5bD`2I~O{PKt9KhqDYxqmD9gU35SzsFA!F)gzcQ+O1HOmye& zh5v>;UwhkLUU_~UcaQ61jknkV&V<#S!^&=h(ziP8LB4*a`lx&O(KmMbm>TaZzoRZy z$l9_;IxvQ1l$EfXR3Q#OItophrlh~1<&h2(y?J}*4~_T}CVh+G%nVRR_A+|+cy%4# zp)_8CH{Tl%5e)h1CSR62jm-v|jkAGU4D7$UG^`zpFmi z(MAue!ANktwoAZSU?_Yoq=+r^HQgpi(w6Jyv*5-2sYcE6%4S7dshTY#cnEgF7w;E9 z#1{xTYH5jzoGznl=DwU+8!9Og_}ldL7kwKENX~2$sbPB`Pepy2J!$9%2tCxB>xa}8 zJu=MWB+x(IH=fI{GvKBd%FFW)O(%B=U=PHx%GY@~w6u#H1E+x2N z^h4SVEZ7LYGexQv77C2skK{bEUko>uP;~D4oevVL87-uIqdtW66lcln`%y5Prqqh{ zx}E)$D{Y&aq7{>A;l9Ma>9B?Zqs@=wO&~~UPIjlp**FbYd||7tBpr)wfvtVaB9W3< zC6vM*GJc=nxmt_j%Zx(;(zv}_M=hyXpQ%q4*bSY5NgT^$@@!qCh>nMqSKngp6bp}R z++QrM;U6rmQ}p&-*^yE$Z$ZhJWqXuT)7TNJ?~vr{t+pq0ls%5SF^J48CgyESW#012 zcV2u2u1dwd7Oj_^{()#-pFHq1fFU85G725X3j1|CIbZ4KJmyVFwLz#vcP;a$oG!gL z4#_kF`wcfM?|ZEu4bG%j?2rMv=O#e++$2wf{r@}NQ@F~^>E;psxP-;^MeMsGQzK7+ z;qfIHV0f@+faB%kUxaiQ9n_ao1TdtBl=!1|EZAyqJYXvzvKznvd?-4(Juaf?YB{l! z^7T&$InRaKEz1q-X=A^>$I-A9qdw??%gtMJAJLv>|I%+DG6@_ zl^m`C-*V%Uc4VB^w2nTe1A-B$mg>?xp%$ilJ8yR^S2=nTwaiy0<| z=PRX)%|m@D7C3DEGg~F!WOH6-AI@r)t4s^UVHvR3W8HRAVkHddD2seE`@cshRn!~Z zQvM#>pG{SD<_xj$5@TA-w6V@)F@i;P4lKP)p|3#e->9plx-p3CBlcPN1yx|u!}0`; z+y0F0y!H*F?Dx9rfXF*83xOK&e~~NseD4IKYtRpXvEg&U8KX$q z$QKgFOFa#hM7+^^yi|k6Y~L-h`qk38k;$g+sE`Zagvr_S2Yv}V^X>^u{bDR0XQyC zMrV=w|AnaPf2-~J7xFBDETMlP%|Jwt6{k)!8NWxpfHOy2`KFfnNJ+kNGf}VY=F`uo zI0yxx(oW)yZ?$(>1}>HQzGUBDTmQz6aQ**;Vg29ylm!R$xg2Z9pud6{!{oJzAXALQ z5EB-6QT|_lmooTUDtTw~`+n;4DX2MlR>SvS|J#3YVgHOxx!-yb@NW^F>+ziXJ2C|M z2ZxIP9J>2b7s=@jU8rCBC-?w< z&{Q@TH|m?fqL6r#<=@3VP0Hm6K0#~D=)Ws__O*Qv^?n1wp0ZDc6g2REhjG4#SMuA{ zMEeCh(4!cjC&_P$KopG^z8uo5Jgw=^0GKa84*&=0@eg=E&#hwozXcZfmYbeV*N9A? zd~@#K^CZi_W`z}co#l8SzY|C_K;BMA78YuWWgWl90RN)&1WX9Az(13&bUFs|63l>< zP(-=KTI0P~WjeY%e*PCC#(!wqrKsG)eMmK}5`F#DW6zJwyV5~TXY?hG(>(h3iAmX6 zErm~q{_P!rgwQ5Lb6&1UYKS0-f(C8@GXVG2`;r%ZZ%HX+7f>Go`84Hlen`rrS#hc% z!`iOaw|25?e-~2k9w2Q20-$FB<2eSS@SRL5lQ|B;M}_Qfq2>af90W}K@@BBuDEraw zLdomJA?ihB_?O!9G&vD2Fy3zFSQU_#qNU*N-^i@!Gn$^2;HJe0byhpDS<-F?^?`r= zw$$>KA0*+1fQN{F%jdF@3<1ya#J)35uFj7Q3(;PEC0Nhl;W2CL*sHf-Jub))oN$o~8BN-uY2Hyjy>DUKuYjTm$yfYyv-Jp6GNT|-SO89o_CZ^2|wVXDd;+Mb)%P(nY z1bm{nt3G51`K4e3Ukr`0=AM=MB^9ybz#gm3C>r+czCg<$;$7e?;l)b?@2%zW@d;`t z)dX{oNHk?@IC zMzF@H7)TY^ZygnX;rSRMWKZ$vVf`H;f!s`i-3vAdY^TmM^%4Ijy%X)2{1=~&mh*eN znK2*f#^o*a@DJjE!o|eLpEw( z^$n^DFg5H=noIseQ?>9KfLsfvxo6{kgBgLgv|f<-hbH=9pRiudQ%e5JapG3m_zMN9 zRR=~rx_$(O--?RJB%Y1cZ86%{`XEb#8$=7%)iXZvIt7-+r`1osF_D94Jfo zOUI-=K<`PBh9LQ!W#ga?vPS0 zxgOI2Gw-j0c056Y@a-$jPMAKP3dcq*QkLJs^l043h;{_&Oq2W?Z}F?$QgLWsx`y)U zs&glGpMR<`-=2P4bn51_qK7J67dF#iEt%;MTlr&a%4I^)mE0q>9Z>1cNQItib-+E( zKB2-}cYbDzrK29oB5(2hI$fOr>(|wnDtgn;bC-q#soquseRR?2iBR(!RABihw>>-| z)wPo9JS)D#%uJ>8TEHQtDhjQc2Z!2W`jh6*-_Noge^~gKEK^xCy7Mh3kSF^-O$GPp zW5>WR9HYapTJ}z|OOF6fSi7wOadx-jNWalZXr}f{NWo1)r;v>gZvv2Xb$+1(aa$x- zv#6(|?!o(LA5dXPK|W#&%w;NDYz+|#=t0<9oD4<&b4SGs?1ip7mJLzuQTGmItPf-u z7nB}sDb;HTefn0cH9V{~5`S0tE*u+1$Ls!66lm!f&vnH!>khcC)jYdT8YWtm=Rv!HmGFPx^|^C`NpzaoM=v zDUf~iKP?O4KQD_Juq@B?)wHMQ(O$SQ?Ea45?=M) z`fX&cwn)9v;GN&WwPt*#Abg8>g~7pcr(r?()eN}PC^wMi{O5;tLX`tHQIo@NO9Q6> z?(#Ar!osLd$=z#uzdF{|OYWH`+G3$-ak(}%u-aSf_q2(9p;|-~XL+>)UGI_}?PKXW z-n`8|X2jwi9tW8-#}QlFMhkP|54cQ@5G8gLz7Xn66Tm0hIddpS{jH1C_c%#f8D)wx69?+| zio@K1F{)9c(*?CfazH1^WP~g(oHc4N@N~U&a-xC+i%*0%eAhQIC>*syo~CuuH3|4J zni*m`i~6b8uyCUpm1^^Nv14e+zyN4D+cL20Ktwm{Q%;xBir1k*4UG0^nyq=)tE_ToJQ~_(S7ndn5snQu303E~_V`W)Dz3 z05%7HFssHK2A2_yF;~gH$nq$oUph5kHr*0I ztnw&64Xyx%8bHQaZn}8K##+7D9zAZoAln4vjpDf-6f2+i$Yg}Zhlj8}*_R+N;Q4)F zd~$TPU@_a-V@O{Ky!Mf4;M+ABj=^e+^Er-s(yU>=bT*!A^J7Ha;S)czW=-d3Zbp=d ztsX;Z=DYp#(ewr2;Uf!@|1(N-Z;T9z{KRcA;_- zQteg^nEB?1oEq;}qcRUS2_HiD0!e2AOLqM+X3ovQldnr%OTN5o%)6T&E)WWP2qTxA zXpe?-8Oc@9h}SZI@FNVn?I7wv6n>5}2_z3m)pKU;b8gN%bR81(4S87(43S|;ILhej zK!6o%ezhgWILNk2J2vES%P1Ex>M}k{?NZB?Z}0;bl|W~BW@)AE%2ZZXa3ZGC z_p(&=9_(rkuzeYe38DvJn5fNDwUND2+26sRx^~{Zh~&L850)sX2EX^^E~5BWFdV5R zoy6VfVW2=cf8vde-Ur&CFC->p-7K3=dY39*;uKk44 zjqwy;#}Sh|c!{)e7nn=KkcZjwZ zRW{F8G0K35HYe&RmBrT;<(5uho1;ASMuu5W9;w78m`Lxv6kW#!8AMqmbNR_z#Ut(}H<3Dh1vbF{V;q z@P+hnnnNDKQ;eQCnAs^JP>kt{vY}Y3TSKBRMK19&YUIfzG!Kt>)Kwr!p;TGW*I`P! zKL;k>&0;~mn`A=)VJC_lO-=pE+jZ*Kh2Cc`-+$#_@m^=3+n}rMUT31|r(flAIg{Nq zn>1e1Z}j*;;@c}(ZBy?QE*kh0K+upSf*Slt4`R9i>_t*OG1!bnmF28?;kdv4B<$&M zj_waJ9sjSghB`GbLZ|w5m9DLPs?1g_=MB<8@g(7Bp9FZW@-??Hxxav1y+G2Zq`LrQ ziAw+@8*SoTPI&@u2Q=h#0b`~pE5PAifq@d&ehlyy84Q|$rxPf6Q-J*sJV951vKJU^ zk7Z6FXCwU6S@r~ogQ#4{-0BH%r)ZsK-4Q(9YB|#Qmxy$g~M$7^s#J zTStaQ0C&G_i((T0m%E>NNazQsD@dTgo;C)0S>QGM44zAg8 ztKV)6ceJz4NlZ+V#%jqy8;|#V2lc8L?Irh}9>xYswr%TNBaMLLzS`&HCxg{qsfm7^ z)ZcjwL>k?sz6M{uKQ}qsJ4{Mj&UDlp*V`;l^gnoZWW0N)X4qK_ZPNAB!1j8^qsoUh zUJ0~dqcEs}!4sZ(A^IxmI*Qr}yei-9*K~PbhNRp&XdO^m9dNAm6-=fxjdHmUb9sM! z^0*z3OG3+vjek}NwNO-=YHbbANiCf-U^M9A*@NjA8B{5BEjCv0PmQ5@z#u-Vw)BJWGu7VBv}mDrj$J}eK%x;OYf zmyGUT_(K2ojO(eWIYS758i<>v0;w=AK_AxPOD=oL^eOr8zKF;@9e10$o?=iV3ootQ zPdjAM)mbvm4z1|=TpCK(p>8NJwbuIFttv|g|4zI4sb3Eh5(%}*o)7wlWGi0bIkBf{<1;+LxZwPGQUZe7#p$JgYb=@d@OyzexW@Qz|D~bzW6eg7`-8Y=CU=VyX z!sdT~+1>^ol>A3BK1$tO=GrAP@1VD%wF(W0FDjW<5N~tA<)8owQ{^ z&mlsd-p%|?_5IrkkRFC@rm;c*y>9LvmB8FTflRM6LWb5Q;e7p%?k20m{H>NX9IrizTKtKA0mAMZ6w*wxDQ)phiQeek&PCopgO7`*_p6IuCpRV)IhK+<(J8mx z81H}kAWRB`ujrHIucGF}G9e8}N9SI`w!qh2F|G7_+MUBxK;}517gBB&xZq z_Xg@wM$HZ2hjk{Jd+~gsf)38g=(j3k8ucq1X=@YZQl9@e;@&f?$!=R0#)=gzAOb>E zPy{IgQlv#iqzR!{Au7F#(xk->q7bAC2%(1_=>kF!qzgz59qA>6l0ZmE@l4*e_B#8V zwbwc8+UL8j?}vXB9-ld%IY+t2J?@bookz}A^yn$SoxbS7J>JW~_WPxK-ryyD>y!aF zduYDvB$MaTC4oq3UwDhhXw<@eTwa-*w76d0kmX^R&r;v!YU~u}x)|=_K zQjC_~-V+hpduzfw3lO;NXVEtW7J3UCT`kq5gfG8M;B&D8|Gk18eEwsi=uOB<0r}VL zi|*}GmyPZU!|BD8*Xww1j|FcBrXg0LzylCtC1l5*Znhafe4?lDE_zQ%_yrw$*oN6k zH_4HruO5>bR*}fx-Z}RO2v=WL--k0VnCCBGQ7=jXJ&F5!lch%9UJTr4=FksKNOz}4?OO)L8Y zYj?(FPD5Oq>J)?#hxh@fo38>$ezNc#xw!6hj}d~0k%7rUlH8VR+a|FcHuF%EmE|L2 z75JZ<&AvA(zYL9wMRv}SIjx`%^ro%|2n$6y4@*9ZyYljtfW}GlqpU`riSo+a?MLt4 z+{Dkf&~xe@5IkN&mHl~VQ|Jvw3qEK1+TF#lbr)L<8C@=1<%;{9OkMAH&3?bN6_?L_ z<|eLCVW?jac8~km_W{eIEP?c)&w?+IaMOvZ6}OPl8eSK&hnf4zK{}p62+itt)0r$M z8c|)(_?|Yad|UFeI;P~ySKE)r6Xi_82dvC*i=1r9(7VOSC#H-q{D;I9{G9S=0*0za z?0)LblUQB#1aUF=&iqqpoUv|twH9-1CHJaber|5E*qoH@(VA~Q15Zph2#7soFTH?C z0(1($V*IvoMwSfWeBPjc>qFy%jWYSbyRxxfhBh0Y+Ktmw)3bHm&goyg`)Zwq{3^q} z4vJOqCyIZfVu>>a8e7b-#OD_O`h`<5n`tiq~FPhYQcY)9-p? z$Ff222e}W&*WTH{Zny>edq%Xx6S^a1ZIsl#E$vgOwk2fSX}Apa6sHcIW%LMcd#mDQ z)T-2!h^&1hXE+`y$QT;4_InfSneGrW36l(%dZmnV5XBfV2hsH^U19Ugfx3yhBzOmm zIo`Iu4+Qv0(-PyKj-BWghT&TS}5ZIcEpD)rVE=hZ4%G)&z(Tp z1_pJLMLF&fc`W=>dRLq~OHGZBa2yg$kPSS1!BjA`&miZB`MrH*DUntwzg6I17z3*+ zoGz%E>a!K>FxTDov;2UJ^~`Ah=+UeS9oLVBZL$|bR7AFs50pfAGSzcw_x3w4p8ge; zHKur=f8qJ^;QJ=5c%?rXl~wDg2I4Nl%JK@Tojpuh%6UP4Jo;AxvnwLxenWywjp~MdrMhS=Xaem4A5G6c2&22Jro_-;rh9 zrRNasbr})q-Yp&oq`Yo(UZ%mMi?WA_kJ`cE)SOT3uqeR^nXBANBkGm?w6d8p{-iSH zAA#5bCO@*9ezk?!mN6~I6jBC8;oH%Gf^#rkEBZddB1o(nZf=+@)r8DwR=O5D2j+wY7b)S`bYWTDT{tG~i1M!FE*D5f!WWMo-m zS)^h+V3TZfTsmQ&o^5s>re53h#O*yc>Q<(EjveZ|Altv^c;g1sN*Q2679a#}Fo6;l z%u#d`ejEsa(XKRqk5`$4*pXl>k3yhd+lrl=WL{+ji2Yh_N5H*Z)ZspuP()*gUzM0c z12Be{0syb~r5mO|cDRUjq=f>e8C^xv)M)Ay{~dCGY7Z99GZ_OR8vxEYh_-K#Cz;#B z>@F>A?BL>@wpz8*K zjJ}qvI)rxw`)P(e$8={ zH5EViioUQ;8H12u)E2d{%!shK;O((z?;d_=ZKsMgYU`kW4n$wD$xAQEel}+P{qvhW zu6rq^XBQQHSgQQN&G*ua3HIo zE2Yfqi0LmvOorQcf({mRLWgZb3GoaGD$E2Fo)2FI`Q4Lk7*o8(2C)`~N4VV&v;lwy zRI8$Ug?-0{xo1EhJg1t*pD#=-okr;^ZHcKCGnE$t_)`*+!_OI8p@+6=>`VLv%3nua z?s{SO0Mux{@2!s)YjJ|AM7z70b1EM|IQ?O<$p`2DHF~S_U_bLdFE&t2R8?XGAy~6d z%rNqxY)%q;c}4S4$4A9odV7n%>uW|PUJr=uYsK|0@AEx~fyHZ83}hat)m*N?PQk}L zwAJf^*~wcnDtVnv<%*?+BpDYS9!jo{J>0`Rs1zpizzsGVNH)(1EsR$EBG`Jfw(2{d zWVN_{T@RC;vw%a5{f$FA~YSF|kDpK&`ud+R#$M*GUNI3O({wmOO~Mb*IE2>SiI`wSaUiE{lrac zC;vKkXXP+uvGNM0`DgA~zXzBoEYF}}x`p{8Q3AJ*zkpebhQx`i4%44F@>VT`D8+oh zkRho~nd-ZWl}G>ht(ZR(Z|16tCg>LU=Q&FCUvpKi)hxS~MB5kMFPL;7{$S@e;N4Y1$SZ9Y>WnX-Pq zj4I!Q(;aGBO16G;K^YqM9wLzjl3Cv`$@x6azzCsC0PJ(*3xM>tn5L-7#IUor9h;NE zTRtnzwqCbIa+c(za9hm=;r71j>qh6A6gy6_9^1IRf~w$`Ez}W2=PY+O7TQ3kM4{v@ z0=UJYkSgr<-uEL(s1>YA&S(D-Fr?FT*f@ZTYHULAf42NEq^j=D=C%c{WnYP!vF7_% z5@UxCIKNRyKTXiEJEFmV=flMBy@~xM7CUU9^PJsiH}zu218r|=-{g1#T>H3Dt;a@6 z&B>5w_w0(PAdVRNWQGXsyL%TSF*I{^$@}e>h-aKH#IxWv%FhFL(mnBZ5DKu-7QJLv z;_EefV_(pqcAlJvHreEqqz>Pmcg7IsN94;E**663K-zX=>;qEdrPoz;mm3$9i!(D8 z20(MDz6V9y!EwMbCetfEN`#6lJot0p-l&jPtFCln{)3wN|nJW*{XtQ_l}6KYl!{t8c2 zHfIwa?6dCk4*mxv#1cU`YXCll*Tqs`h?emhq7b!^?$Y3KuI6bBPuyPgP{CfEmj6V~ zT!D^6l#PKR32OE@@XH8_CIG_cH$jG=`n48=q6zeAZ+LHUQ3U`|lQ4;(yr}_3*w1;* zu3kT6v~N7{1@ky!*oChAhovctLi@vlbvU`w1F$asPv`u1o*|TrI&+s%bC*c(J$sD0 zVTLiwiEI@>+A4Y_Peuv8zGU;jJ&;)Ww-Zk z>!YPRPpmh}Gg)F;61rq=H_rMGPvN=@sn^JEFvCAA*D4Byf=P=f?ZS!{fuP>-gD+)Q^b&4g z2^o?b9_(hT3r4hdb4L99!y+s3CMH2kBi|`)<@1Ee75n|^wvVlR6Fa9x>i7FEEie5} zfs!-1zRnC=Rg&@Kt)e;rL0&07JN|tmY1V{Q8dPuuS8jGuM)i*WJ z=;3@&a%bgr{yv-Utiz3Shp7A&e%?eE3Jin}2^-*(o_U%E-CllF`>}>YUZ73>0+ebT9yaDvs<_k8cS?{<{Q|@<=PoFHEo+suRHO%iHC*O*QE2QiL@uilc?Sg{1xlQ@Z@RIQhj7WF`jBW%AN73fL)cu@hwt=Y#Y?VFL z+rfY7JbSf7j?r9BCydg3uYP^(*ZI9hu&t^5vH7v`17{qbbi7HsaqnjUg4^(7w^@Ho zeZNtd?Ng4MtviOO;G9B*Z5ZJ5ROd~iP+f{sFyb=iy`wKbq1&A~meD9WcZY z@{tqEFUx+1>|kXttg!vm2eOUyUGOOnmc17|(q^+!@+&BtGe!S8`U0&ZOGOy7TOFxax;X>|qcdmFuQ!_mM3rq03!SIV<+{ z72C*sAM4Y$dhP<{6LmVZ+e3x5$2cl7ZfJoUb+RFC|7u3x1ErjIRxC$$yjMT4*LVZn z&i|yr{{K16Z329_|MH=qH@3R(-WL&g#v|o@N-TTkJpx0J`EgW6hR2}Ry=+la^NjYA zor}eenGA;Ewj#JuVvxFk-h&samb1i9Z2gOe{y(f``GCt3i`f(8)^?pxmh3dPG810u zuk>&5AOB;8-;`H8mvY}2BtPLN^q#ungbV&xOaJe_ehBgkD@#Vr$MoRv1F(vS2 z6l{4C$MEntZC&1<vsh?R{o+K=y)8OYT~;$QdRf6PBDsUjlthIB5pXwC&c()D&%WyN zHh9`@6E(+n9u8xe>)Fus55{8kR;^I3=Dy`~yOc`w&IDty9u2<)Nl2f(7HkR_gNC)N z%%)?1Nrg-QT`GLDo@rDpjS%a8HOpB{!3`jy!Ia2vkST&bh7t9UILIei+k2AKp5Qc#im`T!2@|0TFYb$Hnch5 z`+gPr7SzW9*|-KUjmDQ480h=8;7K?JmZZ+ZsNv#&?<=ul`qz8JVyDC}0$pD$D5!^Z zk05CMZdjlAsin)4%-LXdda{QpDX>?4y>yN=%ad^B^z=e2Ymt9*xYL<%|0MANF{8en z{SRfhB$oODHVDt3D9Fbk57#v^+3HL{ENvSHNx+`WeyRS}u}*jMTx7@TvL|XHK1G)@ zqHdgOGS}FD!kxWuB%1=e)d~vdyW-SYYoyrQ(AbvF#uj=j9W-ee253T>6;4?FVfork z_D+o_f-_oK8Yl&l^}m>R=rR8Owsrn@uGq0m8lu&I$Is`%AC?auLvV`CY7cXAkDhWS z`u1g3O_~DrFx>`};G-$qpvKh*&f#`#3(dmMi|g-53ym}M(+PL^^GpQmh{C1_1}?-t z-v^?=>r{~Qy_Xw>(E7Ux7J>Uxo4RSB`_~D-^om}AAdJIzeLwSWz8};$PtyEP03iJV zYDt~K3Kv6s?#01K4)f=RZ-~sd=@64z}~qA#yo9I?~=adt1A9lRax!#zW2q$$7*WQq@`PbSZ+3e02NDJs0Ja8 z`T_PoEcyZ4p|zIV-reVdCn|NBFbG!-W-7j(Erl{ZSxlgSAG4YdxHX$K%I$xj%pcEQ zLxW1xc@`VaEv1M2?4;{z+7g9r9fX5KQm_9wle0KDC>M5;cLQXL>=sIhhG+zVU^N98 z19IvB;X^kC_(Ma|--F{N$b|pKdtoU$JBXp=U>+=V``RCt2 zQBW+MBd52hvFFX;$YYO=>{;R>sFS~TQ-8w?qrT|egQPXk-p|~5cJtEb_G`s9zI_k0 z>sy-h90KFw)sD63J-MCAQ!|Z4Q580WgYI+Dg{^lxVujda#A1SEdK{|v>U^z6!!JA1 z-;8YN#=Y-Fj6F3i&)VGZ#2+Rkc@RPtm}~{RtAB@RFhdaVqoB5P0{RrOdVs6kcem+N zUw$hXwT{_&Haf-H?4R}0J}YF-SVn2!D(|O@Dd?PS(U@PF*LaL)&9ZC_+`pfDemhCh zX#-W74`s`E;f&qsY&pZ~IK#{f zdp>iyGxw0UjAjNG5uNTzqNolb>T~gDbT5Iah1O^1-3$v!`rh`sR$t@MTmB^%V_kzT zlM%N(9H)25wtXQl@bek;2rOY`@*s5MI=ClmHzLV4a%7#|G_L|pzsgMUq1@U?$$gNJ z`;cm^1C!BeoxfqwK8*==qr(qwPnsR3<7!>x=46bgRv z^5+)D6fBfCOvy~D>yo^A0Lot0FY`#CYr0qSvadnA*X#4rFA0*_ixe-KTU*mK9d?)a+Ea;RZ>i59mi0s3;vtV4@@|hbme#xo%ONEuj z+6o2FPeuJ$5_H?Ndr%*Fi)_P6*6!2U@UFwrg;JD6;cXpLkAB~?e@&Peih6pk^e47C zo4Tjw^4NpgTlUAK#Ekg%^cH&GJaOfa5OX-6S>QEIS9aMYvK+mPJR%1rQsY?brUKd9 zT8ST*KQA@3L=L&V2s%!)Fgl-iCXT$<2>{AoX{x=kl z2G!ljMe)-*yp)gjoJ|a09F@C~<$U+muSdd}&4zv1gEPbRzZGD(p^oB9afmkot4^~~ zPH0L^)m);JRc4&I?een;O~H?==AWW8FV7N#Qp3y2Rf3?n*1joIMx6Q&EZsaM1RyZz zFtP)r8S9AmL9H4gmT+_d3&tmOjuruJ|k-jk;BO;8QR!w5%?y7c^cQ>_xqloU+_`7 z_f6<-8oD;u2SVh--|7;9x7#?z5(uH$uOMqDFEC`|Fev|GG+@&nQsM3gh7^)=*kA$ z^s5fL@}@r|fV}DMF%PgnIIRUslD$lSqDIx2fP58_0m7rhGP^pdyD-;#5NXly*Z9Xv zDeR-YU7&8|2`m(hc?*Y~GKZ7zf?iqdhP@%+RoWvaF)F|quYw@U6a0ZOReSaWpA?M% zkPbBfpbG&H5Nj^_gnWq)jAVg1EFlZ@zd;)ZH&cH4b9s|$L5=mM&!oN>WiGbrst< z0|9+W`UFP&m|{1d9(QQ~N(in(XmE2Ldce<>#2Q}o#x`%T7oX>R!;2AiG0v(a!BOe0 z|Nb@No$WL|JEMb8mFx5uz^ldILeVcTe5;PnMkI(2{vZdRK1&r}8XA3%-og6MUXF#^ z`N&QcWVTKH&JK+}^KD08yD}qEZT|E?<0;K^(nbY|<#y&z7b22|vLmkk7KEG?VNZiD zOi>xNK?1djUJCz6B>!DWQ?S1c`Ut|bGB9poRzoNn-5)>V0wutPnfg5v;-G~D!vyhV zOMKxkYyvx@re*=d6!vY0F*b%LU9y;MyW#a4xyemP3=4d{>V*_8=yzzrg3L=waAT@J1{O z&aa~GV=s{>Nn65Z?$HJQW-|DGG zjgBP0R(ZT!>WLuADY~WWjI-0Glw2NnMqG+{+Q+Bqt<{!kVol#n^*-5ivQh(E zetMH0GJ#fYd-N=V*t{}Z*wGR@p$v)X#xKJolbqwSk$lEV(mZ3G7FTFo{@rE@ z3lZp<@2r?Ek!`@hO2NNUyQc;~AlTL%ty|%uh>B30nxLqw`kNrXX{;(?D32d@t=az&8jJNgS;E&zeaf@YgZONClgsQTyhXXPyvGc8Z$1Csyu(1AX2)e3O8mQx{`IfnC zuzeVPfuBXJBbgo0X$hw2HgITbgFk5Z$Jo^*>AMP4?`l(ti<5o-hZieMr|`{bb~=w8ft%8Zx@mAQRP- z8q9{c>f^8Kgqqq+*>w5Rs_a^HZj#ikIKBMLC!(~3gR%ADu43Q zJ)pyC3H;wL323J_^H~@88a+*5yZeJjHlnj2+7cZY#6SNVV@Ak&#~iRa=GG1KXzUp( zX9LZabcf_8H{bUwA08ODsqSMpg+(^q`Z$zyJKiPCHTZU%e3V~$Se$%s5KAkUrPcdW z38A7IOHcOZa8N;T4DW1YPI!|5dEpGA0=u1u8u>wC9qzH69H|_|^|?@;K-r;6g#|Gk z9cT;mTfp_muyC(b47eyj(KwaGpI{h4wJY1QM0 zCuk+l1X9g)V?+CERlgwn=9~_1#gU63uhQ`t0#t&u^%OLJeSGJHY(zzW5sc(%WokEy zuID#98zj0HHe3>nzN`F5*6Z_KGqc#o-`CqTuE*qNL&puX3$!3!3ZvH=)92Wl%> zPxs*vEHr-+=sI$Znt-~2U2j^%GA36&d{EDq<33vwm#45(Fa&wo4Zv#eK&$~M)T58- zL4YIlkzPF*!aN0D!$SeQ`}7wwmbs7#|iu`zQ;=$E($|9Y5?T7A2wVivI*k~xiFxxu|h1>%t;1NP%eG45= zzr3m>4UEVimT<9X$*>{t(E{5lRXeV`J{3xn6EqBsy2v?72{28T+FR{j?_zv`iYQeU zs9+8SBYxwT3abSgwJUr%EZ@-sg72NNR$58ShVgT65XJSk`mAp`9!+Xlh78Y7^laMU zTCPrmPQ(~&3lb1`G^ zNl6evY$vzSthmTFsf0-yNR>U{cVTlEKqTHo5dZ<+chFeW{+)0RH3F&381>lZgMwBC z?;IrkYBVtOGwRH%dl74c0L2`ovl13DPnp9A5Xr=Bxr0j?g{ApQfKX+6#Yc`wDXJt7 zv^1-9lQ#2Rne~5IvZ25E^jYa5brws|glwEvmB>U2d)T=788K&m`?ox&>*Q>E)o+&U zmJzK_*L>yy=Ws!J%B#0$(@z-klX1WnuO)j<-b@=bbXMVVU zIM!RPU{9`d;@qGTuu*D`=y!u=g8W(*t*0F4(Q2s$@0S%W+9i(MBYy!R{|h*v^d}4| z*x%Smic23#-0AiL_JN<4Ho{T~$J`N0+#5|2=a(5inK3rA7uN@Hdk{f@wxVmn1_#=*Rt#5Um(Mcx~O8}VcZd^vu|$7 z_%HNuJ)ib@zIxN6V*^#kev7PCt)v(O#OK z89Y5IJ2}eUP3JRb@|T|inIPDq|7EC}^C|+^=ycCzCLnk9;*hVPJijBfia$ipy;ZSj z)t~2JhqLRs$Fyh~@}RgA1fp_onmHfoee)YzA-0RPIZO=#*Ruy3hi${oYu705v!mO$ zxPE)zAM3+n7W%A&NdKTo_;x3NZ-+ zcrkb}nKkPC4g}!EGOW9JvB&Zw>Q*glJ~z_<)yhka3>0NP#PZhNBgYBlc-B4}d{($l ztH!vKt>rxJqmR~9mnwc)ew5l+%R^0sPrtk@^8KTE=56j<$2*ifxb+tX2Q*~xE|_^~ zdW`~TFAEH8-Go2=ZWw||D^x@l(BuwiYs#+Tk1ugb8>)V83>t__k4u-mK78+fQL%Bo zTb@YhQl3+9i@@EH5YzJ~RdGLI^B&(335a&>SsyN5tiYJ1fa0re+1bUl$e^cIv8kiH zT}onlQSYC+ijAvJ$Hmp9Y$T4^5;)y1c%N3AisQDIQr9$vlxByD_)oA>_W+%wZy}_^ z^|N)?>Cy3=s>H@ZpC5pIxSaY@)LyzyR$Mabl~5HIH_HhF_j4}ajwfWI4jnsN4+-uI1^qDof zD&1V7V|T;*SmKF<@sq_a|k_RsfN0QiP`8Wp!o4+Dr| z)n?tq>)`a1e@W{p`ajTm+MVmch^O=LSA`k#m>&QSGbAEsXiqn1DkOza_L?pw^KRf_x8IPln8U z_hN;D<+m@}9Pi^WOUYV`NL~4vWyk7lBW2wGi4Za*Pw2BWREtOq&AL|{% z3VTgfX8Tm}OQjvM|ELSK3o%-#;sLx7TQ_3WTcRBIcj8XjKIR=LnT&Z0p#-i$7@MQ7 z{vzfKR_{2{f#PdP&>Ebsnw$)>939`%klla=P>I?crl5>ChaX6~dDm+Y+UACl)gk2f zWPm(c*L_#%uC9b%M*O|}20rEc8>3L#0Bj`!K}aG1VotUYaR{K3Ui1T?8Y@Bp2CYu| zz{)gaC4L3+dwJYsft112;#H-F6Q;(JwN1l@pyCy}qw?RxEy^zO_Y>%6l*8{r?Z^l2 zTGRfHH5TYW_T=Nh+65~<2>2yaV*`oU!J=4a3Cze7xT{(%1Qnp42L2{d!HgGFBM)f%WRcnCJ=5^ zwle=o32HE6_`oib+jNIA4ED<9=t`HwUwefQ;>Gy>jT&U}1EGSP>m#|;R8H#CmnkkI zmNkk)P_D-vD&tGXt{Tkv%HrZ7am@8u5bxcCY4UuCGs&8HZCA`WvQY3c@vM_|#yvB# zx;Mv%JH?+dKy$B$j~hM*CMWz}W*Q^JyQAP2eFvM1M#e#8QP`Y{QuS|FrxA-8eFgTpl*Mc5RNc9pu}uam!Ns*l`|af))z(<(&l z1^QJtLd0Uz!)tz%V6v>T5%Y-I#rK_tN>O#m28vapzRoOF=bxF>B}-XebI(f z?#`B9aG^&w22DfQnUWiHxaBdRjG5?Ff&DUYXr?duzhs&Hm89;@tylw7-2WRtAw37t zgrNbweJyxJx)-mO1NG2^xqEs1H4Ee4d!~;{9a(@ZN3Om>tL5_F|6&|CCPuB}=G1ZN zeBKy_5D}3Bs;c&>hS@s_oQkC^?iI~eU3>OhXKw;~LA;w!p#AzSz z(trGpKmLv>V8v9qA7ShYdo?Mq);b>X7FRGAf2QBE1;x=>YrWmG{u4!q3@AE=Gg*=4 zF93&USJvxt2F6>Q=Z5P4d=GE@xbE9H9fZ*iqzxo8;CL*%di6RpyZd%f6f~IOmD!?m zv3xb;6;*(-60mK#x0cn|NuXah^L!bRl#{g6%1r4%p7KB05Th4#6VIWig3U|WeYqb< z?;Cu|nOl-hvqCf|fw6eR`-^mcXznbV1p0653$o00`cL#7Ts8GPz55I`g!l~si>h6Q zj`~EHj-=IlamCY2XfV(tV~-FyYX-!{QLi#N7iM6_sN6p+Db|p6a&n!(ua`JR3+#*c zL#Lz8I~ai-)E0=6t2Z+W{h?F3wQg{b-^JabB_;~bp_kbsm0?2(Lg@W1FtzBcj;-rY zO?W-IbH_P0UU||!yrd6RL7IAxH@SGgZ?jVYn4I~CrS*O7I%6OG7gNT;SN8TXd)y?| zs;SSsx;;MZ$|F>n?6~ge$Yrf}p&HS&@0SHS1x}n%wne$i=WUwXPlSah2XRmx)fy@^|>QgDQ1VIz;rlf{)P7&CLCDH7mnp zTsSwZ^}u%#7NWq%YXiEGt4Ay*>Rv;Li1=w+QTbnnTPp*^t5mzxuJ$;R$M2S1A=EE1l=e%FW`H48& zi#(6~*o+hm-!wL8u0KtXV%z8;3_bfamXlV+Aonn}e8|~HL@7G-C4_#^Hx&p(%b(zG@8J~E~Z8m&o z|0QuQS8tC8tLJL9mGlc$B#xHl5sgWuU2QzC!-O7L4X9N;xIvELN%Ru%*>hMW1QP{m zToI(j&s8?nR%y?1g3{c_Ac5EDYlh0U(}5U!n=6mjd+!=&1sNQd%-`G6dq`-c@j2|4 z-y1u95(KnaiV@gvN7U)SJJHMuClWwt&v;Zow{uY={S?+)`Kav+%syNnE7cV-T3xpn z#ALB_aQ-K`Uy@^A^aJg$GoV*NXh)y92iK`ht@j@HH3c64z`Qjs7dXCjM^jH?15RB} zD6dK*EN_g;x83Tkdna7#sq|<}crU?C%^+}J`q8Yu$20RVLN{D{ZH_Q9G_gjJ*x)TI zj&4$L??ze~t7zObYSFBc1VHEE8p-FWdp8rboZC&loNM-jz?@ps(CX{5UyW;T;w`ZY z5_C$PRUi+wv06or{w#Zu{`S}KC@V(lSz~R5z3-D%9-Yye$LOa6y#pq{>?JpvQ4ftH z;;!5geEoQ?tLAFxi#IS0am=N+9>;}mvRa-&h^>+c9?=k15YTS>^geK`k*@F&Skw6q zE8p;zcir1(S2|GQ)+XuKUX>>pc0=-Zn6}cY=A)5NIr1pWaaQeApD0e>X?69d6V-oH zPMxLEe=DrkfK5*L!_s9{9vNol&_)lPtbNCGZ{+hY@|GXrvu)}U{7%g9*Az*2ju$=^ z=~>5(ym+gvQ_IJapTkBcGP!E=xNaOv%{; z#RcnVVI6a=!F`{)_bm}_a9m$x9>g7~%;9tKrGr2T#npj%1()|#Z~nuAygm+z9N|@b zur&{p_pSKZwQALx-@vFcxKkvDRzSw+5YMWnd5>Co%Qh;vmqJI@o>a+eMa%zo*d z%DTdWf7Cr!I}ub!wE4Z(!p~eCxp$n)-lywF(9&07a-BH(_;U-_3jYe7s>>4GrZRUv zs$agMuj!E7CTgjFkU9EbPwJ8vTkq{6x(5ChhGO8ssLlTdU2k3l5ZopOrhH*;>N26@tL&_OQDYzfpEl+NnfRj6ED5l3~Q^cpKxvhJ=*4wW5L%vq0||=e!)*jzRKWlk$gh zp8NM5KcX!)bhY!yX zix*Q>`;+FsG-!ki6L}q;Y~_{fZD{(@Yu=t$_S|Xr@1|Crwn)?_M-~&nr_Wg%yi%;JG0%0hY<;dnu6dM2H5U*2eW}&U(CaGK zkUwZTdWu>2K5{k~4b+6LKjn5FaAt4qZJ!>!k->Mi3w9ZCb2Mi4R zeOZCj8UBNmG2(N6yPkv3wu_9|(Pt+P*Wp}^uvahj+}~ft7Uuru5se*esk=9wqNvK= z4+^U`^AR>;md8bt@(WUz=}K%i(zB&}Syhfcf*eMV+nx#(821@zoH!NPB>L@8$NtAh z+7&$O`0MUn*QT)hIMyzHZ>I&k;LhU7{aXn~o%%WnD;ek=%Gbd7$r!#|qT(#8!*mvDng*!}Fb%e` z-(r_JxHjocdmCY?D7mGshmHd~zD0IV4`c1fX6LVKK%69BAAh)^J_E7nHz+)=ZXM{q z6cny}%778o(^5`$JF~u9mYdH!yMYkR-$K174P6CoR;GNEnvLn&T-C{w)`FiQHVw z9_#PM6t5ry^smuJMIrz+>J%l7^m7_T4{mPTY$L7bf1{_Yp|Sp*)GQVPz9ZbzL*TG z8?B*)3=j5&+>K^(z5=*WRRi#)y;~AYVnD{Y7^0kBOVP5AGW?$!$$-kgDPgJkw?7pGyyrb=VBw&N1}cYU?(j9OG$2-zvg4=m zi|TZuLQ&;cfcN9N_>v>CQ%W$9e&JzZm=;oyD5UL9hd(iLjJP2nmaTNOcu#n}$~$Oh z$swIfhJA(L;=W|+TA@Oh*5==>BLW@rXPO?)taYNxrMQJZ9Mw^U4Kb~&ob!gAjicmG z%)K(YH@MM~yLG|pW`n-jP++x_-`3WZgw*HbHS0X+>f7xu;(Rmn?h(m^gTZ5uP(1D8U$aqSoa6$VziV58i7)O371U)6C} z_Qa;Z*FWZoXSY5c*AbU^>|LkuirrH5=CV=BeY+=jf0%y|-*ZVPxkUMO;Erj>>!9oJ z=XvSp5lIE`^+LYyAF?T>8!j%|3Pldmlhn@dw{(im_u0tetW0J~`a(NcFWz|4uceiy zUvSXwlB)kEc@GIc*4nr<1D6_LykexhYoQAwjw&%~NZOvl@q}V4&whFHo7q0Ex=~}p zdCN~PnJMUR&e-*E8{Bt(aPz}>&4sa+%x@J?6O+xObdcG~S^5NaQ1TH=#wP;4a;)6w6f_x4%f2MNph=fGKM{*0 zHs?pa72eqV!}3^ARoUnyN3>peScai!dYwHwl`jSs6r4uNEtea%K#l&=Cyma;tx_(L zqN{i8BkmQACKV{&MuXzZ@6;#^x5X&rl64I>&-X6xg_FmkvlW~#J2}mH9Jp`rLs07W z4`(&WR?s4BeRI&)<3w|`Uhw@}3{*EJGoDyXE&V{>V&LKP? z-T5cUYubPHh5fs9xE4f%ZOv&&2{e)I=pHL8vVl*xhEKQEOys~3M?8_^qYX{+iml0+ zxD7&^twxdfVu85P-l$)_&i=1@*y^X`SkN27kl#QF?5V_pCU(QhgI>sVv@aRZH)u&% zqQ9+AKc#VUxuiBBHWN>G6Fr)Hv_?DXe-QWH;c$2Tzi)D8?i0CbP zm>?mD9$mCaA|VKZAP5t67-jTPf{5Oum%&6Yqcg^sa_{ASp8Y%f_j{hbud~nD*ExT= zE@iO3Yu5Ud*XR8s|Fk@?bE- z@0E=7S9t+h%-^T^XBj#w(%e53uFDdW&q+nghOQMZY8ec)u=5{}Z%$-@%fQT;M~VPp-6M;KBwK)v3oMcQDpIRXBcS zF)*Pn21N*#mip46bgj;MO?*VhW*;F<^Oj*EMO`g#B`fLqMV|q9OEpP}a{&cS{Og2R zOdLo=Kfum4s0Kz&>Y?L(y+eOGCk{~YL&GL6tG;$NcQvYfT19lD6CZOY^P-9o;mpi?3VU8+xBdEIVED=Omf&M~t7F8IT{xN+Bm>dPso7!-(|45Gn2j!uXy;aDayT3aDUdK1NQq}H=OPEa1B3yjBIT5qIZXX4J#RH z7}aJJ& z3Tk2|f|b9Va#|r=(N%k()b8vZWoMH?y+L4<80u6RqoBs8ea-Y)?ka0jP!%iEw4zhu z9e?2D6n-X#*UXzUvDxpIZtA!P2h^s2_@#mwWZW@r;E&sEIDz2TBn?NwJBkV5OjX(l6(>cMkWa?! z4pA+uV!(=tf%b198b#&h_zIYsP(8=ZzfP2r+aJ)9s2a=1w|iKTD`ZxL^I&(qpDHNr z0E)eaRrNU)K#_GNG6@We?;T^Y@4Tzq_dbK(k44}ls3qP^JDwtUb8>~0y1pYJ$nhY= z(;5wdbwpdy15q&>ku-DZwjHT@RB-OpDcpLo#OSPy={FM$XJi1Ica8?=ALCX_cQ10= z9ujBV4dpdWS9>tj|THL68 zRD5m^XG?#m9lA6H4I%2|r_Xw5PQ0iJb0+XkOct3M>OBf^ty-n-N_YvL7iHxC)G_ug zIzZ;>qFQ*?K@XNwQ@F8=6AnES;PlTSE!L=k@NTjdQLDPdQ@>+kE1E({YUx%oS{wY@ zXyC*B*+YN0qvNETlzdkF^=pj?AOUvyU|%2-c3jQ%b~ zz2>z+{%EySu$>yh$^m77vZGcL&u4vty*UU8m6bl5nN`FA`4UD31^i{vc1S9mrfJR9$Ij>twYMzNXKbGysY(ZQ_0K8!J)4*sr3j^Zl-zW;|ETx6G{1 z<;qt~I%V4##00+abH_OJGw3Epd=eb%f)T4>n7#&I5b^gPj2#d4o5N3#WCZ{oK=MCw zIcBbW`2cfe;0Bnhxe~>J#6h17eMbOM)Bi~i4dkbe|1Mw z)&@m+JO7!uj4^Vw`DVfT*U;q-PMr%Q-y4=x9h&Ab^$bU=zkpu z)7)Ywy>E9#C0SkHC7$EogJv<5$RTWgb?m6{c(Ix|_NI+ni!VsT-CFS34`=z~fl!}n z0=K{WYyau2=cwh;ZR(I$UD0{iti`ki^ds@!4y0B`0)R{C_J^*z#hSfz4h@6?xw8l# z4V{HurYkRI1SSJD)t8MDZ%N+a7?f4=kqZet9+%txl-|=af~W5Z{_1!*1PTva#R1}M z&qEm#vlzbnv|5hlqq47FQ7`Fz8!8)PC}gKDV<0XaD$EQ4Mg zX@>m-^vuRE1_P2qQBXhLQs%3gJv{PXCUFtHi|ENbHh|Ow^}*I>8!*b6Pd_^MP*%r@ zf><0q!b-!|BdHc(AC>rSQIEc&E4p{+(K-FwoF(|(GO9W3V5jjl=V2X$2}U^j9aIQ= zO$o~cNneH4@yIL6zCwW&zf<&Yw5GnlTuJ*|YpR(Yyt;Tl0Qk0BCn2P7h=X@Kz*csx z6ci2V+TkUQpJRHpY43g3P%4qiJ#?chq0*IY$kRL@IhD!W7ju<|oc>y3X7{0}fTie1 zui?4UJ2)k)1;g>`zT#uiE`p+EZd`P9BM|MfD#SM~oq@S{=XxSb#jHA+vf~OQFTE_a zKK(Jf;7!Ko4gnzA#iEHo<+}AK_O^I6wrs`Km!=g)gfWA1z+_#q*^=1Na*K1yB=UmH z6=*nbUf$#U)wxn}&6U?zelR);{P23dtQo%|OXLW&I))Vw!7~r<&xa5i+DT9RybR#i zNorQMqAz4+aP!cA@yzv`9gsWr%nb^at)tq)!J^DYR=@~KdK>5G{H57s5BL5J0{KM7 z>(M_ENJ|u`@j3tm(#A#f7=aX#_h%A4Io3^2oP=RUgWX_r&q3#C#+P%$%W5JzBnh^u z1;#v>A)mv*(Dd&ZAmRq@?JYr?3J=(e;F%bg#wo93jIL=k6S7^bM-l=YBe1+X5>O%P|Hjx7)VdqLVFav%gmUj;kxE6XmJ#xU8C@lEyW|nA4Z_vinEn zM7QUpT7NbsWzg77U+*{$0EFf&KRYUFhO>JJhL1_V318j%L;~KOOagWmm5n|#f?iKO zJl>ypqu{m^;a&gNiQi&NqbKX$sG(4rRilMxg6I$Z0SpCC+Pe=f>BX!OIOkmmXMB;P z@3QL_1^cl$bKRLv%R`BGV4}_^y+F`7qTR-6XC1|4r^XW3GjvD)R-Q7-V2zPZ$G?7~ z8H4)Y}RCE;iie@QYLMw#Z|?6&ieg^#^|;3x-$8= zg)-(-60wEjW$(EkA(wD#HTxZT_buyf<&!S-^4xLPMUgNH!fPKPvkxKcvN5%gMAKJp z6iQ_C&=xG_@VmW@x9(vcB1gM#y05cVtU54#IxgK<-XSkfvA^)4e zx{&f~U~L}60@Oa-pTyt;kA_LqE3-9(s~3scb2~Dx1R?LX=t4Joc-KSIbJJN&n}4Y& z)vRQr-g;chs}Tx1r}B=OX#)D;UBj>*1+J1B1W==I`2D7qhFVD}^rj5Z`ZzG3^7q*` z@DB{r4L*?ZiZ2oYPsgT?CF|x0{4|N*#8ab!bgEuTVm+IZm$xolS5>}WaA${eO0bGo zjJmtcIl#9TrIXQ3Uyg(%sfm6x2Ca{&(*V)UcKu2v)w?W)kTNK)YYO1 z?J+nAzri5`_cb`5)Y6jlaqa%O0E>_OIF03z@35Z*0m}4cu!P|{mf|YL9)f6)x7}d# zJc`xWSgFbqT_#>xaK7%tjq5KA%o3X{Up#_OpG>J_ifae~v$>TY!1)X)mj4X#x&8y< z!`U|;8pk{_b&FYif=Q3#&ql2F$FVDo6V;+BaunzcIaAkeFXpl6{2Jaw`u(UqO4d0X zH2g;i{CJWWC?Eb*CAl$I1PAy^8`<)OCX>SE(=CG)!D~a{Cc9hQpQZaMN87n>cMpxlq@R?shaS9r)9z(EpfI& zQNfpvGs}97Fs=|=Pe{;h#!XRaUJe<$q&3+5)S@$Jl(b@WmohKl{Ev+0;V(57M>cEUCi;1aCqD#kL-Kc`sDKHhrE6(Df$Iy4S{2b>H;|@&T6eWT-rT&7lo5ovsV99m1NG5fjtZ!@9fe| z+*i|im#}bkQRy0V?JVKqj>O}j*nd~5My(w%+7H&u#xVCF1?z6iU2}6?F$+r!Ok>pZh z(GF_93ip!?lhdk{Q#+gHf>67qF z3#Q@zTN$}}2y+zl4)C>VBzeO@>6@%Hu|?_2IVf8uT_wrl9c6#f6aNGcVzS{nYF;3jrTLmIqIS(2uYG7Cs6l-i2F7J* zhu9T_n2UzW2x%gkPjY`2BTw2QLsR@zt)tjeH+qciZe-?uD-#?xybinLKd|<_arPD_ z>E#e1rpE$)Iw8!_)<3J*S45X5A8~zuN)F~bYQ62Dp}yQ@=jfdNkULi7H4?{Pr?OG- zhxZ+#_iTI7T2Qig!@saq4Q^K3h%J)8t{WJOQF{a%{TNo3+P~3wb2J7DQc=-<(v8M< z@WVVfD}>PdEGW5^5=RLkv%6(^Z&Lm*-_DaH(Rnn~Z8L*NKm3JKik5PPEVK=;J72SZ zelUY=ofkk$Ih9pi#`Vl>Pr;h!-z|vi#F)R}F37h_n16eFQs;J6zKVe9VKsiUf}d&x zW*Zsg$k7e@(b?ujf2SOi4BHePE`07*UUbE5z$rkvsVzRzJBIiu4> z2V-0%9c+M*sN1W`Lt74J=3@LQMkLs)La*G@A8(h%Hs3xp%Km1z9W{>j9nzHCk zr}{Pa>t#vXo4N?MD-YL6dwajZNbHMMxlIc5|1NMRwoh>V)Fs!6n;{HY{2yJgzXmXp{M-N!JA#=|8*u?##j-xt z2m_nkms4dy!hh>XHJ%!6*ZtG*p46G(u)obPM=?b&u!?!@`KubYaAhEV>8mKEsTwJHE;QA*Z95@x?j z(IXokn^Df@#9NL0cQeY`l+S~XM|ss$1OW4<1M)_8Ixn=eEC10WV=deYNVBR1352Hb zkReCNa`?_owbhRHrl1B8QO=ygID`@34;-aFYO)UEGO!VhM&>kakQMG^x6M1OiTjzYvEPb%5Sn7|>G~M%KZuZ6 zZLO_VxlnXpu`epAH3kUv|B}XbVxys)K7r^Nv!bH!b@QMsz1ZAearE=LI0ohpe5fub zx9Ldo(%m!W%S};F&We3lCU&XHapbb+cD7&zI;PgNk$w+C(S z8g3NNjGIxC%|7KC$DuA7$7S=;R_EEo4~|@)96_KErnSj8AN?q5ub9nq8kqV}mhq7o z-Jl2OQxx~LYIfb6u4kTMh2AVjQ#(7$+Qq{`snPY4)#rw5e(U5PM&?s4UXJAhBdyl= zqE({(7Q>nTxDL>rIO*^%nGAMwHx-yXWa&*E;o5^hSRXmFe|Wtx%nt9`-@U{&iD5}C z-Gf?Y`RdO*x-;u`Bif1`CLeR}^gpSLgx=COHV!z0v?bM^pA?u>J@*^dC3{WL3d|&7)3EoB zmYuz&JA!9Hfx~K}tCp=ubqWJDbY71T##D<9T+c(F-Pb|s=#U@yRo-nrwVEBFycm(p zbFwXgNk`2jamgV`>#KJekW=6y+PTd%6irz{NNA_$Qu)&X;z0>J?I+U^aWR6inAC_& z*|h1&a+_>HNd*NX#_jo+QR4J9pue4C*u=xOix#9_9tfRw?F#f|MA7fztKdG~A~f~> zZdI~+KJ0QfXn$+~K0Wy1$8MqPQF~QLpOGN#b1ZikB4iWeZgCqhD_zR|gPB%Ye<17i z$|GWg_pTc8%rA?*ZJPy?-)q6$ZLW0ajlP^|BO)8G8>euvfO$xGCuM1H-Q|6HSj+Cf zaK&ZNwUX#Ncf%uIbuIGbB>~xswesQ)&X=jk=x9g)OwMWvx~rVMi{-4dTClY=EtVD$ z5W2dP`_tL=`y?}E_5DYI&hV+aEXTP#TuyGD@pZe z{M8%Nodv3D=XVZIO*GzaaPu||G;;Y^49QRw+j^qs;0g*DRv(b80m6+377t(bhLs!~ zXg>X91kRoC2$rMjIUh%J^%S!Q6&2kg*^a{U{ko5T3~F(*NigOgM(*tM|i-Y|t3VNt(Z7IqvphALd4R3(MjB zjWZQJG*a8eVwqjAuc^;0R4P3J;@#L0QR5)O=D*`53^lBTI|(Y4%c=3`X%>lnOMEj% zA6MWuna$|M(^a_M?T6V;k0e|_uP7UXCR6kYO|a#Vy%=IJ{;W-AZ2-?Grmo1bz@tW| zC}g9)D0P~z$fIUrvivTz#PMaav*G;&NfCV9qp_fA&MEowBJpnd4dIDXEa|b$z7iKR zUa0kVudkdt1hd(kf{;{nuX&*bkFIGDC>Fah`=UI2(v{ir(FYvyn5M=VUXvlf;L@<@JdEMPcXMp5u&!uS8Hb^Ct2Zh;5?Zr#xTx7N+dgrgK!Uo@=XGDguaU4ex8T>unWMJHLVfG!c23Eo~MOT5e;xwo-5R#EA0I>J6()9PUdAVuIO{N;gbk)-)>OIDHT7~Sik+_^P+2>beysiH_AyhX{41q}%M{P8I zZRA0pxw7xu9O05sdXRQ@YBHu$cCn7WnsC5((xR%$N5P_1SARvlYuSUr*r@lk#Nnia zyt}c%8JDXvUvBLHmhiovsxtKoxY6A#F|floq*TBM+^!#8CW-bJAvhXdV|%X6RdV*C z-eYeyh!~9w+7!q+p#)0S6L?tt&2PK9@B7%fP<$a4q?***@2cn}rX~ zVU$DnSAPodk9FYKKM_xDBNmL9_H}BHfYj$-UFGfr;ZxYwFZaLApaOCCaHf5YQf*HvXZyUnVR%(G!hxl>r zM@9xsS~XQtN0XIp{Lk_;i#75Q_q#f|4b>!tjp&RM9bc(?T8>#g^0&W%ceSY5<0GcP zxmcqC{lAZic$ z@%EN>B+v5NWu(;bFe4_W9KG}l*KFbXQ*uq7t3qez#-$6W!` z)RMytoi~PFuhW6P>{93}A1Ve%TNB6ZoG8fu>2fEd@hg!0JBtWhJKZV2xPSddo*zN* z!!I~QMO607_P!l$2(WH>cg1(zAL5`?r#Fo&O;@ zR|&c#?;Qi_X4u2aWj&YS7Ec9zPpnR{o9g*~lD~SKX0=o<@xu8@mK5#x@&@vj{<78YI&%c#yds#Q3|ry?Egp%n$u{qG+mg#> zWE#?l%XfRh4bt58#$vnZp@b~Q-x$36O zY8r+o{r&UQcNv);{;u~M3*W=Jy8Vl#sg~~!eR%20;vDO4};zGDEo4e6QKArA+00YIyQomd)MOX%xmMayt6;y zeD!zh^E=7kjh(H{<3!UKCl! z=`@A+8F`D?-1{^I;S6~8G@nXef513mhoaZLEA~2e+5KFnN=l|sS*t#0x}>9Kgn4+B z^(Xbpy}i}A+x|ub>|QO^7Q#c7LA4go5HCXEIF>E}ZIg}s3=FH)sd^FvZA>h8X7koG z?tRYN+J>*!hc=TsLaWA5j+u|sgv1IQPbmcG-%5kR$h-_h3m+P1awG;0sWWw0co{@L zNSl(sdi1?l;&b?9P?IqC7Xj_iv*`wLdf}LG1)b+Lj2u@x+qHBUw4W8Jvs8aRv)#@x zIuLk-y}J-YiAM*4%I4J#QOayVeU|0uspX;iz}LZ-X{{s_Z;1|>c2eJ7qb6-Qs~@<^ zM5lfjG=_))6Zr2l{j%{#hxkBn^q0jE!AN>|BN+eqjyh1qUS1QgrcMJ>%wxOKnSX0n zs`j7kN`HZ#DCaiJ#~BsNYQM}o(q!`7A5(L1Fg;Gm_>z&~@N_aQzjQ}`V;Zd(j1=Jt zlYE27$o=LEedRuKuJ7WHj~2en^mBAH-(Yvl#dSr7eX388Km0&V$^@kuN&oC$rrFE- z4THLhq^+=n_7yv<+C#GDs~u*hPMYca>;xuBm__+h-#WVJB9DCK8Ln6Sd=4uqk8DX+ zLUG?es>#Pj3Ahi~7BBnSGe=yJfZq~S1}$-8*%OLR`+5QUNzd1((48Nn9qa0-5Ae}k z3w;#C)T%*U`L)=MqOlZYZqD>lxptPYzK#~18rSJk)%~I2dhQP#XL-v6`M2ggN&a@5 z%o(4UsnRUHegua0y-=T0l|lcJTSFz&=n{Zk}YCew92mp7%1f`2CKI zaBme_S0vFVKLgS45;dS>rY!$?P(Dh-c$SHgs_{^~jra3CfAyV|41|)PQ(dIAsOzN0 z{ErYKM-91}*tDCvoK9|XgU7Qc$F6^+V%s&)2SDqI_8q1!z{LiKH1S6&)Kp3p3G=WS zjC7T0o5J*wLK=GMgIlAQ1}ZQqJA$3K%YLo0;#M@Bpr#YdK+Ukv;X^*jB> z&cR0c;^VHH!Y%tEc*W5~DvN$ULUAaDpMS&U2Y=qqU_beWc^qY+ZlYNcp0%(ijQCoe&g~mI>Fm z#g^+M5a=CJK-1ivFHtL2pYn*AKAlEyccb{rg_GVMC&a{=W#bR;J{4*!t93>HgNjbQ|{R zMi&2N{#_>r-pO3Y-T})rtJ*ubFOe<-4zU7``FXgd4$8+8?aJ684VB-?$g5H!AH^hf zxfD(dbEPeax(3X%w95RB=A0#NulNva$kPojKtPr@zOok6NLV_7KN#&8v`+%FKKU^d zhe1uXxAPV^g;e7Q$8Hsz%D zQF?JB^-3=|(3VL_0p#_W>jLX;mg}_TaGXd+$Cv@-JG8t+S~r4rF}bPp(YtP~u+|G- zy&rBTsOA;lDf~D*A|?>2-s$$|Hk+*EB2LvoXP$24v}jK{q{IgBtW!>lN$oC0yF>H# zUV$%X3?(@(qN}btIY=4E*yN|4Ov?LUyiwGzr6)YH)Vh$7-SIQ3DUOLI#wkrXLwWgE z`qG)2H@|}~@gMkeb}XY3O_l(o1~lXTI?+AOkDKe?@9#)|H;oWPdur$*6Kl`hwORG0 zyWm*eD`j;uHPc~kBp1xkY2>^$78q0<|R8x-GBR5fPvb6S^iKBs| z)Mr5sA*(Zsg*ct8(dzH%qH>9o^;#9X7{?@k`|Vg+>oQVpoxAN_CeQ2UYRR`(9r;(t zlROe_>d#(maqntMpy`t|MWvy2<1GfiZtv=A!qWf>Ck+*X{j>p|AG(wkm#A@=gdE(- z*hOJr25Nt~?8xS1N|ppPB0m4Dk~Ht{=?NCuJo50iD*%ZMZEQSQ>m})@%H$=z`Zp}H zRg_}C9|omyI$ssNAUT}*zV+JZR}J!xUitDbJb1GkZOv>S4(yE0{dK~5pXT`%M*-GP zFRuG^0Nj4TE+bKsCB3w-qWbHI7`>K-vYcwVlnn5~yi|Ki{>Z)P{7#?5&dCZ=9o$K*r)MYgdc~!L++#d>6B|?|1`7J+i&k)XYi6#C~&3%FM066JpP{Cc$ z4J)Bql5274J5#JyTuM9T^NIV-J|gQgW&-@*nl>qf@&fC=^@egxd0(jfd+nO*s{(ss zym`Od+XaT@Jx27~Aw`)YvoR+}ssgUn)R=tQwFlBV1-p0BQNA!wf3@h5Q?LIBp^6p_00`oqRW~$%d~cj!EL?iEnNvbi_i~( zhNv1KSjoXDxh)uiWZmY_0Who$0BFMMS1Tkz!S1di791TfUH~%`Zbl*3L zdULY}Kt=-Si2^dsx&l2P74!)P;oIK3K8KII$X$nVSPKa65hLaZQz@o4As$h}shAb; z3^^x>w*|sYI9$%SnVFu2TgSIIExl!g$L})}zGoV~%@aHPDU7!qEv={Ir*u^YS#?v= zLrtMB#yMj@ULJF+LyADG{yijxvuz`a25J)!e|Zubz@S5h{4u>;@q3-Uw`w&bN8;t+ zpzEq#PPb9EVrZyPj;%qPzP^zPQtH0-11H@#-R=SrCXH?nJ%d2MGa25ix9Cl$_fn%S zSUE6e!+*+k0yFN+D-fM7z-COB(+(6foQ=E=*G1@=8M^iL`5!yv{~9(m(JESVWceW= z`i)&mtBabA$Nx!vVnq*Fwo}w=`}S=t{zpQ6PETD@BI@zgVslny{RdJT-A1m{gt%{s z8C=OLZJJe?aJHe$j@xqxHDkeSZlBSSl|G5>U!rOOGu1W)_$~ijK_D710e~xT^d^oH zSM(BCvz9`eCX=<{?OUSjQTtu)qC^sD%G*3 z>MPPfW2$?v3YHA-p_CE7>)OBcIvB-PH*^z~Cu+u*kZn3|sP`yyJsS}{z1AA+y1rf= z@%jcsu|i?JlFp@-k`n7u>zDn9^^>g@m&ZoLF54JCG=8XZ?!#+=%)ByW-tQAKCjwLk z5LVnbGOW@KjmjO{1y~x|Bk%-B9eEGIFm!|9sSVa+ z+KyR`l5*U%W`}$K!z~`EN(I}i(F1nJ>b>#fnSvI8*KN&woPw+>=Wln)GnTs^zQ1Tq zXt!$CH-0htBwgXX%7yY9aShSYym2xMu_3WCCjF;|7}}m|yR!$5%Azaf8s}m>X6rZ$ zrA4+@i*ajH8y=5r9r72OH(g3o5N7W8zA9SLCw<5_RZEY#8HLLA%ZbW@H2@7+9)Re@q%^fCpIP8$0QC;GXyyPDCA4CY8(8g*^$>*Yy;XqTk%! zgT76*`vvSK6K~%2vnfnezx9+m^!8$1;&T-vZn}gfp*RgyMGGq!7>>1MhA;7KXGxaJ zt|i80)z?PKrj-vF;l-OZC`&!oJKoo)TgU9V9+}8MqHPd~vL?xcoO6Hvs@PTeqw`iJ z>x%RCDsg`2O2`M?^5q@$;qz{!@p|_%pWLa4B+kf49?LUyqvLW6PCx$CF*Ck}6Km!%HcF8n?CDAgWO`(S zy8AuKq!YJ-AV`5wTID>sfeg_Y13fy*dz$H12>M3yuI^gF_2Q;`D zU^MM597uJu_^makhaOtz!n@2kp*CTvchqKc=ov;#!8`6dY&}Jh3pVFD10nrD*EO~5 zj~rVZM8uG}NK`xfJ~y(Mzvy2ld`YR(|6#xDc4&yD)TRc&=4@Btl$GZPpa`J%1Qftv zB9-7`e^&@V?Q-CGs(=Cqx$eZlK9)wK2v$L^#X^_1D6z2aMzRSVIM=a;i3iESHxKq} zj!pL(OpYC%XQYoEp0C*hhv&aeJfW|Q0a)(7=|8om@aqR*S-}mGjkh7|IaFnks(WrU zQnt!C#-iC7j(P8~ahrn1B{Mvhdc98VuM=L3)L-cetkLYxHlop(`p%KGgkia#SMw$< z3QDAtpqnXP=Xw>Vv8+A_XS-SB&rCe|$ec&lFZbV?A=A?O?=YR_RBU(vYGw_x1imI% zyc{lDjt(wXDaVCCXR&e2XGNocRJ_c34A!~0YXToJqofx1hJV*@?Zbk|o42KAS>DD! zLYdeZ%PL&5ci5pm7m2Sy86{>}PNfWlZGFBar8PQXv2SVnr=SRDZ>pS|$@8jf&|90@ zRrt+IZRc&?YHFTEgl1k4@LO>xD1+IY5*+T-v)j)OnwI5GbQ@Yrrh+Fkp+)uslNHOu za1z#rQtju}bv%O^^tt}q$~-E{t&5(-5BmhN)~_UR2L!B#RnCV!+ycJY_=D?fTg1d5 zUtonI0k@~Tn!6hZB21}Ix^y!2n^M@&T9kwivR>X|Oknsul9lKuvbQa+v~_E9b8h z{A=JapXGraY+9~@Q*V6TjRFS9HVR@s2EmtCO(rOBfY24}hpeIR2jB&X@W zPg1}F9u{wrI{H{Z;(Zx(h`}(L$~w*-5PjFfQJm4?j5njYvK~}POP78V?)`pW%8w(h z{&oK~x0V{tMfMlW+g8MPU`oxD(p2XgqdH>aelPGl=QQ2mT5&&y=p5QNwSg8~B5Awg zC-?D>yAB0Qjr9yF_J&LhMusF3{tUl*Z|znr^j3AoN+RuG+@1QRi(v78iW(wQ>96S7BAf1TjndizRrabsJnsMgd^IYt*V_3Bc)ldqNyPi}rz zSgG{4_pCJR-nWMyy&O-`Ho0p4K2CixF;3$d>{2W;D;8fLSgTMO_T$~n`4&pOQy7^5 z`GW1izJ~Rxu_hf3O)*o_(0g!J|J+7M$z8@_Oje<^t+rgM$6&Yd=ZRMfDUqAs9ZSBx zXK8+%_lNL<*EHx%6+cp#x*K2O#gsOOH!-4$d11@+d*6uj-;p#^%n)|IG$mfo(9p6`d&XiK;$J6vN0-NaE5(Hy$}|9Y z*FMR6Zw*~=^o|^+7fhD%3PHZ5zJk-B>HA|AF_Y8ACGJJZ8})Bun+aihvsv$X^ZVV> z>vIYsvYh5eRqqSly{<`ayY)U28Ih7#iH>Mz0qeDzs?bdg^NJ-)gu}2rlUKqcT-3<(kFAE64BDP| z71u(!a+SEkOhk9P8z5h#_Z(MdFvRX%=u3T3wLqEN2`Hz-FPGjtl3_8lgcJj_e#wM! zvbPzTGFs$#_p#Xbrlhg;7t7x1zp3F#pq=b zBZtB_)!R*BNxHH6KzuX+;TTv;HNuLouI^rT6^SMC?`-*fZJ6xikwR)7dEcGSm*)7x zv12kx4DDGVtWQ^T#b9)xS5m&KYp{j(q=w-z$Cs}3sHD9=z>@%(!WS@;^VA<&=j2~! z?;Xr17(T@ul{17<7OPy9Zkua*xEkKGB|zy+>^0GS`pVKPGdmxVx%cABVDim3nT0R2 z?F!n968VZU8fOJT=4e7rh^HjpOAU7`kA1MWS1;VaCkTdX3jI6q@1 zE09Ot-zUY@!v7qv{@S*sqeRe-Ib$J|J~-8JeZ@+o_-*nk1jL=LM8q!QHxRaPdmEIt z<6A8aGg>N;67@B(&usb5Oq*5bu!828$j@zc6V6DDKrkdkDCiETS!i&n6s0q;rdbl4 zKdd#q_uq@-*R8BSRu{i;n))1!g&x_+{R)a1$A~(3w{3r;UT%CLTVSofzFtiFS<&YB zkz=-BOVZX{-^ky(FsHp+i%DDXcb?g^xEG6$N>sxhF|WN3XI%T$I4cbPVXiW1Y{y6Y zy^9;P`SF+_v7s-$ooa)UW|Pb-?G6W_i_If07kW0Qa|)CQkAoVOj6aDloXNT;ofDm~ z7#CMzDCv3Q;%qcujEPbTexLCm3?X~$F&Rnd>W?Nt77=aKwZn-g?|jW|u481VYazG8u;57h)3>K4^V10tcb+YdeaJ&t-DphUyeii{3kh)J zc()aWh@G$qEA{wTs+$R$WsPLy6%CoG6O~}PioRyWQl!HEM2hRn!ed1A<19%NQwy!3 z)0aa=%Dw3K7O9S;ZVz(c;Rc)ttwvT!X;sw1?d&}DHx%CMOeFW_8-CB*@qQeLdNDLN zc8^QvboxEqXr)umDS{*XNy_AlTTG7LPkWn-b{f;*l-e-B#oh=6jql|_lG=HS3cJkz z%zYThl=80T9M&Ga3Cu$71isuF$TF_=EE~f^@y=aM0Z?+#U>Cc=SyU{fV}G87uHgaf zJTS#6SLBAx^?3mocx}^4_rFfOXaxK-y*3`dFq5k6=0n#voqEw{KC^p6XRE5bPTAAi z{#pn>8Z9F7M9PUB@WT2E5`z!1zi0YCoPI>ayEZ&(lvQN$9ozjubdMXq7qewDooc_u z11@w}oJfZ|1~GZ~(ciAagXC2S@a9TaR%ah22U2HCgG$Q9V&-NPmSvQRhxy34ChrYDz5e+*f;tkDk7Oo&zKi^D!!b+I6Z|mKf zN}ELsO2v4Q(+e^8Ae*{&$*aC+o7Q?W&X`SnDQZ@Jl&Q&XCsnKzJW}u>TcHy%GKGuMvkL>7TUVoivd$zFaZQ%=9f`&rmE@lq#;#TJ`tE^p4RO=m;80kew2~dQwj#<4TUH+CeSp) zmL#Jx;0;m=KBA@Deq${g>8m*8noH@#;S+~gL?na$=ah70jG!{($6Y0r!%6Pi&kjoRWB<9i zRb;W2giL2sYVF?cZ}U|8MAW9#3JUx=dv(2>M8tQZgogP4U8ehgNw-`5HHeAgUu={OhL4ehVh8Kx&-ll)OS~`g zzIu9Bk9?m{!XN!zMb5I zj=^joQHp5R;cZ-}&@Thd+AuCf3+OnmQb7G0P}iBcpA`DwfZzrSvO3W;!cR^A1IV8H zAHJlm=_@4kPqSd~oxB7g55N3SPzIE{L9yE4#0BWx`?1pRYF-zV#?6HQFPZK}q&5tC zdEDV2u6U29|8_)$HIo%cMfjUHf|L`;)MN82=c{=h+(3YY9{=nNSj{2~tYgd4dY5(Fp3=EFEZ-LDfdx2Z%aXrbW>-E0=lFCy?*7^D0o+AnYRB z{)o{~TfE`$gSDLwZdiZW?IbLE|~M6jz77J=#C*+ujO`hTY!w zl5<*6)4-$L=fpfKO*n*!mF}-5dziGwyY*jp8?_U>=x?y__}`ls=Nag}DG+!aMOU%Y zek1!eC;FQ-$f^^@b`KBnH4f5n{Xo@K3sl|CP`wGC*NDptg2`Od$oHkJ%>$~FU&Dhe z&f7x9JehI4MwH515WV^&n-=^-^cz~^`wE6PS%DoY}Q^ZY`tU z_ga2JxQfY*%M1*bE~!dn^%P-2<}e8emN1!JPY(>zLJ9yaSL?(dv_2f`7e$oTP*-HK zUaR$IR*p7yDHEOW9LtffoUKAFSe0uWJPa3C#9!4H`)0I0M|gcQo^|l8sJVVS#9Qwti)Wvix%YL|l(r+Y*908}o+9HeE%6E0Y~zIQJY#7> z`wH7yD&FoZUkH^oj-tqpR1~3*dX_0y6Mu}|Uu*X%9-72lbF=n|?!Z7{_Ac^gZvA>% z)i%;>Q*|)&^HR$pL?EB z<`6yq`o}Xd_f{P>6*V13qy37C9d7-Hk!+56-)OylpSW=8F$x9kTI|b zNl$Bu9RkLYrzI6f+$s`DS{|cBod00(0fNfL8|mlB1A<%kPae6dMEU%K)_0*N$*Vs zgb+F;loWpt?(R8f@1Aq-*TbLJ|NEb;4$@!6PH2o+A>yTEpoH+Ff#^d{Y z9F~(3cOvra+FU>0+0YZC=Ag=C;>q)Bn9X#s-hC@=6KR3}*!yb1FFAm6B{9F#3K`(& zSGivVG|?H<(;d+DIb+VX)^>G5i7nKcYkEV2TO{eQN7JTy!QagDu}fG-Yu zg~s`<2R+GyWfyUlE!JWIj-I2$0Jl5myj)G{-LC5^pB7rHDHf7c{b+iFGhR;Kq^RP2 zW@@!GoIQQ(*{Tz5T>93Czxalq0cOm3xSCgKdZ+Tv%ubbtOw>)ZfCrJ~g1o4x{nH{X zWBc4Z-=tjp(Zws5Jd3OC3rb5((sLko^G$)~G08{0zFr zjRxy0_|25`gsu&3p6q$AHNbx&P)qonBP~@QO>h&F7lVby>|j1MZCGa=eksJJg<}S^ zublbnl;%N-1YHmPa_X@e*}10Jgi+Ti?}iOsI+m^}RBi4ATp~w}Uy@s~z@Be{@y1*} zy%J+d1>_!2itT-$jkEaDx1FIW&^~d>1DtupxOi2afwyc-fUjqeR4D-z;2|&xc|?i) z$!o^*z7`$K2|x9=56g)A=$*B&keA6^P|tK9n7ihYG&D&?Ipi6!_}Y1?dP{GWw^VFm zu=un9=mH~#p-mY<)H+S;iw53ZF^Sw0lvkAfoU`tb-B*Rm&9HNUk&8H8HWqVF zoF9E>j8t3lr_Q$azUyhz$oCUjivr^`!VH}78N!&)_`1mcGcvHqqKQ$@xwXpPSDZ)o zOY}#w+M82yXA1%C-aP_%@=>uC^0UfS!ySj9j0H4}Ef~zE>b9jj4X#HDOra!Ap$$ zC1I>juis;ZvG*vWP75=qgngzsm;OZ~w*3sfd5@_hW%J}n&U1oc*RKJ71tuZ|SCTN? zqZ_)@z+t+msxXw>I{oOP2FXPHk|V&KWAc_ICSbw9|c;xx1Ss z=ayqgSmR7udUpi7@JrQ5GG0$1t@6 zdmSCatM8{rGCmv~MeGla;4|i9<}=L9&CbpZITysGI3+Jnr5mHBVKVQp!V=Lwg<9DT zJ#zIo-cGttZAh{8#Y>2Xpq z=j4;&Ln}H{6;5}GPcsCH3Y=SHKp8K8xp)pgP*vlNb6XO6tlRN<=JtbwXX z_3&V)dsCC^Bg=%)iwtP)FLPRR0d4D zD>7SqY%GV#(kbcC6_aFZXUC?H zafF8Jmzi5@Q||TN*N<*^MqSYpppm=u=z%My?x9RRZk#Fn!HVFgPMzhWyth4V-qMAT z?>5!6ulGBmSIZL=VC$DksPTroNw!n7;ufmz-+lq>gIEXg0@ zUEftBbU=+zvlaJ_t4-94HkA-j#iASz3lh(xJ4`EyEOwtZg%;RPLow zfSlNW@pV_qSauzMBH;FgMpF@R_~Sc9oY8vS zPw$`gL_MGHq=njQUdE)|2#cPp6+;8PMBqMvR+1jfbd9B$Nm04`@(0;mUAg=DtNE2@ zC8(Aex0h03;{xU}Ez_uZ=EC~3Q6+_MBq}w8OV(8QBR(#@2V=W8%@0d`<|y-cK5TSC z=P*4oz3J=RgmzD_mX1!hmdn9@Gos<^mvn1-5)n#QTn!*HK-d$f*A>&jD6QT;Tr z+>?5W&1Q4ydo8y|(ge#@8v^@q`$92@B8m=d57$S8myZV9IUhYK=%49dtOU4Q|v;|4zVvRUW&z;y&CKOoNpBmXT4!l zYb{igul;6SbyX+CgHv%v_vGEN%qu7=Ka= zu@Xng85Zt;n#k;!GJv@1ph+8rE%yDO_Xkur`Tt`bUGTKP*&~b>@s`hM1Oy~7Ncrqd&jN)3)FR|rg(B-3v4`y>q@8U--T(=>nTa4 zKsX2r?}wo_)tBo}l!$uuRK9V^g9+Di<5`QfmJmhiNhvIL8{i%!^F0| zq2nwjE|yledZyM9NHKN3DWWJ z8P%YUOs@rls-DKhzSmPSP+1MmE||Box0|Mat)(Ghc=^NJDqjEyw3$n8{sX{UNJ?$%R)_M~?t}6t_JvFgCccJjU z)TIKp>MDVf^Zgq6nsjSyOlT}Aw<&(|wsUJq+xR36T_>B1*Nq&6=zctr;3- zLC{ornT@?#WGkq3-PlTLsu6AG|X>O2+MvcSy)YC?LTR%3<@cdK5+O^(Xay}0NS3w;;+ z$*n({x$e*@`jQRz=Jsq9eRhDpoT~yOHnI5A3uYVXw_hQbQcOq%$Y;E&PR7uwK_o3) zma*oTr8__78m*{!tnWC4es+{Z=jds%%EMe^htqiSJ=lb zPuMHQaa1&YF4aG>I1#^*IC1@=HQ~}o+d|{(5fd9fhsD>*8>biZ8eFawcY*=rLhjt` z=KGUF;l>F`Z&o`_T%e?G>4!W~1GVd!$@>S+hc$wV6w0a(yj)gzG89pNi_&^%xU9smZ3LkRA!qrSzIb zn%6>%x{$*uYW;rw)iy)umH|KHs0mMQMI@(AWj#Qq9oyCRLZ`42LpxXk0h^1;_Dy#) zK5b0@!B?9O&8W|C+blWe+KefE{_QzwP6B&?Q}I^7>eVdotIO(fTjEOd{SG_G5v9FA<#3~UISevrv?(LJfHmxCraCk+w(iHYPB zQ($u8BHQqTg8b~5hnZP4F9?)#sTEJB9~#~EerP4YQb(`%Smby!&5is1uX_*K*|AVZ zaA{vVmd-Iktzga>ftgvw4?VA@Vb@`d%PPd&Sxsa%yy&{k>gPZMic?Hs+QqD09W26b z@6SE8;x;^{xaki)4+d4f%}jm-tkF-R12)HB5N6-dJvO9yd%va2dc|mrx49(Yy|qi? zb3JVXi?yw=9NLrO*usLmaGt#U!2T&u1BIh|HZ=}kiOM3-#vZvSayFi8A5tFK(cQS| z|I|YcQNImF5Kl%YC)L9@dEYfYAFsz;6w2MfiDaY*l5{hQ)3=saHw){KTNPWC z;xr*umtRPHb>q04a^|Dcsk0*Z@~pyyp2A#t6`DQL?7c14%ynu~f&{oSQTIk8%`u%8 z^^>SL1fXzjE*MLgp8RWuP6x|FsDwzXw9r_8=oFj-7w;}mf?En^W0^%H7wf? zhW1=S-MvUkkb3HG}d3LG-eL*c7-^;JU27@&=512g~}C4f(q?EybkjT?JRX_~2;)F-@}Wr5XFsRa$vWlyBN&;b=IP^~P5w!<5BTiYwBF9z=! z035Yyo2u2`AX}?nrPUFy^l~~E;9+GKaRV4J6*I zmp^(_r@24p_F1zt5ruDF5Bsp^cW2$Zfp*=(lNu%I?`gFl*|zYj!FfAx-49!3nSKr& z(bY>HKR=M54dp^iiftNMh05*iWFFZ6v}BFi&2Xz;?8IQa@a|W60=`OmaBZXH2JZ(6 zYtAE+ew=;K$)Hhuuhr#isS`NU#9_mB9`($$MLwZxp)|AdCXB*s@6dq_B4EBUm{y>|-Z_6Me`&Em^6gSY8Sdlw5MHFph%Y5^ zm?-GDyjY+W-Tc8CW6)XaZ7O2Q(xEF81Uo6`BVvopEhb|X5wSzJK`I4vDDlci33WpiaC(czNwk@#%*(Ogc!C#6bf z3UUe_DxJ;GOA?Jx9FFcQID;!*ohw{Sn^|4quv&sPHF$XgWoM${?I2ba}Cf0C&C#$ zh}uwdOKVHpM$8KNvJTw+6#4dMqm7`cK^({^Npu>aG9(QK-L zuXU1vjkiU+5*M+i7B5v>=mTgU2gw0hfhsC0vMOrw@@o6p*jSJC^k{3pWrGR`2uN6* zzfh3=c%Nc7)pv)CY7Y>S0(Q_BiJybhpOK`#?Wq)=14vcGqU)hI`RRLZUu9`>(9&HB zV`QBffwQtN=Ny}{O^=?oV?S*CEz<=EEKX0!8V~M(90(t&CNevkjpM z<8&X#p7+iP3n>bhI{4YWsQr^uR{HmPjycpe`}({cOgb!kA^?6!6-Qd z*BY9jr58h!q~VYTfVIM>;$6HKTM&pm+kmZ zyyoL7>o|eR%C|am-*4GuCv9}F0WdBefuvXKrdesXNGtLZa%TB?%e1>u=|d?Rx9#U> zPct2X_||*3u>3(97h*r?ikSMtIL!?Ld~H&FO=ptqOjE|6T;Ymc8ky{)OcZ>^kT?mn z5p3K70yH8}Mn(w+4-Xev6(uE=qaGlGQMLN`R&H+IZ`bwa;SKfQ?C7)aJ8Ew9@9ijI zcSmzF4<0O#|9MB%WYsj}{)s}bn8T~!YRY~ zJNv)~pRV!>>cNrA9}HioySq3ZTPa#|DVDlMG@|>BrRc=aXu{2VHx3_FpxzS{%B&1A zJhm?=HI*xzfvS)iO|Pz@PQ{>ki}vBAv8|L<%jpAmPrtklW;S9di(`g2%~w=K5w#HK zl6qc|kT>KpkhgtvB~fiAyg2o+xkOI~VO6nwn{84(muulF?ST}%% zZgN((=|Q3v(PvEQ)s;$3bmbVNskRS$oF@+I&&A!l4+>NEQM6}y$4$3a&GW9G@b2#w zVYA*S9f^C9vS_NRTjXl6Ebzj1E%q_~NVN_Tcy?*^v{YT?N=Z>pH`puYC&Pa~GI-n@I+}ym-Y8c~T z3gq7IsMc4Jy;+V+=<8i96O*UGK}sFHyzq@GYFuCd-BxS+75?0j`nDsh==42-n}zhs zi%q6cA@i>Iqgk@LnjH**O4=hz)VD*YnLT0QTnsLN`)oenG;@JeU1#FfyG&cZb-O#E zqeI^Ok_Jm+hok&Ne?r)!82-%41K#fvxieyTH0?&BEmzjgbsaj;43p4M16fe!!ozqA zGi)#U{HmaBmI<<+1=OfV){GuNpPZom;%|B$ii?2r<0kNfb!SYcNJUc5oLkuNVm96e z?`Y#D&;drqLPma{h^8*57u%waoMRrJG_TIixYwSoC@X2ObYy?n70L4(rdHAN4EW4F zQ(buKcTG=RJaVX;dsjQN<{Kra{5uLD8od38bg_$M;|8)zBmHZ8>%$Dxkz3b9%~EkEQLPhqa8f>+_94^B>XU z(H3jU1<}oz7d7#G5#_g@^Mz!buyr|*?f~7YFUz7wN}{E&d06`mmU@^=O5ao8>R2nK zhSf^KHemXj`WH`gss*dR8Gd2<-t=MO5?7kD^+gMjgl*Q72Jj1CthHO;p^iC}w5=q0 ze%UkCZ8wjcVIo!5$$DrxtJiGlb!~Cce2z6E_T~eCguWj&YW@7D*JVV!u z14+s;<08T3xT(IamiY6qbu&msRw)>q8?lPk~EGf@vW?Qv_pAjXV{@sY#b!e7+Da*)~$rzasS*2TLkJNWqy^V0%iBU z-kaxe@jP?(faAi%#=UTL$y@D!aS+d=_>Ia=F`{MJkw5Ib5>9&0+pJ1-jcCgPIxl6& zG_sOVd&|MGSBB@JyFjiu*emU!nk%OPavrkeM1Pp>;8b~7?g>BGryo%{8AS|SPx-Z=Ty2jvxK z$0+;eKA1QZSLHOPq<>3Sn%!689EKzT>8JWIXEp|wlVs#zX2J%Gd2fZ~1x}YQv(LrV z?W2BHf+GW62HkxqnDAAF4%TwT93v(Dee}?f#f+8Dx;#~2{*!IkV5a*ciW!oM@bSCv z^|~{76zQ@^N;%-XH}%au8?1xA&7s8idO7}rf{$A@Z*!(56(;#iC8cJbKB+jZ=W**5 zhtrnU(Ljze&!q^uTF9o1fs2Q^>b-yw5tbtjJE&5kx3#V!k7Mmnvc{2mS1mn(2E9Iy z;e2Zb{FNwXz64?Au)UlpDnIPgn_7YJO}R=tBrkI2L4`NHQxV-8^~VnH^rEKEiZ7NB z>lrl+G>(OyzTibzOseNNW;UbQUoo)}HFFRn*>abP~?jIh-1)zMMn-Y>7f99;#S4&4@=};ya3aSXqgfc2KlSCYddqyNxS*09Aoi} zB+AGmaWxdBOfoY+ z9+&KFp> zIZ%MlG4l(bqqSh{S<85ZCe?mwv$;Ln)GM7} za@de-Hz{n3*l+q;D>&?JP}?#z zu#j%Cqr0rSIohN?2{t>B4=iFiLdYT&-a*{at1NBAV%q5mLtkwjzRuwB(U+(-;TY4G z@u@ki_Y0NuG=U( z(D5bLPD8qJ_nKz50ppfwB^Hz%otUzrY!?YuUTgZ^uDE!^2|ZcrX~xk(_bJC_ooVaY z3yQEMQ7F0KuG?s(t<${exKUNkL>x-8yA(`g_B`d|W>~9RAdpdbG9yg3?_BH#(cZSf zc0)hKClsIm5qyP5@uaSIAu~AVXmjS;s>>LD6zzO$1>t}~zCsK{MrHqj6Htwrs3QA^ z_AjRD*|hm`bEO^btewFZvOghftZ{)-2KLX-$aI=t@8;V!#8!GpwW^-%(Thl#pS8of zz8o7EEqq$iqZlot-g~8B52qcwl`>hRl_d26Kks3P;F#4|FW%xDQtM-@UyGe?e79gM z;YX`&nmi0mmKohPR`pUadUjew4v~p+$+pwn+oBqCZS96dyvXG$ep{;-kFnNgC==D) zsi1Z*a1Wr~vBx)Cy0M|6vfHPG=+8|Fp<7m;?X9vCdMGt{S$oh?!f7M|f#JFx=3uU< z-(T=Vgi`p~U+^nr9A3e3-+U#PBOW*+nk2ui*-_IItK0eY&#DMEHw~N?1DI|v-V9=X z=Jxemv)Z#KOsVZ(Kd0Juw{79yg-uGMu!IGJnCp*j3BmF3ah>5vlkWptb_)uAwLt%` zF1$lb8lOX-cd4Fq>Zg8Rs@*JQmTZ`|BH8Bb*kGk)tlen7fVaY^%s`%+U|ndM2AK$_ ztva9(?-KH0#IEdqxwp$tEkXZ{0P`nW^}0IuOs?oq@XO8)a{vAX)p|qCBcAn zFOl*6)jN@Z)1@AoB)tg%?SuWmTSc$2RzEP$!%MAdfPX0|+X<4>@_^Cj0MC^F@r6R) zU-(N4;-#GT8fOqGQnK5i8-LG{OPyEwu)UdflEsJ>7%M`0@ummTHpzV+Vy9@Xx#N$N z`n=fq?6;KD?A=zuQc`IvyY2ivLtgJ2B{yv$HqCGl1y8!X*~ySRGu-9y$e$+g`JPKJ zi`3~vcaY|A9<*(kXEf)nw^*Rd;F~2?`{|6T(mFYoo8C^;HJLuJL_`vpHtX2YvIBaM z$9vbw$WbC5f`@#y1ig_Ph=XRh7M6=YDT3A=fSap=7=}8eRuBjEa80{Zw~0A8kjk?2 zyMLYjlx$vHb%y7{`>&e4AWoWKiF=rcF}Vn`zLNkbjbItoW}k=|ubnF+O1*&`2TeH* zMCKA^OA)J`#(z*u|JH$fexPAZJj{KWKjra+T05M`}k_=(NS$42t=inv-`w7@Q zO}@s)$?7WPd%w^#>!dnnNA0_GYkAvnHH238&%;aq%@5e!6~JBoOJDLY-s4vE1{bo( zZ$6+{lRdXre`|lD5lEAm;!U2=iUVf#DE;d%%mJ!8*|8&A&FK$9U9f9uTrm;ntnmBE z(qKT`4niR5L%~)98p50AWD5$ppMubNZ<1)4TCt_GEjyGt94_F|Wj840h*$qvs}GCd zKR2013Uj2Z9hLj?u`x|Ea9C;4sNPHi(vZ`s}8l8=sY}%JNxw;)!;bGV77sZ zp7pjz!KRt`Tv{mtoV*DTlKTrkrzE7T3H?Av9o@qr9z}~6P8B-*A?;;p1pj32b6|Bv4N9UT$j`bfCC(5WWzbTm-2t zyH3mRP}kslNL0TUH5T2~k}(Cb5`J^lj$w$BfoHbNQGwH<2a?TK5+$=n)A%Vc((CQd zYy6l|D6wKw@465Hsh){gt*aeTQ_Oj6Q8eQE?zNfR-4-5L5Me{W}G`)#4_ z4mF)4L-rB2!)gy|+1n59)13BfthzkrXF9;qN=IQ}>;nZJ;EPW{_W;U9-rdXBulp@F zSQAR;pTj(ysz-emNIZK!>uq_P%B`Y2MPcZbN8r=e32rLEl2oR+bZ zwpv?#j2B+pStxp?H%vDsh-;3_yN1jMRh-s-It5)iN=1~k9;DP4D1ag&7qXiO-|Kk5 zlS{vaG&#c0D4o3k|3m_Slk-}Qr*a3W1gcja1NhL_mm9M?I{|6Fy8A4@Ae+uTZw|=| zwoHffL7O4t4oAx`P)J)x2?>xy;lh zgiMKA8{8=;nE7n*hH1fuAk$He85<-}WHV9cUW7aG@K7xg`5nVp$?oErWi#?XUHh@v z+joimFtbvllVa3Sl4*kzA*CibzKlM}w6x7qPu#dw4^jfz2v)%#=jWznL4zT7qPy_( z>=pi{iV|r!Bu0|_w$!E5bSrtMln9C_88++ibrCPQ9EuKcJ|PQ|1(xOTU*K)arUpMl zR7A!uetEU~cl^iLOJ&kNWWDkxrM$2H#bBQ zVL^AmRC-?990eE^>Zj~TXO6L@JK zeBoY9!Es%QJMYB>QT3wWqY4WnOm(5iyec> zUv-RdJ7qc3+u(j^&soLl#=ITkC7;7O67UQ0dyi8k4HmsKUw3x!`0z6j|BpdFQ*#`J z6@j9SGYLz5K^#>6GjPkbxy3%oqn1aj6U`oLO4n_+aBdG_PKXzkJ@BdluI&FQ+*ju zDlkbDup+vtLOCSSgB_?0;?#@=iPw4iJ|WnAnI?(YYdwAEiSzPehH<}%`yNoB0*fn1 zE3MZkt=-r4@xr_%otCI%-h0T6wLwe!Ec)#R?!%pS7pSFX*wJ^3W4Hl~yNMLMT`?+7 zXK*ho7F5F1(3dnnv%*gswBc5gPL8#`oQTu0Z+M83LDHcXNt4r*0Y4AjV!E9sNwitM z<(C7pXsMLV^|E0kcP&r%%>(anrsTnt`iAnM`NGiR%KmX!ulO|~1obVoRG;JXsH-AX zT3U)Y25miEJp;Y>Z2ZTYM!6&PI$pWIvRT+$>WkknBRKx2@czFC!|T`y@E$x*s{0FObk&-^^^fJ)W%E1i*7H_K->bXlF{Ppc#H$j7W5}rCa1ivw)=u??{(?NVh>h@I+O2?LZU2Hj=wzpI8M^ zs~eO?@GzE@*7#Lv7v+};PhWNmgF&tF?%R!T>;(6&gPQ@UF|PP)I0h7%G(BXM&06=&Lr2Ow8Hy|3BRilexNK@(B5gP^MGhn{1(#~#WAQH3pm-Wj-igC` z!GlsAnWm~7yPk6w2L17v z;N2ixHXel5O#uUMTw-Ss1gJqt$JXK9Yk*y{8=L%#A&l?$2w_E*vu}(GJk|yjNc11} z;&wfpx)b)Tz$p-;MvKuVKG#3VaVh?T=MgZy8C{LZ4nimq< zB(?Amj9mSac@Gc-CPe}XHcSK+0^N#dWB6eGf7wZXjth-UB=c=l1-6E%<>T{_6jVTS zi-F_;lmMIcb$3Vm!mW7bR&-87*;VbC@)%WmDXC$71@5kgnx7dCOW2*s3dJuKtff&v z%L7vJr!iTvOB{`NuVlJj8DV5=;#(XDJ8ur!nctW)ByTEG&rv;hD6TRI^LDY&s6*Z0+-+r>b|+PWvT|62{>!Y0YZLXn z22feP!m3B-_uM$AAe^3#^P^*5{L2{ghY0mQ?o>%68lQQwcZv5bq2j|wE|=~=DzTmp zWM>tV*92t$zQfG;TXvX?13ZHaPExhZVp8VXlWDhoPpDMvoaja0*-QtyAyY&#AAHl4 zILYd{RJWOh1wV54u>6n5uzu4?d^hj{W?9aQ$Qp}NOMRWB1WMwJJr-2-slP&QAP^bU zf7SszOKGa7W#dk8g?cah@%*r5`!+CsfZ0d{vy3(8$Wyh8YK&aL4s@HgWAB(U*XljN~Nu`@8SUl`jcl&e(g5`{wG5I zIX~0)E^vA4*XT&XC%1vAp8-T182w1;bv5tTnkVgZT}%l7h)5JnkQ;L#$;MfT&|LBPZhq_8^Ta*`SYvXc~Etvl!8 z38`6GGU}D*=*Nz~Uj`W^lZgSWGk(?icbYpJlpZ1utgE1Z9<)j$b zRxK!$gj@=@ac(2+&C~D{XXC}~#(MsSKYw@6|KtVM-KA9%d+4BbrM4xA8a5S@#_))pljZ<1jnz5)TgihI|vtOF|C z!uvU%Y3OcWvlhtVVwP?!mP*5i5KKhkLX@M^YBNJ>hAlJruL9GToX72GzF4|=;)1&P z+{>s^_Lm6f!tePu4_^)wMEU2zV6#m#^dJzZzmg954IX*HQCjCZ_u()tP?3MHANU=b z`j;097=rpQr_D`GMA9aM5ne=yac`OJGNsS2*7&f8{P`?=@lm^a=`D9@+%`2zJS;d#In;HA*+xo#gN7@DO7h)+{u^O~W`o?80&KwW zcR2Rr7U*}T9_HwCQgCqN5q4v-|*apFTtM*EM?t^e7zDno*d#zy56b01ZhvlFzo=l*&30mZI>Egq02B@d!> z)GM%3sZx{3V6;byqP3>ZUznFgem*(RS+VaWzJ?gvbgNK>n${ZKp`EjHf z&zko+h-3pDZb6GWP1dnO=Tcpaow`(-Ql~vc^oJqL|0`N*x}?RA zzYSRuBM&G7wdiAX$IS}$OujJAtLnLBKynfvoZR~XLtY?SeNs53MTA%Y5UR;Xc};Oj zO>dLkxF`;R^_`tv$2(iC8@@bs28mjj%LGgIl<(>~@P*aOKUPpl-}a>GXbdJh+j0d) zS*I|z?3G_V-kf4hc)fuwL2t~C-^b&|;G1=+e~R7nJE@Q}pR9AcVvK)B%v1TZ0mX_} zj>0xOVrX_Yt@oM{@w!KukF4(uxl_tERXvnkE^tels&1Mk{9##``0mZWxPxDcNo;t0 zT=+_2^i)BQ;jwfqm_40K=@cdES;Ax#4pzJdnh?yAqs-rEkaRV| z(}-Wo8r#26TKr#AXluLcHvNCh9{z4q|5q*mm-x%YK{PO*yT9Bz$U5)|Cxl+W!y%4`R5H;uMNF>-*Mh>g|y=WdhtI? ziYNx~5fco|Fe1x-@@O_*W3Ii(v^IP}p=8cb4ylP~aIA22tk zv`@v7rM~!W;p;4m9-I!D-APrNnkgITV#dot{xh!XNrR;kDRi7LWPr~6MjOcwE@ccI9$y+xWGH{Vpte$!TZhn$HChN!dI>Pb}{rmh9lpQjgKtV&!Wm71j*fImz{A zGpC!lTrt%HUSI8$KYe*ggy~tzbb0Ds*N|8)xe+NGQMjNMaOK>WY4f2>uH(%p8BHpT z+SlrNv42_c@gt4ZUui`CyS0&9pPh8`){r5|F4J~xE%uwBUS6-=TY1+4=lHCWu)fqD zv*eI*YDA#Zpyt+X$s3V0Gvdm1e7Z6Ak3U^jc+}!DR@8F(4kOeDUsAh<1G#$00(sCh z94qxztR^;(NE=$@xIRHd95+%cTNAf8YJ6kw-!;@4Zd8Lisn@Gxq)^%Id%C@9>w^VX zPUs5zaG4*xA3l2h?ox4iqv#Tg_X4P7A17+KPGQ$Z5gv~Bnx$ME#|V7o5^;$VqRuC{ z`ucU(3TRlnls~+UQY5@MCJzH_?*AAo<#&szbr)rKB~CAqZ@VWxm_tR*Xi+f(}I&up|*~b(mNe9mX4M_xk=iiLLFHVC`k_U`(mDKol)A@r`5=co4 z32F5ZsNYQtk8H`pPClM($ER81C&YXg$nUzx>|^-0-LDmp?CvPr+eAOCv*z@++*jsTCxXMT6nq)*TDzaMlWkpfF->FMfUN*Rs<0r*&_#T}y|B_qSW zjeZfygN!M+gX|IxW=0S82}A>`Kw=bEc>q#Z0mMK9j(66dpZoaQKAW_oPOMch{S(OV z`&(E+wTPUqP6^T+P%LE6XFo!sK#;RB`Nu%O?g_{#)+2^~bh9MCawn?C{>abs?e_4v zDA4{7gi$Dxlk;drMKb^fe=S`3tIu|$Eubdl>*V(!O;PJFv6zZEXM7U~oB+d7aSmi` zs3SKg&B3|j_2z0$u{(6BF6lN_%4Gk}5K+y=PNOsH$i7R)sk(q`EwiGNpB&*#M)HnG zM&8eRKcF%Aim6sA5_Dn@Hp#h$|CEQl%K_BfIS_`)nM$oZ7u{0ZI}TaJr8Rk$)PF}* zfK35X8&rU7_`_2h|I~;KF>NkY_f+mV$jGo}XR?DFWy! zKWceD&t;=srvmNrzW`W%^%8%l5dXUiAkkq;L_>EI9l5*l=NqYhh+O`~%LNRzijy+Q zq)!J%s>s)*dWWmyg6k#IX6D{HC%iFx6xtg++XZ>k{&wdI=qTSAOdBj449>&arw@zxWWMLjmf8!v<1IsDmLf(rZN+2wzE*oI%M-pd8i<& zCqrat)}8aV_v)lub-T7bJI5ja$UOg^n5x8pdJQo4^jEd_dqebh%k;?)TW4}C2ZV7p z{))HZQSkN}Lk6;_l(I%$Ga4x`)~Z^)O$#DJ*=+xV8vIVSo_w(ag51j%;8+f#kE^2x zF61gQT%9k6C`27Xmu_$RWZFeMUBkWWO<%uo6Hl+k6mKnG82ywj;_2b`OptoI@3^3M z_owF25ow45Y^K+!RFyK|S@N5W`73cd^NF1mk?(CR{^?zQO#0)~M-*c638<^X%fq`r zce#$Rz3(^Wt`cHQ(KG(xHQ$FxuE_M+N7zR{|3NcByCr)1^9X3u_xrzJ~6Ygd*#ql6LDJLS~i}>@+ zQLPMjY^13)t>O_kX#ujTB-+^k&_FuAQO&?sc(R$3*7#@(=3Ir?6}@YwyTo*M^mjTIby$tjstXwM2SS)MT>75cjY z%t9BBh@_Khotfm=J2O&`5|gcTRTIA0u-SY=_ub+M&HDjjxP7eSpiWWG%zQ;P=!lK@OE%%gul$zwTZ2+TV zSowhB7s`6e$CW>q+xj{v=L6I^XAmT6esjjUF!%0_O6>=8G*!uqP3zn4Ve?Ly$$H*g zM0$r*Fo#-sZKt85J>0bO=1r{Oiji&kaN?aF^F{1zh`?7dejy)&N2%1*1lsD^f$di- zhodbn9h^SqyN|=#XB}tVXv(+Zdyf0K3fIRFwd}LpQH)kvIZ7nDyo&HQUBd7zD*7>` zv%a=Wr;6OIxe`HZO`sM`j=Li7>|?YDevJKCtqB|-IC8We!T|~gH7t?K;R_tjAlzi@ z-?@f|0cHfK5kf9Jrm%u)f7CrVAUr8OCcNGKe{X;Ap6Y6hgCtZ|H3i*MT3`mC`-cck+wj^=Z>J@gwz@D^I3Ud zN-4%cE%RP!!TGfyUbrUj`00<)10lKaZksQ` z>ulQsqz~VyQYT+Wj4m6YY6jZ!7CPRLx%&*ag$|WNHt+O1^3R-htmErB8&g~u9~~=@ z=0mD}dhFCI(5fjlCec!%{LO24I`?zW4c(5K0#L^vZ$k+pgs8!g=wTWD@5sX%P!L{_P>jnf?@WiU>FlfOI2!Iss;gIupM52K#LfMgKL0v z^VlvsY3K0D9z4Bd6OPXNpayOJN2W*(;UVMuDvD=ZbPer!z)Ui8`;&WT)nk=h8ur6| zDJ&XOy@ZXO4P%N3+1L>=x|WEio(cbJyJ$EA)JH|uDG2AY`QW+F zA}F8^iR1^`Je>XYF(|Y8A07jL#%O@|z%*SReisw#D)evcARqrcQOKxD4A5zPcdyGS zG<{m75O*`0MM*4V=grB_;9-e9n1bU6-R%Lq#2i^?tf$?Pk;`lFFjxU_&>tt^vyi>0jzEa(>Xt`_?Y(mvr6hNMus4J#% z2eEHi02I*o?*iaizZ)3+@8H5ewSRx|EhXk%bfv`QPP8BT?jqJZAmaaH?!5z=?6R$K ztXM%`z(N&i(ygGOL{y|GgkGfx2uKwrq6rX11wo|>CdnzA)>-ydQ25>!2vq(%K6`0q!>1%J`W*qdM7Ez~&&i{U-*C76 zDn0M!+&{pg`YL2|q(6L6^n|Wuc=Nqo>79N!C6x$_bx@lil4lsU$!t!|j}W=a$Jti= zU7~4^^2jIKk0LAy%9(@XL>RVE@7hwIakOfuim)O3k6w3Io45;qiW*3g1svo!)x?Uj z5y-+nobTo#EPyF-C@jCIiPK8SmMleo2&3rYTs`cDef4v>7o3tY)W}M1G&##@M zm$}5OhCP=0UNcm1Oqih|I*E2T#UkFLbH<>(d)bGvc!AWgjDQtUFHQ&F4wi1&`hF0rq~mkqaL zBF3S0KjgG!aPt1Fv9zDxn_n@mKy+nY_Ak^>~TS9_2cwVGx zsC5!wFsbvY+C^!bl#`^4eGvQiD420sw9^vl-a841_Poz<$RLmVgZbgc_m|1IqQ#FE z_3;hO*%P0ut*3<>CrNfDRW^Al9Hj^L=Z+#fY-{2((}N}ZTB9#$tiYI@Rx1Th-z9x? zE$t?VB8L2TN>7A0ikW+R&zc2I1b_XQ$9Y(ns_^FG`?Q{;9SKpDMfdE((E_*al4V8a z1%5EuK8-^1q=AlQ|Cy1?j7VvBGw*H!At^WAW2KRwIAS4gRUjAdERsIy_fh_)(8Hgz zc}uT4_CK!eIqux(ShbYhQhXK|*z5xw7|7D0;E(3EDJiRFfgeL3>2lS>v{wGy`neWD z#O)Y3tE!A()`6LKF??c1dQHH@oWzYM-G>ndZR33F4X1<%hoQoqQIS1M+He4iN znVCijH8NzUdcR=UQ^~HAh+*}KUO4uHkNx{?HEb^VCt?JP*1M_hYX=^v1S1%S>Dnck zQ{C^It}17XPcT4l4<5Jvrk7%zMT$sq+Y!Eop9TVaT5cH3sF#($;6OjmGjpZ}6=zK$ z+h%?9bWdSMZ-P^QSj|-B3s~|060uMSnZ~Z`IW(f*pid#AGnrcCr_5WPY`ydI)r0Hg z>YIg6WX4HzBFbwGo#W^F$+fA9j~}18KQl=~@U{nM=<xE4aiOjx;%miV~x@fw;(TiXe&vpTp`3z`heYu7Zs&-N2}zphuw85QKf zN}f&C%^Y0+p`ofnDO>f#mHrB;^I;YsH$OiG#{7*%l;NqWP#|SMX3L|-E~3~G>{GHJ zNk#kYSeCt~H_v$Yg@(+^IFpgIr03@IvGi2`#}j!9eYOrkiXY~Rj)uME+LsmlPDJU( zqs|t^-@-ocK7zoi`0_lU4+2A}8v3UYEK-!OYMEo>ftSo|T3VI;Qf|fNS*%D*(v>2; zjGGuj`GSCY(1s%CN;bdEzCaCAJ?`1#2_HW@@d7IxBgmqXTVT7z7E8Cl83@{u>ZQ8i zt!7Qhq1I>nay+mRu}xG}hRkW3`CAvXPoDX47-pej%=@UTDVsMfYu}nvR!&*;DTn>#Eu6%w&JHS73hiZ^;%K zduv{}yF>grPvaa7_@mc@R?|$Z`-IdBXU%m+-?N;5zVbQ7j|ucy$Qf&^^S8Hgk@@-($$Pi^-pL z+0#j>GXNyDh!zCZkc+;k{3zr(w3$#+e%$>B02ylwc3oTGbPGG%HrAl;PG+d+!gR~d zoYc4%vEy}sNNmux6y@=leeomr%G(p3vM53_x!DTOGELEZ)VBJzpK)|d3UTQYn>kK& zwk`C@C&hM+!}ekh?!(nz@?ym^Pd2g*@LI}5U*eF?KJ21iZB|mW5_H42HO5lOM^`D* z6ZD~g?DQ8(F~@($Z^Y9POp{@8dAqd{6)$#cx66{#n=euxlpc5@k9Kh5HmOV42aj0y z<$o71*K9u(n2>tY;GKk|Xlim?|HOUsk^rok=!@(-zK2jU_(*(P#3Yye3NO>)Deq6# z@kztGWdUht%*Bh-Xsj+BecYcOHgyWo_s=;@{We~*$Xc}kr0m2$iMhA>;|U} z7>2`sJHj#=dggI_Z$ES~!|DZ6(#~~ArelBr%h~jDC%?lMFTH=_vUjA)22uT}!}jdD zi?))GUrbCqr}~(`u%RIsKSMP~Kd)@f=D*{Ea|?^K?!2M8ejRA-!CPs+JmweVI}*bn zru;(d1{nG`Jeu{Jz_V)k0^y-8mKiGEBQf#4Ctm-@8Oh|TA2xebW$hMXwcZiN?(B*G z_)1%2hw+K2>uHcMg{fyV!qm{}pjmenrj>R^+s1jIxN7?#@I7QBZeh4|D02N>Kvyhs zLcq?=C!w7td19SW@UpqOKNj-h{C8?*Um(}XOT$lG5 z!@U~QIcxsLk7sAVE;66%5*d0k?hi57f8NT!VTDhr0lB12(M({#T_vyiVWIynDY1$7 zamFG$Fwub2U4!&lQb#4XL)ZbJQ^i!jOGg_$i;uO^Cy-X@NRPXZ$GWu6i}AFuV5EEbf<4T$k7%w1T44pp5RP0{v4cW6pBqN2FI|~lF$s3 zFkpIVT9^Cvda#mOSqLIQ=?aju4TZCIf^fcI6Nh+D3bSP8rS&@ZR*{Mh`}(3okQg&k z^xxAc|Be*?AHT=XpgRM;#rRd~L~qD7OKy=na6ySn>n&}4G>1XsafEQGjs4vpmT^9P zi>v4y9EtOnhti);seeb}|G$0@+$X>pBZ>LjwTU03;m3z@!zVBt+C}ZEaY>ws$IfLu z6^@Qnj5S%A)8EB0^`o8O`l%(|*=z^XGQzie)%9O)>HBl+`36!geCl;dPoM5)82wDV zyTx*<{@xZ#1S7xijPg;-AhDl3mzNF{1~4XlyU;&6<0I_GtqTk;QgW0N)fQ_}v%m4k z({@e~q#sQAL(ZT-$lBGY*a`^h)3iYgsMakN)f*Q(^{QaCfkDDX&_#!xQ;fj1Mtk?y zeTg4)+++^hKXxxfFFu$)F=T+g_c7=7L80$XLM2_QS656?Uw<=Z1QhIxHLzY)8l2jE zvu|i=X8`#Q3SyiJbMw6WZ@S>Wtf+h*pGYr@6_^Dctq%~u)PO&^-dvwQwBW2R@&Sg# z{Ib?XsG%F-#KL>`OQx$}wO2Q89H@Nyp{NzB0*!F*R7!|yN?vz@NPQugM2x0kq7ZQZ zoRfapp9eS`a@li$W&wM}ev6%8t@6ENO?_^bRvVt@z3hjrLnr3W6I$Qw%6T*Ggo5q&EpRe&Jw zOHQ3~j8SQ$)dSuiht!?u-DPg%ThQoE0S~xaX58{11q`+N=I4RzrJndk9&5?khy64~ z7f*kKx2-GBVlJpHjWIDP##vk@;J|&Z0 zelvXL*s$-%_pj{H+OpO0B~259t?9vKpjchay3KwiOlr~I5B4ZT$PJ4@GS%vC;6w&W8l~paI*;@dGl37P6Sfg%8Q;|+lmN|MY zVgd0StR_<cKMmkQ%+TQ^6>JV@A~>pT+ckEUS_g1U1w1dJIObfc4ehaJJ-&O31|OjxClp^iSefwwijn9rGcY*Q?1;_kPmnd2i97+A%Nk&GYfP zYK+lXf#4@=b(Fd!F5~a6W&ON+9)7D#j$F%-tg{?=-Y9;u?Q+F zt`eJq6Gtq#h)9mZ{kXf8OD!R7u0!9otY^L7UvW|O-Xn45;l+oq(h?f0psLzU)1t|d6jV7XKR z;iq4u={eKsQ<{o3=ML*0iI|wi@nUxw*a^r|o>FoVLl?#!nuCKj3OWhSmCDKs+&+Ez z)SW&!SK&m6R&zlK=aJ-6i&$Ll-QlGT%?qakKik`RI?jqu#z#3igbwi8S!h&edfwY+ z_P5XR`@>5%@$m&ruB2tn@SJ^4=}yJ=bWD0`TA&yv4TGMDA_h5%`Rf>VbVuH^R@v<* zJ(q~0ir{-DA?efN>v5c0ERDA|*4F~6hrSnBGiAK%GwXEVZzCTz9y^WZz&|Xyf(ibN4{G1gTl;e~j)^hPx?2yS?=BrweK`L9 zB#`;wT*MZQnGJ8o>X{NH^;pL0hY&~ZvbI6Qm$8mCD!BK69t|W7J66%#@=IY;V)PXR z$A-t;r&ss9>KERantgYFFnR9MZ$W3AJ$|Ae(<53hxt`2Tx`dZ*uIHj*=w_x z0}G~=k1g&ycIS&|PF9R~{O!Cfk3F0_0o{l-{{pP&PsALMvXlvm;CWlusc*Z~Kj(At zqUVXt1DB2BgM)&CGusB{NKfVa-9 zMNN&m7hr6d9lj$ar?XwPKSkVwT2UBLve(Y+;bh>9n$5VNpOMLJe9mgeFkF%j6k+W=Zel6_UDPGT0&;yWv@@OBqbG*0iIiFq4w!r%y7XkP}J zX{rg>r2}xLgG2_Gv72`sz~vHY3y0tDOcS^Y-8HC?BY@suzp3C(3q^IJ7lTWr*WM(J z{0ms3dRA%9V>bLi0^cL5Tj<#Y3`pcaDG?O!{x)r&>uTN>(U5$QBTKzylWA5nOaU}$ z!AY_&5ThMB?lf7t@8wR}r!1Sar*|KH^{l>g^Kv};{?geTyyDSIt22|aK5!psKT;<* zZ9PE4>@i(xKJ`Z?9dAkfPsDG=zRm8Nc4+J${IT%^kl_Iya9$9|?75zDR7Fe<7pfLHH zY%h~wmIoPXz-2LJ13m$hDL2(feedx7OdlH7AqPj>u9*K9b>Bbc zAbx)OHPK!1nq+XNl%xb>+3%b8sj>8sV( z6RuViFj3sbo3!6d8&04@r!{gLjYBymq0Q~cx%vcoaAkkZPyV|#{g1BOA8dnv`6a#T z2~l20t2raCYznJ)UfE(X)!|sU@jRl3uk%um-~lC#&rF{)_vND8GHSY{B?QPlm*0j^ z#w}pXVV}aTx=Q$Tj?aR7zzzypm5cdApe;pJ^xJcno}SJo-&Ba5$$QlEaIG658@rMB za$sY8oUrfVyykVRE$>jFn01&YLJJ>|nCI{J+XQ3a?4{qV7&`ZhOu)=PS8`O;&2hvT zv?u;cP52QdR!61*cB-oZP=2|*EXvPND)Vut{w6j2+~wP8X2$)47osE;K(|#k!7_y} z0Ar|}fn4JRcj-2R@S%+()hkt7EG!HhYh{n8*x$VTZ#MM55S{)yJN?i1Xyd!R#3B@$ zWynW>LQr}!3hBGE&h&X`sI?& z$y+Q}W(E(vy7>HRXq5C_PZV}@5-A(idhgQC7i2!Jmb(ukT`#gALRKi3AtjwtgEp@o z3?Z&HG}q@?PJ8qqfKkjJRCymLSFUP7e0P{JEgn!UqyD$6tSbtl%F&ge_%ZqoO8=J^ zh}Og8n))A|^#q@z{~&z$&ONH$-nx^N`K0dd`r8?u=X6@`-jiNEPDko<%AOP4bHBHY zO_C&>?qw7ickKR2&Nn7^p06|GYvmTDH1}~{hdb$16<}Gb~lFJX;!n-VP-W18zIAH->WA9s{@Dm*PE#z8ey3S!Up&A56J}|XbDzv~M(uEgE z&ok4YreKxku+sHMilA7_G}6&{eab@=0oemHOea0Jhi(sMuy9L;*8`hj&i3qG~j_8;|D5P@}lHAV&X5@`OEPupUl^5X}2LdXygW&V=%b@0jT#22wZ(Iz_) z!rYjXFA7{_&-EN=RN}FEOd5hvX@Fau)1T`50%Avqa`^hYB-V^jbI^D$t2XjYo@hBa; zb{xa+^zz}2ropaEe^x$@vbHG>`kMSaL_4u=KBq7Gkx^IG%QT(~6QTo&|)sb_) z(2cVw%OpzU^}XhwWQaeqzz}w3wv1*U>26&g6rbfUH26-5e50kLC@I-qqteSTjBS9I zpo^4r^tUe^_LqRx64!=@k6FoV|250M4S|6&rgz2?>|R6>3F}Mx#ruP+Z;7=4FZ#9J z0T%AZptsMl5M|u<@C>&~oL4=KL|a2p-7P%U!JCB0lus~1@bEm9`kdyln|IKzv5&cQEODM)j9_6c3oY-OaJWWKCw-4Lpa;$RL=tGb#L|BdXl?9!RnItmzscEb z{ZJCH5mwv<`_7-3eJx>wn}}prUcGu*37LIUSr_%qm8n73BvMdf_z2mCcQZxu+Nav? z#0i#C-y@M;L9(*Lw@Tztwmm17OlSAs5k`G2d3&^`Lu^C)T2a4X`=I~>`+)4#@aeX7 zU6dXCEe$^&y<$IonAkatzh3f)$0n(8F;+;nM2%U@6DRihEtV4m z`^1 z-D0rXyU^IBZ|^J^AKZ1Z9CiM~_aen-gHa!sANiHok})UJfX>cTU^#aqR&}L*l&a}9 zS@gckJ$=#E&T9`BH0Z)xGA@GKMm{h+O5pa0M)_DB;yHLY@$ILyWn7S>XqZdA@nN+h&c!?fjhK)Ao zp>tRh_xbW3T?ONHttR?`zhw89XFdVKaKAC00Jjk5IY%QOM-v%JBB_wOC^L1$y}m>DJt0$r zJw9j;-~g_`rX0F~R72KItB)ppS3&Kk=t}iQv6xXzbb5`8rqoM&2!9nhWNbda>KcZ6 zZvA~Yq$1*3ULog*S%alNhhX~G*{tqaFdXDPc3G2*4vPb{44W5yB=%B2BO9Mz7)#43 zlgzg^&9Ho!E;llwRA1t7!!If(itE(_9>G(=F~PfEIiI?rT3_eNd-v*0xO4AhQ^Hll z9fnr{y4u5H!ou3l?ne358q@0!ZE?nz^^Nz@#oZGsRj7OQ%GrB|jeCY&OG^wNU*Iy2 zZItGAIozVEbt|}5M^fV=h3mp~*nv$Qg%?8gCmamA((g%Jj{o%b)r0zm)ujPwEBi(& zC~x9cVy6XuNVdoJVIW0LsF(A>qY~{Xu8d&eXCIRiYP!3B^w((} z_WXWZc_6rddoBp;t$X-Tzr4pGR?szQPka_^l$|a@ouKO6n?WW`^)8@3Fvy`f3U4Hf zoTt9at50|xHo$wC8^(lOG?uQIyDZb^IkIK_i55csNyFBu2g{_(O zm>?G=HDwcn%>Y^+OaPs*w)u6$Ho4^?`Xx}}qXp~qQYiW<^U}?}&|c+ksWX>@BQDNA z;s5m8#o$d&X=X8gf`M{-#>)0lI9}-ywepYfF#rZzJw&Cy;8FV<&J3tP_b+UEubtS% znA|=kV}z_`)`7I)ja$GlwZL&fh=9M_x%PadL>zuodu^g`o|2L>?73utJ4$w z7QjysnX>?#PO+AM&fY4)Y5phS!v9+=3OjL`9ywc#CpWkveOSvh7FXjZXM*s`FCC3< zs23N9Is2fLJ7ZQg>#|^`O6&R=6e6y#t@;0VNR+az48{W&DkL#e8(hcDLelVAhZ$8p z{aq&_u4}rOYvmkAr>(i(6%;9$VOqW|9*EidFg0@5XMdGcHLH}kSNL9MB$Su+I{cCj zVr;?3d^_p-zXzB8Iy;{kjMx*MlZW~IDal7T%=_F?#*K*ktc>T>n_As^2-jui3kmbpy5z z0aaMK^rbh|BIY4vg9c3^)3iPX)qlh%zpKG}rbCf7KPJcJ$37jh9D^Rve*d7W>UKQj ziOqA?HNkg6me4_+9pprf#x_;GTf*5HMp8Z+Vss^YYEJrp9VbMo_r!+BB(h{y2PL}b zieglDdZ;-exA-G#8z1*v!McK<@rxeVRQ1O5cImllpwa(NcBNyx@U{m*0{ssH2&{Q0 zVl9EG%&^2IQ~FQQz~s3&FA&fE9k(PaP_jbJV)wP&g>gIxvVERnouv>TCzDC~e0>>j7%sTL_+4FS%M;6pg+x_dL zZ2pEz%J`cg08dv9l?j(Gy*tYafDKf8|HX#~6Ta-N=?_Nr({8jke7M`m>aX6ytDjXl zxGiG@a0YNX`hVi|JmjgVGcJ;;IG}A;`mZnWKd7eunZ(jddy0Pf9_({d>mqnRgq%9{mcN`jy5~Y~8Ss~e0PZFo6aDA4j*DRfn`ibt*heGVv<@wI z`&WrqH)(0Rfs#S6;0pA7qRJJi2<3#t-eV;_0eRBzumMK!l&dQaO#Ez z6q{)-D(QS$?ft&sdUI{lhn3b>oZ026*-W zc%0dwKW4?0u&NhetbB2I<`@;Qo=K`tat3a(@P&^g;sTfmGc)z058n&0)l@K!Nd=3S zbAtjpG~~8eVg#yTKNw&R`trd7Z-t3-*Gd)H_2=F`a$~kOPgtr2NhJ`vLwHR#uW*Zp zADF8(@z(=N~LdZiIfd@eS)x`JQKP@9j!jK#DT~ltbmoaFs!WJxT{)!hqXxH{#}Hs7YA|> z>AO9qt^WGl1zQxre-b!F(|4`;fM^$=z!$cW?u$NvN+(Et_z?yTYl8-jf4-z{B_so2+BNZ&?eLriGqsITf89Q) z85_I<6wqyy=6+*?z@v1Pu)sO@88xF zRtjw7t>_6e+1Ue6W*wb4+~*Huc-1c8qILCTDCLqq@DN&yE8Od!I$;wD^)Ltkg|f@ zWVf%WesUjbR7FHJ_$@APvVPiNw5Q*}nos}qJ_2CNb&BZf&{0p=%4w2!NDco=weh>6 z*pZ2YrKe|~QV%NxIR#n#C@#aaUQbod^ysSe5Y060r~ryOgg;FE_a~fc7(p6%BdfsenvM1uK5tN;mw|8 zi-O9>y(oKkCH$-5ST(rKc^=dw*LU@AlfIA2?>#83*=>4T*?}We;}j@Gz8Vq#{P83o znEMQj1BM+-Ru(p#y%U)?hbhMNdT5l0ult3ii1`t>;hD{(h@tlkkK#;8qfGHauQg!} z>Pg(23#hM(s}ucgAC{ZcxU$r%OT2D`HRvV%d6OI$fWE&J2BD{PI`s84igPN{Uy zVOclNI{V6apW(ifgC81eAA1|>#uINF;=C53#L{Yp_G zazf{&(P60d`|cjF}rsG%_D`?KZ{1MAjI|=G7mjsmgR(Dq0?$|`I<|43mxc=~R9jTfJBjA#}4S=M(;NX9B>iTZr40C~{gQ73ttxh$S-p4|;Vt^! zSy}b;i7tbyNvVM(mk>92&NFQ27K=nN0 z@tW}A$&JVXGpdf6l<)Z%#78O58@LP;N1`hLHz87?TUGxq_Q+h1RZQX^}tOE z8xu&wd$=CB&7_`Ki=LYtLb}`aeSBbU#T}C3kM!zp^1H$s6YO{I5Ra7h@$A*p^o!e4 z`Jd$+-uOoB&!rKbq)7ocx1c6(rdRq|g^340(lRBlo$-$@QV7qv(e&fC?jDSb+n%(U z8Tu{WE8H2*Y71401T4Hb+87QsSq-kQf}>$@W*dpEl5p``#IAzJGQ>L9xbnBJSA_I! zmd@2455HO7azQ-YSY*=vvD6)s#Xe;qSCK>uF`c~)*5A^&BPNZXx+v$huK7-Vof|10 zJoz>ulW0zR=yqpF;n7i*LOD4;iHAMYJw->Vb&dD%=?67+&g7Xu%7)cdL^h z$$GezQ!9bTA~i%A0LS$%0BA<{pJGp!6Cj}xC+jW8x*HrNQuBhPuj^R#otO%~0-Ye& z1`?jl`kV9x0vR{V;LGD(^wdurlLGVYKD?+jFz+Nyoqe27G<*`3fd0|--DFceAd#gq z+bX?HX!@yg_v`ite4_W0-Ne#A?^vZi5bpvQ@E@hL_^n=|^K}&LR|R$3IUO^x8S<;; zvW#aFRS^Or=|k01%TRuB1DgH>L%kC47#cV_=l>9-{`&2DM_yT8by^ zfNww#Duq!XPM+bK@D1D5?TO<>T6=Gv0WX9>Wq_=Z8lp z-!S|>{%0?qCg3bJBkip|XjM1L zYvx~36M!rUK;wV5X*T`hDjfbUF)9Y(Pk(Lm6j0WCB`$BV*e<9>`U+`(jCx|to%$f@ z=hc~88u=?+$1d!1Y-f0PvW64Kcp;@*EIZYT&Bj;{0Vo7sb4(~JVDb#~K4zIUMM<=_ zzScf7JuTxd#h?oYa;`fvfOK=2AV@!)dWKQuSmA0O-@Q-Sr=I>|!xNKSV|&KszT^Gz zyQ`r$`K>nNL z_9GjGrB!Y3zEdijNbvMr*KHFz%J;K$h7SNJ8}Mf0UsBD#O^W~dCH#25-o8=4ebDhM z{Hv;}>}IEqUhn>rIh&Mg>XPytT5@uWWfz5i0O@E2Z2B%ReZw0a+(k{D?$4syx{Bm< zJ<*EHY;Q~GTt6z^%26brg&Fe{vBmOf)zqUnh8biNUy1rS(<|{sWOwrOXL1awE6h(J zj&>!HY({7>_T-l7cy%`P9Md=1lG*RH8XxDyEGYv9Mm1=-(uq?-AwVXuJumfNS&zR1 z{pp-952Wqi+;4zhW3CQC++1n^xOF|a_nN_w6SQxWoizVqSK`SXhqvcS4fKG>bzlQN zUrx02)GmJv<7$b7A-LQEs{GV(qssqX<2#JBisaT77}} zL8W^Y_pk>X$g4`aAsBUW-tr3^KDW)*iW=qd{56_|oP2tf4mtePfAu?IqyGa_z&ju+ z_MMSS|cD zHfTS)%dBmEYCnZz7?G_(DhD$hd`Whj@V+k6g6gx0KEL>+M)|HfVlN$4%(zZCEJzp2 ze6F3hk-WuX$XvuP!Qe{*ec4@E^r;JKN(%dS^n=Dn$2%X+%;wQmruKzA_V?jaWds zZ%o50P)N2`f}ui?8BEyed!=fsI9yM4eupBm1b$cU5~H-6hRf@`{+jq9xW3t~aV9^LJ4Tb< zN*J;7QZ;4`lhxO{UHI;_;v3HHdD|$lmI^ytK4a5aKWOyN@dcn4$I*#Pcs2!j4;70( zr7C=}n%+X*wS~Pc#LH}rVUC+tC3(99JyfL+yWNb^ERiyczYzX8>Y8D)k-owCX+?IU zi}$crDo|&{KcNE1xr3w{e^&C8g7(vvNLM#0L~wCe`tBgt5Pj}o-ECXUW(R>TC?y(} z`zdIlT@Rb;d!}sRsa2{xYoW%`yBhyx!|=+F4_ z%$UiE%w5__P9UD{ehJ~0UtIRx{|_FB}7~rL^tD$9$85;rE0B|y&l0Y$+4At+&(uwf=DIe`MDEK zMWe5(rwl1@=i2dK9@KcX`#8)qNtUgorvUiD0o{XGH8!$f9MU#fq3eBRA^lzmhqN56 zc|XGHk$og{P<_!N((L^N`-O(A7L`)L6q7)c(>dAE5xJvFBny{UQYLX#f#D~U>g^Yw zRy?Ye(o2!M#SvXInO<1&P{`RoF+TD5DZi6^JjH=7A3?j4{R_efXgf^Xb zX(bSl+KKo_kGEK^xduJWzn_~M(IDxi|$O0IP6fHP9I_@|hZ)nIz|{*;Th;A=d3offXwa;{-w6qM+=UU6q!4;IP}EHLZjqu$9E|4pfXS(AAPzd-I_Sq< z@L@>(c|F=__62mz6uq`k`3@}I`T;B2Bz2*%ggC%nLJ!F1#}Y@g4c_AqR|;x|ObCrr zubpv~AZBKqJKcMV=8>q8{q1b_RnoVlfa|bEfpCT6QWJA;A zv|jhm3=hxmXUiSj%Z)lz0aHWqhRjxiHOclzvF89Ydgl77wXcGb+PeweZ%1l?O7?@Pw(%|iHDSaKj zQ|~e~P&fVHNu6Sm1LuAOe-y>Jp~xdeeXaT%bSjga#e70I{?JVhop&ySx(XXJGMA%{0P{+av}mn1W3ed3SI_)_j_4eF?;nsSV7^RNlEQ zmNQ!{aq;kD4U+jxi6hQ)wcjn`Ro_hW&)RIcm(T`7B*kR30G1yX2Vl&9-G$KG~M(~%I8}DaW`Zop};&g zyY=2HC6h^dq^fC1qY6~Uzao&_rbvs$$;vMC_bE?#-Zy+Dk>}^gf8YGJj@q3k5fBlN z44m_Y5|6kQLwdC@&zf4JcJGi+6=4{?Y?XY05DRx3Zu>M68M%kKk21B8m@sk zBcNH!m+;C!ZU31)L06n(=1MWM!i0{f%O?#kv>#6sO;B|_7Zig&dl@c_oS`CqVy)R) z99rei-a?kENRbbhI^6Q$$=H40a z?i~+S`9wZ0p=@je)CN|!tzAo58GvWmM|#-iSf=zZ=AJp%H&NL6>aJ8#Rt?Z=+%2SZ zngpB&cBnSW@jeIqF)~H14g1?(nEvNF!zRO*+(|t)-eK&3jxR#FNy(_*@6uAVDzP@=s8$R^OPfUczIG#CLXmaYzooql9ErZd-#q4vN~RniQhmlS#QkL0RcS zy9i@kPuM=3SMX3$r@H+&MYrEoSWsJi#5e!R8mK4pt4)9+jOkUe89+GXtp2ia+GY$U zgH$GcK>`2=O-I|QF|N;=<5yMtq8_`@5_oP_Ja|^ER9>BuYw9S$&)uDZn-0B9xo6}a z@YzWtIcl(Fb!2Dy|23+bA)m*J0JR0EF_W-Q@%2n? zY7S19)K@_S=tm47{xk|{#FhzNHpWqAgG;3n`D zmcV}Oy+!=BWt~v`j2`tB5*kO@R(k$B>fp}lM-8?1ot9(a$c)r)qa7t<{I8s^PPHou z(l_R!w`sp0(Aej$*u<9LewEi3rM?#Ad}e73y8=d5CeEz&F2N>qGH~2NqPT;#0s1VPy8#c+qwMxIwQ1P$R?H za&jcBPKK-SzzJE~~f&h-hU}2f0#9V%H+*MAGcqcdA3FXf+eGaq;CC-0V~W!rCih45M$EuvTd&8&ub=E{TJsqr&QpK5@OZ~S+v&3+wG(JdK3AmCZsQ$ zOWDGE1~sN7u(mSP$2`>vkiigOh#WDe8g+a60?fO;_iVA`bFLe2u>?gg)o-zQ&+`m+ zue0_;9N(_GqQ25fEI0Veeo_TsYXV&(OWGwt2Jm@VR2ywAEEFeB#IVx1c+CA^FXm;qf|=(}4LVy(8P z2babwe67Yi-S&%c`o+RBTkSjC;O2u(LB^?N9mo=|OUGB-K-Rj0a?E*xPx|q~4D;Qv zl1yw!!8x6#FHSk7)2>7El?hF-3{WoAvlb}+T$ z_%h>5YS#)`~{X`ibF#c`GDOQeb2oki1l|!-2%k zJXe^y5?Iov;r89Tj$&eC*=Lyi^Eo#a%R2Zp4rMzZaVJwAcyH!>q72B% zQGJyhyC3{nWub`ZCNVj70d>V5rVDBfXT@N|#tuALZ_|dCJCy&`YW;hja5f(L!E0Gz zU6Nii+C1;Nlv}S)EppMr$@)_Gug_SN)J6i35g_DNzHZm6_cj<~~S;|28sw>uH1_)sdmWa1Gt;@}&ka>7W zqg13x%*REI3zxPMi{nJPKxq(J8W(DhY}gu=h-@2w5lRR{Jp|6 zxoiCI&s;OaMS{^i#S0N=fnxb4e27o&Qggm|4ei30HMX(-fu~U?rqXLFEdwLCzAU9n zzc(5u?NQcz)i#~xC&p|m=LME)g`40i620O#*4v19DIobpq1x!O2ukthh(dGDnT(VO za`4ZAo|&R@XZKOjj2)@T4f@yL4Ly1Ja^ECIbF;QvRLWpLIbf6KOoRq zBPgC{E1&efJAgmrEA5G@<9jU_v8#)AkfYe4u~u8${Gpri;rAo4-%@vcYy0@!!1$h+ z?$_|gJHPHAKRYAdgXn#+0W8lHgKI|O!ckEn%W-$=9q7Tt()7(KU$5h41WCivU_j=Y^&w9=>jwdCH z`v0;&VB0&_r|F2-%qTG(xz25!%4$R>yt3!RniUSULGqIe9zZna$y9sD4|Hn}iC)7e z436n`T<)Yx_ikDJSWe#Hy7H@a4imak+ZFrHwG?hrzcYpjvkeHPL!Ya)5syaYvX&>X z9hF7KYFr<7jwb{usLM+gPhLOy$@o=fypMRGRZp`14%L8-OSXBRXWfdn=q!*>Ep-&0 zIyoy;Za-yM>^FjAxo)4a9xAhJ4;E)#e9%uasO@<-ePvXGp&wrv4=*V6ZEZXJh`n|D<5bO39G{g^U0@l{FZMaKkaKoEM{fN<=( z1=WZ~0c;?~cwl9uy4^r#@yguy>Z>(3$L@TzXW*vpHlE4J)2)L~Vji5B1_wP)V2_=_ zBHd?&&?m$?X(M&Ka2)z`9J&f-69K}h*tSP31-G(@R1Si9oOKXU^D*BCguSuW;-`Rn zwbFBdC72bGh!|Z-60PI;#Y^D%)ldp-M#nnRQ@fu2n?yqYCM)4}?aSBF_EZf+TiqF~ zoGJ-rMdl@fs!9LO$65zh)Q2G?&R#pr6X%+R9$oR!!*uuiU+%a!+{3Ot8MyqImahzN z06TJc<*1&4|7%Af;aZr?kW@`WWk^#s8XSg68o)Uz>qf3Km2_)#g{9Y z{X|aqM?lvf>+`uveC{&;;V1uZsb2b@%kjBG|H%P__U3t3KhPO#c=4B=C#FUDZK)EROfU`K4Yr>crbar$wmGSpG3 zo|*0qt_1qqXipH}^*$P)_wPm5KcgV}*7qRZctz{l$_m<%N?CEz^>UaXeIlL*%USs- zHYc@5W%X543(FPgB|!VttluCFN$KGp7&e|0TfWz*^6S$DOL#NjoXLD-zE)Py{`R>2 z$VF#BT%JcYM~n5T?R+-bLgqTI_cs46b?Z@!(@P3S-7;Hi4E`>}1XR&7+>2R8Ufbtt zZHoYZ^8_eeiaj(Zv9}%e-|e)5fn%@H?E_+PPYCE`0=-p{MIqx=K#yNE@+2@66OzhL zif4;FYHB*@;hYo}xy;QOvhL(V^7y4Mv0L?DVz&ZZWuCWOR$zu9BgP0IzW68lEfz;V z)=7tGg_xI^H07^Zwdl3E?zIo-*b74FSA-P2(>{BxGIIK!xd(GEZg)Z z2#2O!#1|mcmZu>roQOT-(Z?X{2g&NhFmcQpx~($~RSj%$zT(X4vumwKdoZKUFW(D$1;k1*5F;9LECI9Rcl zgoky&)Sg^SEZ~{CIbht~H|~hj#0%WQ<6Dr>Gv!dU5jkr2h96{eop>9a3s*y65kxOJ;LG^8FSSeITC` zz+z#Ff>3e9cCcvqBg^J&HW|SL(guXS(;;Fb-;dN4u^d62zEgAIS<0~uW@vF;j@fc2 zJP9+-l*!AtQd%W@=Js^GO40PIk;>oPzu@=zW|vA#wxQQ^kgKCIrK#6AELiB0y zKtb=BdiF5GX_Z^c(wznQ>y-(>2F$EE>4mWn5{ciSz)%Jqexq4%*&bdQ5=|LIE}z; zEiXCds;_F6T)e7=(;R}8*3MsZp=SvVVfqOxHg#Ko!b+%yFe7eWGj+(Zn2;8_nMKeCeRh1K92>lc#~yS_T>8Z%W{*IJv0n@?wnYXRy8} z!ir0a(}fNrvT=CMTpY_+Ol7UCu|mK)p=n%_NT%KdZIj0qC&~8xNJ)GGA|M&sCPm|m zHgH8<(&Z+DJb+sGE4w*viaD99ApA#EX)V?=JG z2=MqYty3}iI?1PXR57miL`9-r&`fbNr$qUsV(c716f@8)rYro4@LS}~%nr4GBuD+} ze(>e$j?Z7Rb(OZi>OIk>)nJunqKHp$JQ>BFp^u{dC9JH8)jShA57XIFD4>=~tZFTZ zS5O#GlDOYALD-|7niv|ROUv2cpPm?6TA;LE<@lvUORQ+`l*3LHqkfHwaeuKu7% zZ7MrzJY3A$AfOVim(lHhbM*NM@%Q=D2R(I)gATqVBpaFOz;u1PH?pskpLhV#kLSgA zIn`8UPK)y*X?1?YS{=7W9$R40_0)2L&JGzVu5XLJKe0f@R;!ti+S>78nTX|%RtW_O ziIcHeU8~oHA?tdS+#3f&*mC{x@7`^<9InqTMY1g8c@fZQnh-CmmW*n3npqycAouL}yf z`PM;#wNDnlj0qpPj`t-P*phqZm;zP8fOhOxmOng$DVv$uroKEh00vU>h4A?PboX>kjh zEy57=2`-Rp*ADtk-5M*s5OOs*qi%2*85w@KdWLssy6f?-guR2_K2g3Dep(Mbmj9HrHEw#BiM5->Jg}bgE3NdsM#+f#zI@cDmX9ChcHd z@s)nUq2Y2yH#I11w?$)|KXHOTC|#d;>Rf+(=q~j8>+5&x#xch3eT-yp<7Gm7RZuQb zph5n?eKv(xqr7KRj%|8Taamaa^U&)ol}jl!J;P6_zDbW4`NXGUs%&Aw_wWa7&DYd~ zC&WKAF*TZ5Z~v6mwbRXh6EsGVw@X|mxQi^Kd>>W`{biF%`_)3ROHJq8qja1<@2xmz zs%4#zJlm`t)zv(2g?qziJi_bX@uRxIY0CvLdef!;U_whBx`xhH=4}z!JZay8F<|6- z<`r$gj85|TZ8WXo61_s*xCx7@ySOV33FRj5m!3#?)zA+W$SH#|PN0X5kbNRBoM2@x0<9E%QpL?LCJ<-ktl;xsTt*b!C2w%AB|a6}08v=0`t9@Mo`gLX!rgKu>^435D% zhB|QecJ7i|e|*!W1!~T#i;K|%@S3dZbUHjHnhtUtvhx<5N!r4s zq;{V6-}O4_$~DJ`Cj}eiA=liMZCU48H>8_gYTRh5s*dxPGZSvf z4A@~0N@YFwl;?MVqgI4Xzt3t+0<~>;x}Mi`XIGGMa{P|$kO(E~N3KC9>RLOr&YpL8 zHPS_R*wI=&9q9uxlnRT}w%v}TCO0b`FYKvN4IY~8?zOE!bmAZQ+(n?lbu5W_OBOTTzd7| z!1QE~tpWPSTDl>cK3u`AR=k8Bi1wTnQd%oeLH1u}VbSj??}<}y5VJy-jksKym+@J4 zhy=*whgqSbXyQ|{K%6W?WX+7=uDBL?qX*PBjuOWJEYL$&sC4GF@4G)jGqCF9|}GftN&h7mc$2rT`vgF-i(X*;34fXiCp(2m2XE@e?&I3_2isi zv$xV2DTfMLx@&jaP@Qa`RDhrU9K$DO;1h##960DT=mkzB|G~!SInk8gIT;OYl}2s0^b` zo{q^uUNokMr8)~=d8fTD4%DOvG&)G8`Vp2i{*^+I};WIj* zPL)pHFma!qgPU9jU@pa2_fBQK)ho?;Zqs2GxdDoNt=cs5h{9;ne}!wgmlX*bv|yU; z(6fnX^%ymLgUE04*dMOtC%i!M^Dx>HLw;YMMhzVv2wPM@H--s}g*FJXVm(VQ>-#j+ zmcf%tgH6j<+h+rVn^e7)(<|>K{g?(aU6S;PA=M+2{VYsZ9m@owGQru1hAV=OLPw*> zC7?r^bUwiceG*J)Rwg>s;G85b>t(~M`^ar@?-$f6HN(Jo3g~0@WlWzk2p_CiA$ zP#?Y;J@Xp%JpL1AT%A>w?n^auRjg}y3$o$8DIb%z0i*D&P{5q_jNoy{shK3GC&@*&ym!gEhf4=O z^3c`tV+n!N#@?b2MQeD;$ylHwYmo@UUuM_(fybBU2sC0^ciLR9bD^jmMd9iDCuJR@ ziT>0n=YI3dWEhE$$$KEKcBb^Ax|slV=r!BJkBJ7MW51TFpx|eya=y(yQluKNIr7Fb zF{&=`6@kFHs?4>9PpOj&#jGv_Jw91*pUs;ZEer{kFv_7sp0=}SYS~$SZTD`qTtGRR zk!mvRK~-_4yq`p@nxHqw*4ZVwkv3f5P_6G)K}QMs4W@Ug(^PrAS_YmwZ#3-n1Pyim z`qmE0!>;xU%bM;8}iVRc3CZRHo04$X(mR91~8S zyDxeAVnoZ~xIiV6bl6Gevb1^9;b+x|%_?yp>ja(<3258LVfcN>=KgrPExDCX&Qqz% z^@Kt~>YF`9H$D5P6a1mF!2O_haR2+byc4(+HNkiN-7U?fubV7BRgD+^)(b@4HL z?>55_JTTzubBkYY1n%YluwUNA^A0OcUBEZaP&@eW>9&`IY~pGf%C&9u<5v<@{;=K` z$Opa|a(lXB4_sXHY30R~G`BVzLyKVSwukTfY1211mA_? zbJwm3EYa}EmYL-7c!^I$*|J?DPGy1J(NP_zGYQ3opUdBy^>UbxcRc7ALY!AN{L~TZ zb_W-D>tMp++o>t#^ZFBm&G#QL6so47Ozc0xf}kIU5?LbE^tuQM)7D2^FwLrfb*POU zlrOvUeb!`xZ_H!aoSP>`#xn2J!c1e59%?D=u{;uJiWrAC% z1-we)V^MeBVu9n)1P0mN;_5z8W3O0od2Gmeu^&Ywug8-xp=>#⋘R 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

    u>mZZ1Adn2YO}t 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ℜ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 lilA$0Byn(LwQnhaFt))IgOepjWhp+iG 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�KEVHczZtonjO0sT<&%)0(@$47c{t%6#mY)Oy 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 Nyh8u(t@}RmzW^080c-#O literal 0 HcmV?d00001 diff --git a/user/pages/01.home/_pourquoi-le-style-de-lours/text.md b/user/pages/01.home/_pourquoi-le-style-de-lours/text.md new file mode 100644 index 0000000..3cdde29 --- /dev/null +++ b/user/pages/01.home/_pourquoi-le-style-de-lours/text.md @@ -0,0 +1,9 @@ +--- +title: 'pourquoi "le style de l''ours" ?' +image_align: left +--- + +**L’ours** est – dans l’édition et l’imprimerie – un pavé ou un encadré, situé généralement au début ou à la fin d’un ouvrage, qui recense les mentions légales, les copyrights, les noms et adresses de l’éditeur et de l’imprimeur, et les fonctions et les noms des collaborateurs ayant participé à la conception et à la fabrication de l’imprimé. (Source Wikipédia) +**L’ours** est la marque de fabrique d’un document. En le lisant, on sait QUI, QUAND, COMMENT, OÙ. +**Le style :** chaque document possède son propre style, aussi bien sur le fond que sur la forme. Le(s) rédacteur(s), le graphiste, les auteurs des photos et dessins, l’imprimeur… sont autant de personnes qui créent la personnalité d’un document. +Mon métier consiste à identifier ces intervenants, à les orchestrer et à harmoniser leur travail avec le mien, pour arriver à un résultat de qualité répondant aux besoins des clients. \ No newline at end of file diff --git a/user/pages/01.home/modular.md b/user/pages/01.home/modular.md new file mode 100644 index 0000000..20bb8a9 --- /dev/null +++ b/user/pages/01.home/modular.md @@ -0,0 +1,21 @@ +--- +title: Home +media_order: RectoHD.jpg +content: + items: '@self.siblings' +--- + +**[RELECTURE ET CORRECTION DE TOUT TYPE DE TEXTE,](#correction-des-textes) +[CONCEPTION ET FABRICATION DE DOCUMENTS IMPRIMÉS](#cr%EF%BF%BD-ation-mise-en-page-impression)** +pour les associations, fondations, PME, +établissements scolaires, mairies, particuliers... + +___ + +**LE STYLE DE L’OURS gère tout de A à Z !** + +[plugin:youtube](https://www.youtube.com/embed/TuWZdE9bCFA) + +### Tout compte ! + +L'image de votre structure (entreprise, association, établissement scolaire...) dépend fortement de la qualité de vos supports de communication, internes ou externes. Ils doivent être le reflet de vos actions, engagements et valeurs... de façon à ce que vos objectifs soient atteints (éducatif, pédagogique, commercial, notoriété, recrutement, appel aux dons...). Tout cela nécessite un message lisible, une cible identifiée, une mise en page professionnelle avec des images adaptées, sans fautes et sur un support physique adapté à votre utilisation. diff --git a/user/pages/02.correction/blog.md b/user/pages/02.correction/blog.md new file mode 100644 index 0000000..f04c9ef --- /dev/null +++ b/user/pages/02.correction/blog.md @@ -0,0 +1,42 @@ +--- +title: 'Correction de textes' +blog: + config: true +content: + items: + - '@self.children' + limit: 5 + order: + by: date + dir: desc + pagination: true + url_taxonomy_filters: true +--- + +_« Ce n'est pas grave de faire des fautes d'orthographe. +Ce qui est grave, c'est de ne pas les (faire) corriger. »_ +Moi-même + +### Ok, mais pourquoi ? +Dois-je vraiment vous le rappeler ? ;-) +Faire appel à un correcteur de langue française permet d'assurer la qualité et la clarté de vos écrits, en éliminant les fautes qui pourraient nuire à votre crédibilité et à la compréhension de votre message. Cela vous permet aussi de gagner du temps et de vous concentrer sur le contenu. Si si ! Vous verrez ! + +### Oui, mais pour quoi ? +Print ou digital : rapports annuels, plaquettes de présentation, revus ou magazines associatifs, bulletins municipaux, publications pour les réseaux sociaux, fiches techniques, publicités... + +### Alors, je suis là ! +Vous souhaites améliorer la qualité de vos écrits avant publication, je vous propose donc mes services de correction de texte pour vous garantir des écrits clairs, sans fautes et parfaitement fluides. + +### Mes services incluents +* toutes les corrections orthographiques, grammaticales et typographiques ; +* relecture et amélioration de la structure des phrases ; +* ajustement du style et de la cohérence (si vous le souhaitez) ; +* conseils personnalisés pour perfectionner votre rédaction (si vous le souhaitez) ; +* vérification des sommaires, de la pagination, des crédits, des notes et appels de notes, des mentions légales... (si vous le souhaitez). + +Les petits plus : +* avec une attention particulière à vos besoins, je m'engage à vous fournir un travail soigné dans les délais convenus ; +* toute reformulation fait l'objet d'une validation de votre part ; +* une fois le travail terminé je vous fournis un texte avec toutes les corrections apparentes et un texte tout beau, tout propre. + +[Contactez-moi dès maintenant pour obtenir un devis ou pour toute demande particulière.](#contact) \ No newline at end of file diff --git a/user/pages/03.creation-mise-en-page-impression/blog.md b/user/pages/03.creation-mise-en-page-impression/blog.md new file mode 100644 index 0000000..54cea26 --- /dev/null +++ b/user/pages/03.creation-mise-en-page-impression/blog.md @@ -0,0 +1,17 @@ +--- +title: 'Création, mise en page, impression' +blog: + config: true +content: + items: + - '@self.children' + limit: 5 + order: + by: date + dir: desc + pagination: true + url_taxonomy_filters: true +--- + +Je travaille depuis 30 ans dans les industries graphiques, l’édition, la mise en page, l’impression et la gestion de projets graphiques pour des associations et entreprises de toute taille. +Les créations et mises en page, grâce aux nombreux graphistes qui travaillent avec moi, répondent toujours au brief du client, quel que soit le style. Le choix de l’imprimeur est également stratégique pour respecter les contraintes techniques et les délais. \ No newline at end of file diff --git a/user/pages/04.nouvelle-section-1/01.secretaire-dedition-et-de-redaction/items.md b/user/pages/04.nouvelle-section-1/01.secretaire-dedition-et-de-redaction/items.md new file mode 100644 index 0000000..bbe4e7e --- /dev/null +++ b/user/pages/04.nouvelle-section-1/01.secretaire-dedition-et-de-redaction/items.md @@ -0,0 +1,8 @@ +--- +title: 'Relecture et corrections' +published: false +--- + +Correcteur confirmé de langue française, je prends en charge tout type de texte et effectue, selon le niveau d’exigence du client, le calibrage, les corrections typographiques, orthographiques, grammaticales, voire syntaxiques : articles, lettres, manuscrits, mémoires, rapports... +Toutes les propositions de reformulation font l’objet d’une validation par le client. +Facturation au nombre de signes (espaces compris) ou au nombre de mots. \ No newline at end of file diff --git a/user/pages/04.nouvelle-section-1/02.chef-de-projet-print/items.md b/user/pages/04.nouvelle-section-1/02.chef-de-projet-print/items.md new file mode 100644 index 0000000..ca8155b --- /dev/null +++ b/user/pages/04.nouvelle-section-1/02.chef-de-projet-print/items.md @@ -0,0 +1,7 @@ +--- +title: 'Création, mise en page et impression' +published: false +--- + +Je travaille depuis 30 ans dans les industries graphiques, l’édition, la mise en page, l’impression et la gestion de projets graphiques pour des associations et entreprises de toute taille. +Les créations et mises en page, grâce aux nombreux graphistes qui travaillent avec moi, répondent toujours au brief du client, quel que soit le style. Le choix de l’imprimeur est également stratégique pour respecter les contraintes techniques et les délais. \ No newline at end of file diff --git a/user/pages/04.nouvelle-section-1/03.etape-1/etape1.png b/user/pages/04.nouvelle-section-1/03.etape-1/etape1.png new file mode 100644 index 0000000000000000000000000000000000000000..a7e4b78dfc57cf5e9d116098104ccc502c4b48f9 GIT binary patch literal 56136 zcmeEt^LJ$H^K~Y+?POw3oJl6OZQHgdwms3rwr$(CZKsoO-+R~Re|Ud*d!5!dS^d+!RDmlZ>R#f1d{0YQ)u7ghuT0W|~x`DO+U2|NSgL_Pw10(TOWP=*HHyrGT5 zfbU`K#WkEjK(J8%xqmaunFD?b1jkuK-C4=b)Y;9z(FDZJ&5gmr*2>Aqz}|$x&e1I6 z>K85u2r-C+uz<3A=0&Gl8ve1*@vF!7S=Ce`8f2h22zW0z>V!g)In7FedAeiMa?16R z!?M>?mXF(K|JJ6~_T|=6H>ni1ntK6d%vdkdm<4(tauJY-<6 zev3Mj-~{j-@Qp$6kN^Mj|A}=7i3F(>pbcK4z3Iey;a)~9O(y*P&xL~zxer_-7XCnk z(9G>W)uTnOd&T7+NpbnJ4(jKn$&resNRbNDw5mM?VSMie4->Q`T8s;So^T_!sQ*K| z!MqR^lnPy4lg*E);h2;ThP3g;?YlY$s!9WFdm$fEGf_l?{9hRAROC=B4$&|i_;ZZ! z1MrYSzZs*@b4_SajVob^k)>v}Ha~vVIZ_9!G6)u-E;ZcL54>5{E>6S^Kr;mzbQ%Vw z_1e#(X>AvWaRT@;*8ii0$sBizf1dp;(AU>okx*#cx zP#dk(mixmBvKSV}$a8{hWyId8`A_)#h8SEU&Ioa1SoziyE#}`%O<0by>y79PA^SZ| zva|*?!Gg5>M*CpQN{RPhj;#Qv9WF#u4b>r$iNZCXdE4N@wyY&l_<0{wNF~t(`RuNl zZ!Z$c`5~gj!myW%-*YLnv1~L}Y&MPCLq{I$@@h`stYxBwa@NuNRo1s0_U-~xMN*Fmcl4L(o49c_E3tOhc&d<`L$ zHL#_s0;vpe-9YovcRNL~GGMg0u$iZ!&4hRByM-_20zT)zj%xvcSeQlO8eLHZvy; zUD+L)@yQecMwrp{(S;se7-hObR>2L{eu8986A%%z;nzYR_4Pi_@6@sS=5w03pqR^V zch^W*ZU!-9qe2s1PdpTQ?qQ>5NIR-$RF%lk4dAJWMyWWrRtV1uwAg2 zkejEHn@htf=H&@tVUqUo1lOs~O^QsSuF#Hm79(;s<8w75auowU@|Akyk=js##h{_7 z)17d#cOCxufr-(pJXU>~R0l9j6Ywcs`Xdd}rZ8MizmsBSe^hjXX<8zOV05@{-hP0~ z4A4sWwlvOqWlzd8PqyZnnL_u_`Vca${&H`a@pn7=#D7uIcBo4JPq?gZ2RhJm@O`zK!dZiPCNEg*W9*+efMSO2s%fkd0+mRYWh({ za7 zj1dFrNM&q-$UA*@m~Z;TD0Xi`^#<2>HC&Z;8HzA4%m&Usx!Gc!ZDeQIFJ+6HPo~JH zr@Pw!#=F_nP`6@GHyW7*dx_RcI*k5M^j0V7mdFky+;YL3Zi4APkn$(svfK2i$BMOR zyyQ=$r90K(YsM@+n(zx@oFM5OrYeI>Q+xE3)$^>|d931w2SIw3Z%~$&br#J0OJ$ED zMp&rRmYYk66Na?>)dzZGxIt$6{DLTAz5M~my_jyHr{zSBGA-iT;|x_pK0kER=LMMc z=fiaZ-U{ye#+?T4)DjSWX-vG=v=(wUWXW2wBQqN{vng%y&x=y`yM{8CZ+k_uM z#t+1(&Rzd>^CQSsW_&cwA`V8nWt#H9xGBQ#V zrJuL#_jX81IXdD455&P=Tq{_)-ylw>ez`sqGiUMT)7oi3Z$xNvRBElcd{ozwmFeay z&?|9!#0BqH?@vVKo~g{N$z_ft*R(^9An6J=xuL1%f~7Z+{F-77PXF?C@LnCH=^@<{ zq;U0B=?DJRX@|3Nzp;&8lwZa1>N5Ggn)u#G*Lq3x5jc@Pp-<@1>9A_xJ z3^Y%oCkNYkhhnyNI-z$YcN~?UO5UB-lt%iRPtxZjwlp@!@FcNYwyhE>9NPP5R1gKy*EIt<{>OYD2ZM>{+DOAQJ7qhI^wM#_5;&%mWLH>t)^}WFjsOSMP2)}Owzk_MTFrrqh-b1iv@6Pz)B59}I`Ij&O7`vy-<+5ds$6}*NiHD@ahvVQM&*uF0U zXK42gmutUOMt=C2Ck;6dPDg<^6yQwDapsJea8EFg#+4v>A1^~SI; zTlwg*i>GnhCZ&5!;3i8lR9%EX$zObmnId?iNoYB4R$70a>(jtx^*n)!VQ=Azp# zx$h{H+NL{VuF3~koxomurD_~)dLcJW){7fQ@;t4oB3an_N~`@+TAOA6mPxo3Fm`#D zr&YJ7FpAPSN4|s2iqmI2E85%Su|@~u0!xDb$I|%enj1%{HB-$(hygTKPV)S}!BG}= zWJ%&+Hk9uB$|OnzU|y`naqPUbep!)=-)_h_O(itiYo%1@Wb)T46_a~;)5$JMt@|s& zq$)9wE$N{wS`5rD#(07i$uAwg)5zcV=<4{@MwmEl73if+ghAxrXR$T0`_eL7pd0IO znDN*XXr2Vc9=F@v(#b8a+Kzdn~!e&>r6;Rb5Bv>*Tts+(HCERp zCLD{<;G>kXM0OI2;eChe`A;4#N&%6ROMk1zfba#VlsYe1e9>+7W~)$s=Gz!i{B}*? zUK8yHANVM4<+8a|WYJ@qf&~y%>8oQj47Hn2n><9J+5r}1$HBu~#Y9iw{MzLLH6 z5;R_C&b2AbnmbB_ zNv;E}%MntHJg?`U36|;E)@NoGTLsro#iLJ%3AWc(i1eIT zy@tZD3>y`ieufkOhLdF&mU~4kf!UrH5;I^9C28h>>+WIe&B)j*l%K!I>UXb~Z@lz7 z$nc?`{#kJI%%kXznYJf83}wKJas9#onvAC6-(=DD2;f#2_3LB1#*01S5{Jvqf6u{z zxIp-OEwhK;T|6l0_)uO82dkpyijGKyAyl6vJu3MpR_1!ke)2}J$-c^X6wj*&MYi8J zx30AY8cF}GamAH2spCbCIgd@A1IVU0n#Z`Q zENUV@Wsz6pc9!l$9DEF8W`}dk_FmOax}KOJuU>zyxo!&=nL*QL$UUtnGYGEvLO~iZ za&;+SQaIW~)ShG(-IO^^bbZn}*=62D;)GUNHaa7J*1=TOTQmB0H|mz#7EZ0Wb@87j zSeYXQVGqzXuOZYqD3LKoX#8&pX^=r{tou-*_osb>Z_Tm?D!B`o*Mwu6Li%~^n{xh;r}@sbq&d@Q|lB}`S8ABy915xFpY^oK!|WTXM(q!R$y z^ttdQahp)?{amt0Hl1%=!m7J?3-`G9 zidpv;rIAI;;2=B|$L|Wn$4z@0h+V^*HaQZ;njtWS*WFyG53zPkY9H@5x2io2S8EpI z|H(qXT!pGPa&2fr(wT~oP0LD`(77nSdq|#U9pbW@2v*ZMEoQnte^#4y`)ybQ9s`N* zkg(5DtE7-a$-%zm-<*>~^V}1+=IQ`*!kz>)G8iPCo|KN(d}IUPh_w|$U{(+|LhCus z_L{4ID8;N}x8Nk%EZuvTq^y5FysxfQFvY+9+W4Ijux;!G8Q5reNU>)k*@w-}9l6QI zzx+s)@3g(SKq;2ab3a^&eDvevBJm6^3h? zNZL0WG-;D^)&YbK`fk?6CZfrz0^@8Td@Mo3Tl67cnA&cs7kiJ zdrds5R9Dl^b>p`dSJNr%n*cfT5buX4mF@qU1{Rdu$%A{T1o&KoThi&`ij zjXc4}pArH)>E+-X%fbJ`X&^XEEz9UBxwsTjE}vXIMWm@aqpzv_V+=(AGue`J0w1_Q zxq(!}BCx0J$bn;T*C{+66r}Org?~)HCkmP4lt)i7KR-z&J#7dUdEHd3drogt|9Qti z#e$xjBDI05P*;~n9wEdsITehNUe-Tgj~?a|xn(;x7l96rdcwy|*1(L3&Bf=avoC?!4#Q@jNo;vcGv3w@ILeDc|V9R$AL)h`E5kdrD5$y&*Sbm>(M?h*%D{QfX z>g3p#dhYTXfw$H=-BeeN0yd)X<&c*@l|#03nLV+m9gtxw5@ed(SWXqykni`Q9wMD1 z?zpRWq$gf&Y4$Lg;>8R7s>v$!cb@{>F$*!~>g1`4ki287e25U}c#j=Wk(z7@>qja! zE65>b#`WY;bYLZ1g}7C_($vYivP^IksZ4)~_?)puztVt6zA|aQMsFU3Fo+b{G#s;Q zErE+zqLJ1#(saa4KB+1Uy1<;mr^oPK2y(Z6Rytp`29E*(!bPbav!6Tq;!XMEJB%xA zv8K^e^nM2*=kq6AsGiZuupeIg3WNnWs`0Ly@Z;K&B}j{_0^I!q#W5;TD9%76OQ2c| z)f01+4m#-cy*jo>=-Y`xgCma5!}QPF!tTGGo)mRq-1GO!a?^G8FVIs9RCw0_l{o^R z^C2$N|I%^q5cg=?7skw+a8uqK=2S3cqX)AaibNQ#k%gnTZ&%I!h*si!`R4~$v*~wO z1VOl@f$IJObkGufqCzg$AlGNipw6hyTf>y{7bX-7y!0kyL5lL(PzDL4AawMQCer#> zk@ZN#QAe1%zeGhQg~*D+wN{$ucX&`ENLSErjv)@3vMg1_z*SvE3y{PkJ4Q?KhU>}M`bt@Qfob|!_>#4?56!u7 z2yrB|Vmd0}WfOfJp>1IcEvySxi-ZP49ZcMJNLx%SrXu3zFX9?L$=54zv>d~F!fhb` zn`@s%bAKJheA~xCt>gNA^ZiQ0OQY(4MV-|sO@DXgob{;O7o-hUJs3W{%SHx;#5}(1f;xvJU%KZdfxr8!8n z{-QD9=2zDEnc*yEw-aKugi;nw zIHY5)x&XDkh*DkSH-!)-)FF@af|jY~WIsNC5_139y%VL^5riBDQB&+FBHZ#t&z6o% ztb|!OnQDY#C`d;bIC!V-P3mAGQP(L1?{mj7g2XFm6C!A~heYl>aJ zw5HYI@^0o$gk>)nkX6_MWN7_u(3|xpPbs?w7Vd#X#v8x+NO-jX*kk0!@5p*8d)*PN<-iL!m8Gd-tgTO(5qS!85ikj5AdTr6_09V3w?W_nw#2%ut{&g*ch*U z$0GrTJLh+?*=WckKo`@s?of7q#*5ZI`BrTHmJVV!U(S)obl3kjm&n3NhLai@5&XBD%*R2}?l z;aB|)YIt!gtmC`Z{gSH6d4rDG#1A6{@_N!MrN()FS|apK&AMD}9MJgBZuV>?B+?oqKJ~dim%o7n4Iu?qnU-bPk{2hm>%6{w? zCr{jHKI8)#oDA{T62X!sza`mY&h;ul$Lu(<@fjM(z%LQRuUG8mW&P1JqhfC!5!n+^ z${`fx*dQj>AlpbVvvPXSh0%hh4<^NFcdim{ti%N5wr-aS;-#374`W9xHi%R;M=RGR zy0?ajtZPG-%QT z{9NkK{Jg>nP{e_~Y{fF|z+(Di8X%$mO7w9di=ZCt3dHT=%QEjZcTIk`>W3W3i}j z-<4npOg=%O)dE$~*>%Q_-u)7{w4M#zuxc+@RkNaMsblH9y(`g01 z!v%+<0C!?q*%C%$u2|_}0l04d@&$J|wlkw)uyNU$4>jrvYr^q5`+jsckv*&zZ92os z^XyW+oHl;G7s21jj3i1D4*9`+(6os~H2_$?`h>of9r#t=2+PgsHBVL7u)4i{(tlt*wME7jy(UJp^={%`4 z5XdC^1|F*T{}zIz3l^|6T(^dAex30Bcz=qV=)Cpm&`iFI2TXMNCJafFmlYOoiaOy{ zA`x0uDD|y%-2r*dw(rSyLInkSl{$g-^7)=`RAWw{k?FCUohY;!Puo<{DWqrp?hHW; zBO-=$sEoK48tSF+s*x&J-i8=!$QHCrqBr};b2c7#VCz5vwos*$Pvo?UlxpQc=8i10VulE$3Mvij&pi!A>Rr%w3 z4Yv|VE2IXY6*trydqPQI)WyHcso+~uA}QqHi+K6|N{GX3^|u+ZZljJ<_b<`B%Mn~`Xs+b8=qoJ#581LF93IygK5tnMoNlZ){0CXn31F}pAl!B zKy1cq@YhVLY!wXJr@3tN?;{r~xNuHd+2ulPyhURzGYRO)XFHyo!wn0MX`%ID3;$uh zB^4RLD1~C;1DhUEWk9DdtpvO% zB63cop&vs!>K^N{gM#}Wgp0KnM_Zmu&{dFhksC!)qt2;us`HZQGJ*p3fS=K)@aI;n z=`o#iaCZ4WGiR-kS#3(m`q(sqiDfF&O|LH5*jCZjueE{6Y&-oSEWH%C@zi)gh z3d7)4g3>qi4dNBk^4UtaGd!*`*&AuN3hEbH3m^4`pWgd#E(zJ1L(L^jI#NirEKaM& z917MblghkkG(&MxGC`R?w zd@_e44!?>~G|)`gMSyI#bJdEr8v^OP1~ZS)N><^K56EoyXjdsMtN0(mAD_hEe4~tP z`w<-hS^@s-M!2)ED&@OVGWqyO1^lMgbmK)py)YQfE)UNoFKT&7k-qnwCE{5n;6Ii> z{ENSc+mlMC4XM2tyO7)yA@yt&h9di&>*^zl=-OCX)g}Nxt5ygAOgz};?MF!EVfT$(Hb;cP(uaOY_+^%Q zhinvOt#oE&zzy#`Y8OYb@B}#G2cZKQyJ@F1-(7`}?oYimpZnLpNrR{oH08vyx1BZY zq830{z%v`zVKU$P+@I8h_{J6#5MIyQ*|U;}#PWXRL{%K33fpcK*OhTqX!AVu*WrGy zD*gEvBtboXP|Ao>{H2dW?sc_Y z$zdwLlSJ+fr;MPhMC0CvBH8aSMaikgONl|Cg(a=D()l#| z{n7qfg8OWszoeUMLRPI8_HR%!e&cwR0JG{qTxy?FEVhoPr78Jdgok)F!8u>eJ32f4 z#S#N}+|I+(&682}tx3G{aZ_6JkZHJVJo^J)6LHya-4%SHPswaU?+8{E@)sbEKO_iU z&~VarM6u?2fq)4c2_9Oj%aDv#y+5S_EF`IQ1(KKUi_D9+Kg*Qvf%GG2=-0!S;a=&N z0N^3KN9A=Z;g@RU&3`HcVL^>*JlZe4}pEHTnwT;`H+p-)v zD*h7bY+-ucD56dA*A!7--KD8TB1=j1eX@#2(L0?ll4ZbW0&X4HrL*q6K^>l(@c7Vl zux(2c(kD-JE36<;pO!F*EYZYh)`lo_z&e}g^oi*A`@H6SP39|dJd;;Gf>e!N;lleD zUM&jI-BCpp~IRLO^iZ)akIR4%NV(iF?ul7M1OMoX8OnaVy8<` zW_M|w(_~rXnPZrMcJt+8ekQhW>KLBOeKNH6N(CgRG&3x>lhARO)E4CPCaRK1?Iv_$ ziFm6!S7_0xX||q-X1z^d7k9rmcidk4MF-{p+<-q2R>kh+N}O5%T2UjT3u#+=Tg*4a zdYafb&aGbU=nuNFKijnJdG7Pl`>4%{xn@#8L1IfebH~!OSno0mIe1XtkB@d#Tmy}V zEl<2bsVdNMPf>!ToNLWHtL!d91%&^@hgRP9a*9gEbi~5&vrp3&;0B zj+*G_Z`ZQfz)edmqw|dv8(_wx-d=DTn4Pxm?kkHTDP_F;n$m{YwP*lJzu9{udY^d0 zTvE?2&-#ZENv^v6MMMAu<@~WxJMZDataDQ&ba3?A1;_=kICnza-u_KPYi*fm{@6;7uvdNfXwy6sr`Mkt zPIiR7=`{O`A5R>DZ(P}OMD&T$dREK8DOBAL!z9#}n^*uYozTtaKonc82-M$#xcuPbd zy}&~fsZak$CX(u_(GKbhnxT0va={(M+$F%=E@5mp-#z>IE6yuo$Q#0J58*-)YqhIV zy_NJ-5$iQK3z|pbbwr_|IDReyF&J7(F(^^=2A4MNX8}<+s*ED^MH4<4-vbJ}&sk2~ z=_+=`POM!k#ihHb{s#-6_@)RnjG{bH2A>*Wa-IxMDyV79k$L`X%Xw{vrRTZ@M4bD( zH~KX^O-ITyxE=Y-x;HYz4eJ^`)OH`7Y=6+o@_i!T+hzBpYw%NJWT_EYbFZ&YE#&~< z@pzwbB-a_9Au8hp`W;ciR~B7Aw%{h2tO~NeZ*GaaW?d`fWP-_wEql4IN}j5fAi;r( zJqxuYube+~#H|2C?EN%AQM{2`r3(2;SD&1^`LAX8q|0VzE50pt`~a#OvOa)%>1#iT zYQ?HL0XZ+l@`XKhN4!l&%u2l?98XMH;swETorG!lXCj4`6@NUlCReLlj9#t zS#t#sNeVx7P*MThrLiY_UZ+D@v23m-!q@PY3a64uS+SmwxJZ>9T&W_|=@VgHXU2_X zaY;7rpcCFFqsxc=Kv^86VV|K1NnC)nS^OurozZ;pCsXibDml$E<70jo9r${5H>R(V z7;~pk!}Y4zu!`DTlNF^+>Zb58M)Mm^e%ZG^O$;=+fjXR2)QVl+5DRO~+)mN?!7`OO z%2JFn1t9Am1Z1<#UUq@}@Oh5WUAkEspEIgiTL7$Z+qUxBw5!Y^v$IZn)@Aoi_nhB( zY{I&|#0&z-NL4Z^vM-k)pI@RS;C7$qfd4u^PMCsuJ@i=Q&6Q&gDn)mP4JA= znFPF+fHW)DeRR>f<5}(7=n9&gVh&w?QmB?wn$JFX+3hiBz0$+>tHoW0YdqeH?DAH7 z2?CMX)ef|7Ye<5yz!w$YwY(%;VTUPuDl}UL#rme~b|pvs?UtXo#rtCTtq4MOs#U7d z>hIkyvB`RpGS2Mn79f5k=#r}X6*xEMCbh@dtx1s*re0*!2Yb{levx0J$&3{^x|+^8 z+E=@r&iBH65A~J(ns2AT!xYY|b=q z?oMAYFot#7_8EHOXU2E+ky;ux`NrT{IIBq9L2Ryz+PanhzK1_U+C)!c7{GwsIp&6u z+Vsr)VDuHVu@ghirS$T?PoD(TS`5mDDQ|EIRmb|q3KSZ-qFW&viu10cw5t2>tCPfl z^4#cg_8?6|ZRw1tuf4;!BjJl(*t)GMNucc^ffghxDIGHLuER_=8X9u%?Z`nbOQlPysv5lX zIk?-B>5d>O`xay{H=oeqg20%VuG#L5?-Ald;*(pxaK6{2%v$q&c4oP=yfVA%97~mH#n;3ChuBw zQ!J~(49p5Af*4EO?8X9(H<5Qi?&i|S$(+v|i|z|k;k6}uxN3FDgf&>ATn z<>6SCr-9TA2V227yc1zs5gTK6g$nkFZ^^_RM`mTa3OHG&AEkB%&+v7R{$B|3lG*2r z#C`v%ZV~DW+&?@SYwJ8B)}QK5{ds`~Ku*9W>lpGN> z_*7N$s@!bXman|o-lznJ=RNHQ8&f?S>~<_1WJu1m}Js znC_7HrP`>mo-9&Ub1C9R{e2&|dH{>xNjnR1Sg&Qw_s{D($cy1kmo*5oH5Y0ko}Q0& z#u}ipuW?kVVEx^E+vz(&yB!%fwy{iAo&J5{ltJGfPNrNl(4)aA@;YKA?fZoX6bJAZ zcd57UFenrTC|C7So9H5)sY5qa{x%#tzFogKv^{N!v~@yNY8#Iso`tpw{BV!lBw;{I zoo#DHrCZeL=~g3y6WiVy2>c44kL44zaU|4^o}(G#Tu8Yg;y1(@x>ie~w}iuN`+lp1 ziqZ7IY`^Sd{r<|wuTFi0ba{ND_o+0L?SbOfbk@ESXu_f+5@e$Alh=O^)wdF*Q5TAd5$JegLVvyB=?-$d3yBk z0Z4WpAVSMx-Rb*1l%DB@m*4P1vTu!H?bgP_xg@C^d7VvFsA^YgA8gQ zQ6U)8S48M(*A}|P%`4)to~+(#NG1+k-k`q`;2OVF>2DTHb^DH>KCwLQUdj3- zcU6u#Uw8bBAKJH{*JVY{tv3Dyx;fIU{RDDq8X0?2I?6E}LiyT{sYs{@dl1I^MzN91 z!F`nrIPX(fCvBf-2T;v<5|w5DI+OL)*#_tZ6l6%q`tC$T&1K@#>Be061=b5WW?WAZ zT5_@t?+)!8KH$DW($!*j7x5eR+5AfKT^T1~#P=aIj0D2E6btS>DxRu}Ajs1)g>v&7 z`DRHD>mdAwH#0R$sg}eRE%5>8e8vYE+xL~&pnA%Z{%TcBPX};upT*iw>p9k8PMm+{gaQgFGV3E*R9jDMq>@jwI=U(JVUeYXq~uU4J;VRkw$Z9(RxCPJgnDi4CFn zW6)hqfsi&ApeHy3o52)auIiTXsq*VQ=hx^+IXCd`ajrE~I;S@F_9=lH8`x5jJ)_=1nspg*{DRuE0blU|h5>A@qwpCHf^` z;!Xp7)Fe-}ErSt8jxuoWa=9)xP5(Uaad=t4?dkn(1J`}~j|0p}NTB%oBxm;$cmQVP zoM!&%kgoOw$Hp--tyaN#TkKrdv1*Z?Z_;fxiDH-fh6&WtTQ z-!$!QKhuX+c1s={x_m>bR&bZBs3Aoh`)q z;v(e*umleqFW=GKE)HL?KJ`Qiec;VJb8)~Z$VwGc_Lg|p7&fJblbe-RJRwRIv0QTr z4wusTJb#yB5t6TW2Ul6~g1#_u#9KAEbd2*iZ1R72=mxen>k4|&jPRq0laMZ3a-y`t zxr~MC79GFI5v#=`gMl{N>Zilj^Q*`^3Y`ke@drm#_@rmMdRDdn$=2ePc)!A{;eG=Q z1UawqE$_Z!MM7AAbkV0OJUe|YBSrZKK3%q|Q)+O}or+ge)_SXxtCA>DZ15wlV*&Vk~4KfO6>~=MwlM=T8Ok65Wp8T zI};UNs?EQQIvgQ&_5qavX1^PdS=$3I zSf(9#rGQ7i=~<sk}iuzxQ_f6=nwEsQCydApkqA$v<^Au$VK+=>p^!?p*<@Yj{Vf_GthBaZS%YKn-j5l05$iw$hXGjX7&$C`_SDP>8vd&b(z z4@qlyB|9>lH7OJdtYuBWEGBdDTC}jJF4?SQv*6uG*$|`33 zDP+>RU8kUqwsbEEffGy|GpU_BEqQa>aB<(lwH`LiGUk$U)#u(^zSO^a6*8ZeY9s$f zn^n}}G!r{GYOFRnFxPOy#v(0*f-%GflTO<00F@r|E%TMS!W*T%l2%=eo*=ACk~Tkw zu@4aG=BQ3HWmCIj5Fcivt0mQ9A4pnr`os%s*4EW8eH2FC)Hv|6zdti3VtNNOuyBbmbtrtbubY-T4bPH4=Dj}R*lKMvh=O^z0e)4WgD>F~LHmab)D zdO2FdllVhPD;kqVVe8vOjezrSL~%vsw@vN}#Y%DrhpE*vY_a5W%MkR) z3h0g3NKMT6h04+d3Tz%wG1KJL%~OUOU~!VW!V8McDqwwaKK%~LfPuC_jnr6 z80&gUEc6V3UHzOq<_$9;n+2s|FQpuy`*e^_UK3AV%OgX`F|F9qh^^M`a;jN_8C13M zX>wnUxTzNx9!$j6j656S5+OFk>7gGNc*&{^P^TDNMQwc4q#rRz0D8+*tUY&{M{Hgx z4x9DznE0Y+B9wCjpJ?rhub18(j*ChViSE|5I`3(m?7H}0XJ9N7?qgbqnV?GXjPE?~V2q{`D6}J!HXvF|Us*Mt!xEjSzi`#%U4^2@`DQYZgCFpo`zqvYZ zH;*I@Yc{;d?=vr$jC8cfM)GY3xOaGrg}iK0ENl^K*#gu^)byshUVrXxIe=V&>D47i zN%YiATIJibc#D>qz0}Zt|6VVU*fVfL5*{{UYi;>wnh5?JlZ1G4OX#>O_Q!2sf5{p( z-xF;z1(4;%s57rraDl4c&BZ+Ph48J6vxt0qVcnPWj{gX`1p0<%UH1bFG{Q0J5cWL_ zvP}As0AOuTK1pYz92QAtwf~xmME@PBkos9ciUJwrlCMcmA3vg*cQ2GwaYL9$s=D}@ zZKf%*N-C8WXTIE9o_u@8#i$ThTN&kuw?qA_S=7iCRHd3&(IO~$NGt8$>MUGY z`ALvl1sSuiF5Uv}&_kd-51mw=Q&Tg{8MYK4jC#oyPz(7SoFs1W`kWXyA_&u7Ib6L@ zUbwAc;2Qy)M=bk(E&ucM8LKi{S}BJi-_n*e1Jjud+n+pgW{BmN30*Ha$BKx-y=_63 zP1~^A=;ME0${cXp@)^{`(-TS-`!PSor(d{-xK}Tkb_9vOMJXyH#PihXxH?WHF;mPy zw&A4fke7@5jkJ8l!{ZMk3w*vUD6BG=!SPI$5YP}Ut(NoEN(>u-^o*gZF_Gk|(1;5h zv!iJouF$5Rj}do8yII!px@?`o3V(B9rPm*Gnni#*{C!YOb*|{P45@`F(^zO%fqgyRf!Bd%lleA>(S6j%bqMyIjp_&ZH=2*ZY&|T@cxn* z60Qt^xevVaof5N(E0SbL$<-E5Y& znEq}Va(Py=Y`L&QXvi>dWQDR&et*6^IE3uA{nl)sb<@b_OF)mONRT05&#FCI&2oGu z{Iy&HnHEsU{5=(2mz6Ivr5@asLFyf2edT6WZ-AyT6l(q-b}w+Z1J!DRzM!Dy($UlQ zU70Ampz~=O@^GvXK&Qd!CduKcL>9oIY7rY2#-PklyCG!*i?XLS_6`?xYNykhfcZRJhLRpa(aNLS0ze`-Xd8fLFAkNBS#z{K*(W=!mhoTb`3G#BWX*?Xd` z33!t~k6wy++3k)@km$3baujLr%3vg)t%_7-h)!o3yY3i!INvtj(=9gag`uJOUx7_*X_qbPX{x;=zqrc# zqTRTWkCDn(6!XH(Wo1t68(UQ;heK|8glw$UkoCEA0*))pcsz!FuyYI0EnB{z=%Gx> zUlDur-LJ7o^FG^jc!JRjFfQECxQHHS|Mi)k1ma4P%a68SzPTfoE@+IX<^~i-RM2#M zAyetNM!P59iuC+K?$#L<2!2XDKEPjTFHXO>s4Q?VVsSI6ZM6@|XBDOzQ}qQUiA(M5 zz6O+?l zB$Q=w$FZk%!G&|8n(l{PZ`Lj#+gnXR##~c!PuAF|(@W>E9xi|=i2Ml*s#lCDt$L8< zcq*xdSuP=u#2Or~-?qS!&K$$5$!nJPF|-MS4LKKMAc_h&<~$Kyv7}l(XNvl=#1J>b zG?r*KrtRub5?2!jwJW_G2-YZXi3my%*F5dJWgA{|rlr7L8!ZAbdVI=1= zN3W(A;7ToYK7|CbBPgDB@4)HQ$rq;ZF}|%nzfSE!vlOuZ5I7kHdc%1FO%m1R#&{o7 zH$(grx^3rfySuZx%C^uNrYnC=SrK#HMWS2cyD#b7d$znV1V z?|oov&l?jnl*2fFM^->D6sTKnjCA43&G(!<=TWvWX9|O4^;j~{ORYxX8E(aPhQ@dy z>B}z$7O1Y_k6tikIUvMWBfW+2FQlQ!6+}r`IY1qDh==$;rrt6ruCD0DV&dZSJD3-B35I?aCUxzAaWdCT(*nMbo_Ri#Rv7Bzt=6%D4XztbZ~4BBBINg0>{De^6# z(1ddt(t8f+wE|-6;~DlkAzx&rRb?T+1kI++b7=@))~hND?ONV!pIgAIP~_W_QK*xO z7&;=aJ%hUz^Ur^&7O)KQx=q`%ilMx_vFD$^G8leq`Stx5$wE_@?8et$kS;n%hEk#< zw$_O@U=bP{yIFB*l}P3QMm_r?qf&P2TvG z)X3;@suX~)%;ajf$gG69Vsyw@u_R_K#@E|lTgC#TQ!y{$@4ZBHA*f9b6~!K+*zuw$ z+_4AnQ+ViAdSKC~HcJo-&z8HEEsN3CEh=hJ{#{@DoAgB0|r@RZr|JjdiK=**H7XK72}pF#tVUQP}r-O?057ypPapgWc;K z^T%u^ZHB;Q$I_@QlcRnKT=yFV@Ia(wq7q(M4%T!-;xFm;7_G4FQ6`Gni9h<^^_brH z_A~lip`W{kTB)Fv5k#fq8TW>68o(2*U@Zx8(d(7Y(5Cc=T?5 z-qE|-JmL91$;I~DsHP)MXUG&a0-i#tL%Y^wI6s`CW$4s=P~$8*i?g${F(G4Ls?EL} zy@X2sBty4pvBp>?nL#UFt<=oa)j#JeQB3 z&7eQU?ng9vZRotm`FZ;Ej8!SU z!yA^Ow8vMOb!nKYJ@e9@SQp$`u9N!ONVfXTj@R~tNlZOdi++$!J#<`ZughbZ=?AgX zWsun8M+7NBO{6Sfv>~(e?+iTiLEkr;w)57Yld29%Od6=396ca06}=g@@DCK~y~(R- z+PSDC%kGiBc>@266R&-xG2cE|1L9o&PdsoigL1LJa*DYn;TBM2Mj=brPA>O5!DfQM0PEA-jfqEf9{QI93obcN0z zH=u-4gVtoxYe1$dp(L9oujL)5yeN()sacIC7S6Q5Vp4y*+L@Qn zWe{@x+?g~=quMf;cqV!qV-Ilk3b>S8xvUKWY38?N>nMGKE)w=aJ>!j@mt5$!mQB5_V~fJvNxdn03a zB&%0!7fD}s)Qxqn${!6__-plKs6qOLYg)3n=n~%p1_|7v)WsLhUgQlC!}I#X`AWOE z4Ptu^cM{sMlxPt-t4|Gl423CGBx`ly%T?&5r~Dt2GDta|BzDEA3gQGP5xL)uiH2OB zrCrf}$|2BPQ>frIwIn%BO2=ETb)y^4F!!KAlotYG*eX!!H0cqdFNhyn00y= zpH$Hh;_cS_9BEG&4CWoyGwpngWA5RwqOMxQQf@m^H6>c)A6H!^N>22tGw!_JTD8JsMm6-Dfh1^#6y^^gl=B6dz@+hBp1`2u z^puo6>O4%J8bL$efIFu|0Qr~?jDLxCJ!~X3nv|5B3ZXL{)^zI|tM)`&`heQ86nlMg ztM|?wqOiCU^M}*2+KEx%hMH(H*V~Jj=AMf^F*Afrbg2@_au78`fioz^GP`)rv72`hlYogePm9*X8E zNs0;=;^az4n4&KPcB0MQ7cR+=KkMfj7xHoq2IPqR-Lq{rS8XA6 zU+Qv4eFT0uk-<>rZV&#@^w#V@8GU{1hK-(tc=^=**Tsz7v%-|4lp)Se($l8Y3jljK zmG+p7J6oOgj4?lgP%-F+kOU~$G^YA_-MH~gA^T3~#uyT5hB$h}$aG;&>4J&f(Mq;9 zVu#sp=@$GT;v|!y7h$$#IfuFA$&=BtY*lHoDtV}lZVgH2EN9J#*&1IV-ek4^MlGB{dOu8YF4`kgv#?({N|rO}GenqxHYknl*)L?r@yvLzzZCP7*7Hh5Qw0Vh z1t8!P*gkJ~3ea+h+&2)HxP#?X@zm9dPv0T)d0F`oC;b9^>%i|BPL`}kDM!Vfz%VGa z->9a2;((-syf7?y{3!CLdMY8K$209vHDDFXVRuUsO;2Yl{=2?tYg^XpZ++3K*(4ly z;P7wYmr~M*6Z*iK=Ajr_ma7Y6jDZlXn_^dx{b5^~g+2zMx%{PfZ2wc-@R1)s(?K)) zzW(@p4=eFMgD#|%=JIF9Lr#Tnk8!qiXAQito|HzyhF=q6H&Kd}TVeJvyw(xLq%ICE z#uX@UawA67XSs9D=sXQ$Q%<*^c<_fgd+=Fn0Y zG>CA0PwHPjZ_`hNu080Jvu_pc>Z^`K(nNsrH=tvUqEa#fX|cyHTztGzPoh(X zPry|?g96*_NS&-Le$OP9qI-2>RiSiA`iC?-yZHO~6JW04o-&?#j#Mw4`P8o`SxX*` zWPm9qI@HJs19eP((2Dw#hMJ9ekTx9Y57GGGy<;HPHEVIxJGSMd$&Gl3kpzNZnKCO& zDdtb7mW6Bu7bpLofs)~~Wx3-eg(-)59U%9im-4AhKDDLkQLD1zsqLn#Q@eY34XYt8 z@mhV(@WJWhsG|K_;0?*Q!jksvFf z4mSo~9oA0)F?&z;w5)4Y&PxMb;Yk_vr3LME6NYZZ7@^8K%;fs~rzJR1{<)YA#3OBXTmL9ITQa|fFisNB z5HrR{N=u)a2t6f^Yab$e4p)zAkfP&6beXX|`sKivwayBo>mcc+&!`TYj!Y@3x2xA$ zaK{`$wzD3e>Du|lD;WG>q)W?TcYKNSuoBRE>3fqo_m9ND`+|93CGv}VGVDL^r$!M^ zcB=V7i}m*idIB$2;>5n0tJzYj(@aH$!ZJTJIS4PE=5&KVm=RSV_&ANR69Q5J2W*vU z-obc$e)(s2jfC%q;?3gpnBva|UC$YxSKrtyu{dfD@_zz(&Mm<<8<65ihVK*MiF7lG z*>n-R`JN{}0PuwSEj2geeAq@4jmYeD&NPG+S>V;xDhS`+EKJ*<>H=X{^~I;^_st!t zIMFkW^Qc1JP7gk6bc9o3Sc;_{>H0lWJW~Cp&wTr^=1#ZY$)M4HL5o0X?c{T~fiGU*jDfULh_HxkAJ8x$)~WBl4RgmXtp z?01{NGO2=aF|(&^${B(15zI?Uvs5oxHn?87GNzdTt#WU1{8e3{C2Poqc|%xX~6mUspxmPe-)+P$eT__^BPl}95W@LRsDnbr@F(<9j3#gii*(G#*}`0jBO6*k zgM33EQeZ}++>zqT=^E#uM}3Ovc8mFx7;zB>hBv$ln~BS*iNg$2+VT@*d2D~BZND4` zt4>dFVUN>i(fy{0rh;rUS}I_>Eoo7M^!7Uus@6#$##1s6Zv-a zHGQ%7|~ zB`Wc008g~%4RMhJ)O@gvrdexj5hA$a08f$Q`&>$E=^s$Bj?T@Sn@nx~W#isRMj2vE za3j+m`ur6sq57`Ci@0QF`*ESqAs&{&<;OezdtYj^TGM9@ZKbi@3;odq{M2s_*K~y%tMbQ( zw#A3DGGzuH0C_z=Vd(xR)z1VmVRbn>Z!DiK3kBMa5hm?x>ggT#}%l1jQI6%IqHK=pz590 z{~v(kq7U58caS$R8>9^8c>7Uf&as2-9qTV@Oh}0RJ@<5MltvyY;q;mN?X1I0pc{g~ zBV;_q5@9pbW?x(4W5vl7B)GX2IlFD@r2iaL&vM8 zv@AWk5qr)3K418>MY9|z>KLYo%2Uk`vd@|A_AAFepNIkdbTSG} zUulz9A8UMFRHFX$K4BLz)` zaw{mC+UV($uiMz+aVfYzRCYl1E^sooFVxoNy1}w-ZV8^L>#Y&P8rc*a4`}PN`ZKz* z<^58WsGyIsi37UXZqFs0XL8@fPSQiZk_$_&I*~ccEW{t_N9mAVTze{}K`bxWGhlTn z#C?m0s81`Laxy}WU~CB+m@_9OfbsQ+SSHe9ouna53$Q&x=gQe$39uX ztNEMEl6SD^`l6wWLM3A5;m38nW74viW?Y}USl>>pfR*-WjEFy554`uyfxLSVnW}tY z1L|nE3??D^Bm%6_@cCv!*QCnaFuI;(+XB5}wZf_WWb`BVN-gw&G9b^jv?bOp^X-v% zt_uM#p1y@Az7jvbBHmpM|8d)T^26yZPCcfUW-;SlngW`bJ6)UtCPRWf$%L3kel?V!D z9?Y|m;>k+c5F8BRhy_}H`kg~${*XtUu*L_G4X|APCa_I?_sE&r1UQ-tea{?Bs6b)+ z3$zHDG)Z09VHf5~9Tn-u8Z>U!o)k{pFFt}R07+6QCX0go^m~x^sf1J^KAf;>A$KyM zkeuU&HE6mFC>zD{sCunVJC~2TrLC{tOpI>01#vQoArv#?@W+(=Xru zxk2j4gXf^-%-hNKfjTU?ANFvw5MPQ(OK$W@#zNN-8W2~+`L(Z4h6mUCN(p`^!-Dsb z7Y(rzxR-X2iXvVS9M=K`=o#Us(oU*^!E35Yd%`>h>Ut7|1>?Qw3cSgZUgXTcim@xG z7Nh+owj58}4!n*-z*ocX5rX8RmCYKN0JyRi2TJ?pubip18gReK( z{o!j0g48J)XiUm*xH;+*PB-3EioYV0pv*e4gI?#Y4!z$~>{Mz}G_yQDR#lR=)RHmqMX%y*@f>V_ za4^c4D#s~Y8M8_n)>e-2u;6-iIP%a?T6|_rI~C!q%C~vcK1!|@;g&ztg`dkJ{^=QlncqY>-b%^{+$W!OTC^OAKRyuw8uZboBMo)PE(z}zpo+oc^6U- zSlebzr)zsOgSVnwe_e_A1}4bQfZYYx_fpFtz<756TCp=E!46fP8AF#&l_f;B@WVy1 z_~P|cOzLWV7MMSX0PlsnbF3}~g$Y;!HFNv$xqGy-^C>aCkmA`Zc%z=y6SN$5%!d%~ zm2mKTq~_v}4k)JUVX3m9O=dqBK7CNNXio(B4Iy!x^+Kbp%(=jT8pMSFhl@1y^SaBb`N*ILl|cu&8n zXiu`ozJoUd9$@&ai#(*K_m9sq>4exBNrg6(gvHL*GvvJmqE8)^#=hB!^^HvMaaLS3 zT*fK?ar5aM8cJxw7f~KGz0~0s?H!RX)?Xi3tUl`>jWkY<7W|CiVB%_P_U!tW8W%zg zn49YXxxONEZ(Ipwwu-B=3}#FC_R#s>(>RcM0~M0=yYy4zY94q;F6zj@alwO3d2RC= zU>qYAcszmiYnoqhz?vSSXKM?_xVg1@QoralXm9h^U#d$JDUMkT1F0)}`H7(ausw_w zPAI=9%0!1l+r8%0M2&QN{)_U={HIj0TRZXId?+p0Km!&W?gs@-zGD4lNIx>K-Vx{e zEN>{l7VA}CR^BfD5%;c49K&X4zrz}T|0F4#xXKcS8 zVOudO5xcG<`=$s_py?JprsSX8UnPKf&wsTlsp8i!;*yEyaZ9gwK6#RwzY7v$&fR~c zt2Gm$iVr3Vds1%aO#>yyPGfzU_kYq=(9tRtdpaC7mL~tttdeu z*B5ifnO;nI9y|{V{QVcIhQ;(^=78WoC1L4M$QIE*Ll?VII6AXrrXo@ueIDM#MRxBo zt?BE&vKYxioy**4g?ZzGH>Qv^Z|5kjpxAv|tdatAa9o){a#4Ma zN<~Je;Wve}Sk$u7W9bZTi}FmAzstu$F`YlE%UF>4$Puj9t8GmSeFoI1`*v@H97I1YIDX zk2F@pO1YKG@z7=j6j z!?xS=rRP4Y2eHZKo@dHA3Unmeb0wTKqk}Vp+@#6)V}7YuxDv9$2s?k9o_H~>vbPCV zrgCrXJ8VRBQ%8VIS4NHMC2|mT*spLV_~r1LfPsIQS#tYUMroOPOMII)l6+T!YWTbF z$D|ygdB_H%%WW%D(bPNM+5nxj^{%Ge=`dEG!*1y0uSD(KKygdI3ON!27zr9X3OB#~Ou8v9WB~*A zCW`5l=!drooD6|G6&o;l8X~!xn~#yxo)n_C zmnY5VR%2I!Qm!((r!d4Hwr~1(VIg~KDqT?y1SpG6(`)$I&Jw@O;<$Jx-c@-96gIMl z<9<_e^6<97{HRRqGYta=dO;3i1&l6)7D8@_>cAW0LZ5klP#bdS8GOrJo=ECGAU2-+ zp$;s^uGK*z7B*Hs{GgoxEGyVMQIT|Ika*rCk3Y!OSKMK{J295!?LsK>5@qh?qyH1L zP^9%IV+JLnq%dh0)EgZYo!+cn-P6DSK37?3Y2T$O#_X}bbexG4=!%=B z;>eG%R7adpl4vf1I3=N_MEk;?u zJiZqiCeL3B!nvGCBkp)#(!l5O{;~DkH8}e-VA`K@wM7qvoYeA?BWs<`f~3}ObOB*J z4_6hDP$fZ`0Q+$#gJ`e8)+cS4;nnRC0%UK8W;U%(Eh?N_gsWK@(60}S1qn5qJ-FJ_ zj$V){TpcZR_1#R!9T)-cv}>Dw5peY|4mEoRsi=e`R1L~;#7lDQ6dv0j;o0Ns#Dx`> z5h5tZ=S?-f8N!4_{YSr&qRa;eb%7hN(_DLRveH0@UX{0!SrNY@^ z8aXEC==aQz(gHqJns`H}KYLr7#SlMW#znYE4?jfGDDwBjP1DO>b4$kwkm@C-=QX>= z_Vj&j#c9+}7t?|UNbh+UvL8y)5UPR!Us*0+_shPV$M&GYQH0E!OWkaE6*Y!JN zi1lW(m*hQjJ)=|b^~#yjQrzO}PQ{4^HC6>I5A}$w_GtTWr&}vpa>=my))%(&5dn$h zN8^7a9^i7x53r@&RG)Hq+Uv&l2=t4<;)Ysx!m{PI%ErIGLc?sL^X^1C=0b36e}EuZ zr_u{i-G?_}{-pz(pZ^H5`qE(CphtJu{$%#y$=3&g&AWiodM^#55(AAQ3DrP5;~;ga zsO+PmbsU{yXE8JP_!O9Z0hu21@XNf0&qU%xEP08daz~Xl)O|65kvptYD;Jv;(leer zg;J_#^XkMj2nl|@`HM=0lq~=W1J+DyKw?%21z;GrMiPo^+n(qPJs3N2idI0Sc&>+pG?c2Tfw{&!W_M+ri;taEk z2_CTWI|obvLI8>DzNb-V+35x*)So>kbFkmdSpCfd{-K!hFo&(_{i8t5POPTRKhFFu zM~OvZ#!4u8Bulyy&p{mO?#lG9CB}M*DC1!mtdc4=&1wA_-@!j(JI~N;q_)G8MxG~< zp~59(WB6J7C*u_Dr&Y-uN?sMreBS7ads}&nE32H$zhc`f*~6~r2--u8`WLxj`{;Z9 z@hHjQvGlGOEwP&taWi^qlmysPo?8;+LBGr>ZbuiC!rg)t;)`IvJ!p~)nE*_SpL`K>d2pA5lmTMsdm#qB%k3_9= z(OYklgv3UbWj38*lkd}?Uwijv8CTk?7D+51Pd!9SI9c#4=B}+=tb3$hk^7pDFI|oJ zh38gVokRSl`A*inz)r9J6S&cz_Qv86uv4Ge2+xtkj&$ay7lc8{P)0aY6v7IKp30HN z5z*-aT8@#&ZwK0MZd`Td}v3g=3B4fByG|NZ@ATl~6r{T7WBBDKies?&Nr& zX-6kcB%0y_Bv(;-?yldtm^33+-RvZzAz=$l2BQ0z=Tvbv(H+oQ9#OUA+&ftb(>p@! zijrX$m|(q!52Zw-Z{*m-NA3xokPKOpLUuy;kx&LUoYhdqB23AI{MiG^W+`$`N{Bit)I-l zt`*aGn&uQ649~%wItQn?nT9~6d3Ar;&oJKp`tyuy`0$6`8hOJbWzixa{2rZX4?#6E zSMOA>!mry5ux!n0GB3PkQ7TcnU;Kv_su@>f&A)o^Qyz6#1SY8-I8mfd(5)-X@dDC*zd$c0Q*BR|oZD^&_136*Bq)hL0o^N4a z#~GyN+@~IH$oRN1A^zkkv#6BdL|P6b{LO%PqB=5YpE+~}Q5i*jEp7ACUq(-cEYKZ& z{tlI(lP!da5ZGWfup{e_1j?Fs-*EVBERgjVb*IAaGmC#J4eGQ0UUZsirR8<_Www4k z?TNl*SJ#Ie6hC*=1KH!|1b3|><47b&#bkPEdS0*<$QJoyDF#>;8LoyuQ0c(-(2_Rv zLk)Og4lipY7(pkQ~W`XORZvu7f`UXwnVOmNkaZmuR!ETuhS^};6jY()}GxDrN05`NwH z5_N~9=a*n5n37eU5+9}Ma5A_y)Ru2!KS<2%67lvrGvN$j_3H3(!4qK9Z|o2+xDsRK zxmR3R5h^c$OQaNtWAT@Hh8+|lFD%1WDYjyDvPa%mqs@y8{q1LoWCXB}4ZK#&qVXAXLRUxEkARCcKMGNL6zkEYwx zcxP6ig)Ee_#%I~*NC^i;;UoN*w0^M%i9HFbGGVpeT2+!6FM{ciPp+$C@23XF9?#dC z8UEfXUVk85u!{B;|Hs}#(qccvA6mS~tF+C6o7(DYFQ(j#Tsg~)l!Z>R}=IhL(Nol%dM$?08pM*Qx7Y1Me`LN4f2e10a0h9#ZWkVbL+K+2KtGn50T{zeBGj zD|7D-mf$`-uARJWX$+ruaFtFY4=6k~e%o+3`Cn6#)^AYV>qB#F_jmEVybj@Subc7u zwc+T#ueMruR>TEWO@wK7(#}eLL#1GxZ`rj?7?Jq1p&17qeg-p4P@2l2LgDKy$Y&xf z^J?Y&FCh#Ds%YU!4_uQGsbQ9BZZqL8izGpD7U*#*-06(Dd;;9IY8R>N{Gx{RBCp~7 z&CY(8mFM`z3xVuCbkwscJ)(m>2e{fh*n9~NPGdVkW%L2}-%VEDpS{hX^%=6tGa>^E z`W-6%4@6wv=$fLo&6BJZUM_<4QNB2o9cuQ}y81*XbY3jfXVqafF=D!Vi<$jw)zu9W zD7X}5QA1s0G8P#Kl9IDDJs|<{Rf2s(U;Zh}cG_z>!(RFD_x)&81<{}57EHKbv@6F( zelOYl@SY_f$YKMl3qlQ2%V&E&zh@ufQ*@cfH`Xm|Q=J6TNFI2p{-8FvsG?3p<|s3!j6@_@=mhX^ zM$f0u*DbK#{bazXa}TUWk%IAxZ6&8IGX72zh#_e@W+)ar!JZ(X-9`HNh^{KhqVOsNEl?u7Ko1%Ce`J`QtS$r5x4o>t?Ogg}redHig>3&?($2dMAL zqEgM*JN3F@eiKJE424R;AP8dw?SErh@4M3icx==?+b@$ctdV1O1=ivPfe1!M@EWf^1zdSMcv7MW zULVq>t=1>Jm_Ub@n*`#6iB!rC8Z>z+H+XC1^iWC3vdqE7nU%#GY~t~m*v#N~6I0Z<0$8~#1F!qZ|n-k)C*gnW@`|)8( z>Z-SG`T@8RilU-Qj8jh=<%AZRj!`Bi1J*@FuFU$W=n!X$a{iG>=Enb7sI;?Bkhxo7 z^r974!`wkd{x-(xneztanbVr`GNfwZ3!H({TGGQqH_4j|)}Zfk3yzLpEVjS(2qx;x z`M#l_s2*1&Mn2FZFKNonhU(WJ#0ur8EE&5gw~w>_z$yPUdEmZMQflC?otXVaWQ1b5 z`t9leb2jROt3(r17(*Pm3`|or7DJ38s88MGx~r{bM;e(}xRvTQDtcpTnHr*pFXdk_ z64wkE(6Ag!z-!a~*dTl5tR8#-OA97{uf4|%Gkj9gcE}NL5MmS3x-S8R28z6n%mDcx zg-!I(Ke?_+gXOown`)AQWYhY&*#u##X1)VAn8r`#EXE0mzellfUi!uB_h%e?t7q!( z2t)y>diY!EX7H8PLS1_Y|Em;3ZW=$i8awdDQQMvhGrLw5QT!M?92zs z#sL`dJrAD)T-S}$5q=Cbn8O^-DU*pUHB(0HQUC8QLtZ|WxtY*QuUR0g(dTwRlq(88 z5^)Ozq+|_D%I&}y{V>WlGDEYq9Mfb4fAXdu!e@R~tHqfCxR=+?3o%$oYaA|4i4My! zrJQ@^p6Ns=%ndZP91&H_tn%InZDbzVd#3IRorgbl{~?a)a9~9Afr%p^C##T?FIeD< zypI=h|0NCl4lWp3lyByF6DQr1u@q4ZNCR-VZ6M08y~G}-Ql17&)ToXPQ5 z^7EgTtCE}yUJV0}r+inChtG(5f%@o#2|c0%?0Bf+cP3>4s&uBjgY27vKCHc)eE63g z5TmwF24Gn`(JHyHx~)9esOs`nk^Ql`_oGiY69?Y=BHT*u8`T5&TK=PyIjvCfeqS&F>$6VBMFB>!J z-`h<)dWlMXpHZqr#`7tcnY=P^+c1(xx#FD`z$N?>EZT4t@jF#Zo)j5t5;g9Yr71UM z5_3M2TNJ#p^+%EhQTQ;9G~->r!5`JXwqM^fz+F1ju=J&KTPXEHt!T)un0D zK-~yo&t`S+2c)UoB2|o<4q)Y%qSY1jME({zeQ__eG6*YGDGnv6nJ3-x2?ZT6pGSC^|3Qi zkCA^2`~V|Ls$Puj zP5z!(kIZxSSm zxFQk=RZ`V&XGV8+PbL=Q3w4diO+w>qdDJf;1qSIRbK;*@ZkQ`4J6<9SFXi`iY~NQi zMJ#4f4}cCoWLpcl@eZ1AvS!&`AP0UHNs|4LBriMFmETt*hCT${7uY5c;tVo*6lcWe zW+-RSd>T=bG!^HUB9-&6$N7wmJ&@JK$`XnOtzaZ4vJHeX16{FUTaOROJt zJz&fs^}k|_{+m%FlKjP_Vf&`OMr!U8ysw9Um=PLP03XKAKe7N=Ym+jZ{g7t6b*!YV4cjz`m3c| zgAIT{GK*fkaM~;x8ig17X~O1gGf+X|P#uFBH?*Rmm{$nIsg3ez&8~~;>A_dB&#-Yp z2M@S8TL~!eHH6uAG$*Jp>`Ih+KOrZ7wtymI~6b6Lyl zv7x@Ii(VaDT*@m6cisOk65r=^dkUxYSV)_jI-XRt1WCDFP)4neO|cVf5x4n#^qJ@`<>D}-dP{;>Q$)p> zjGV{((c?5Cy>K*mbn;v8p82nzzJXnDgT&W7O->F`ZE5&>qvWN^FV3lD704MsI~ly_ zpKv+c=EO7M4#5@j#CDUe+`bOKWPVwP5lo#J4hlv+u5ZKggg$unAC5L1^ch%d)Y&0) zU&3l6%MHY2mw?T$uL1Y9R4+PF(|-RMD8cpFL=B9kZ`qn*ui|TC&rp`E*Z2_U)hjkY ztJ3diqrr9f4N3LF?Ckh8=a{#=s22M_9FPnpUq*){+ecC7h;BT&I=F7I*89N56pNn? zVE;U$cvS}4yZgKaz?$&$8n@jeZVsK9;0+q=da+M-dH8ke$gIw;V277ijP2orZ!*kp z=u3ZUv;WiJ4Ttz~Q_bs7#Csp{nf8eJY=F~UGGL zJ{)L4##{fPOhiOe$_LQ9`HBqCWrHX)yu}SoS0(wp--%=kS>B4RtOp>d~N#S#&jPSZFgdhfAqsuAHqO`j06&a_OyaPIT^BYLrG3|=0AS4q45_z-k$xz<$Zp@pHmIsdxtN+)i;{5#V)v8GD-=^IO*TW|;Ty?%7+yoYrtvB{jd}GQAocyA&Jwbru6DnwFFZdju` zY<=1Rk}lr%f*b5vUkkEKraJKC2~fCGrONCHEclTO_pRKhiQ$cBKCfOPgtP5by!C06 z>8(cC#SpS!jnmJeJXS)*oXUuvBN&<~C5iP3$LTieaXylk2Cr_gY(wzhI3wU2Z&#a= ziVys!${i%Muc62^3G(!zSOw;rF5yGHJaqf=bBlp0~~W5&8Lndr+|{<|NODb^Gzh&oQzW zDF#YjTJM>ZaXAf9zeD4ILZAPz1A@St5W03liEU*=JJzR?0j-RFAL!bMwiX9f{aZ~5 zo%CJ!!1@<#aQxsreA4=2cx{>tJCpkgA>0Z}Bjs9c0&Wuz$j#N=3UrEtr#(j8hY}+U zZiH|?23JeVzk@{k3!VJC_quBe3uDJwYA>Y%-w3F@-|&mez7bor6-X^LpxBtSQT7Z& zwCa+Kx8%4Lgv}TGFkZ~jIiq`$Kn$ZqcZX+%!seH5)%=k*{!}z+zzPLocy4pA&|N7Q z?(ysglbOv_L`q?xuYMvvX+l3WzMW{?*PON)7#=kUy$IKoU!*p?kJ!FwtK5*k=Q93b zBlgC}XB05LO8}MpsQ8roo@SuDp?>!154r9@V^l$emXpmZ$VLj3dU@tSR#_409ppch=tt9SRZ)ys8Zm3|FwMd81**FDE?a0IB&lp=4oFfWUBECZw_27~-AG&! zbqtgUDx63h$QWjO95EZ<;0sq@&)j#YpT^uCV8Z%+9VsRuixcE*m3o>>vS>mu& z8)IqNvuN}^pG;fk{gJ~Yo~<$Whaq@u&i`GdA$Z<&^Z{hs?pVd<->P!yz!j|T7JSB* z!Yqa!rt0s!kTYD4?lR>veHbbV?>i~uR=paNjwk-rnM}tcmVxiU2uYD$WrRQamERx#a_Xm(2991=~@k#p4Cs+MZr5D8o*F(wnfKfD+rC3I|XAG zB~d{4AKxdsaCEH?JMWZGtn*vt{v4pPpWUOF($yR&De}hQ$tnvo9#0vgpw(&)Qz0hO zGK;gqd%c{3+trjYZ)uU?!cTu*bP)>b3Ip!K3$@!ybvhZt2@t5X!kOEoxF>w^!&=Rp zYJl1M&#+q`mPPSNTRW2irzO+u%5*xTTh|)`0k(M_^;&;t`J#D7!XpE^r-5ou!3JYs zQzm?WpLjQPa1`+A)YP{lORbwP(jMF@E#Ld<%i#L9RB~rMMH~N__nz4&PteAQj>^E1 zY~O2BnDXpR1vI)ICYg%LEq^b?xki;o8A8qP%JVqbiJ;%j+qkQ0Ir07;OGvlRE9?k?%>?(Xj9Iph6*Kfb@`xj)VA%v_x7oW0jxd#yb)P^(rJ@6(Aqs2}riy`!vt zSwQD@k&Gtg

    >>&s9fC(GYXRd~G>E8@bUMn!+Z6oqg}Mu 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≫ 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 VdbvF%`EdjIs4G8Hs#36u_&+6=FJ1ru literal 0 HcmV?d00001 diff --git a/user/pages/04.nouvelle-section-1/04.etape-2/item-etapes.md b/user/pages/04.nouvelle-section-1/04.etape-2/item-etapes.md new file mode 100644 index 0000000..eb60698 --- /dev/null +++ b/user/pages/04.nouvelle-section-1/04.etape-2/item-etapes.md @@ -0,0 +1,15 @@ +--- +title: 'Étape 2' +media_order: etape2.png +--- + +**Secrétariat de rédaction :** +* Relecture, vérification, uniformisation des textes +* Correction orthographique, typographique, grammaticale des textes +* Iconographie +* Vérification des mentions légales + +**Direction artistique :** +* Mise en page, PAO +* Corrections maquettes, ajustements, chromie, +* Validation, bon à graver (BAG) \ No newline at end of file diff --git a/user/pages/04.nouvelle-section-1/05.etape-3/etape3.png b/user/pages/04.nouvelle-section-1/05.etape-3/etape3.png new file mode 100644 index 0000000000000000000000000000000000000000..317bf4c7428ee59537b18c2e6340ed3e7e4d2e21 GIT binary patch literal 67197 zcmeEt1zS~J)GeUWh=Qbqv~+ih0@Bjm-QC^Y-AZ>#H_|O3ASHQ#Lw9o*?{~jnaWBtv z^uXC?@4eQVYtAvo96Rirj2Id+J~9jp44U}YFY+)jaQZMXuqKG`;4iNnC-sVHMKwfC|!BG6v^I>zt z*kzmBA$k9>j@7}KtsqetktFbqa3XI&(fbeJ4WgWqI4R}xn>CX7P^9P2TtmtA|2v9^ zG%OW-KoS`8_5UC8|M0vh%|mj0#usfmr8PA(i!w+-j3|ny%S*VmyzODF?0j^;++X-L zp2cf6T`280aCNXa&=-Nzyjz&TH`x--NJ8Rwu-G_VZ=nJQ2gkQe077i;!|vO%mklXD=#3JHB)#>b7&SC>RBusGQR$B7L*J6AwmQ=f4GpzjuSaYx|3qe_p$VVU z_K4E)z6pvW6O+IIJ0$lTi�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 B;T-?~ literal 0 HcmV?d00001 diff --git a/user/pages/04.nouvelle-section-1/05.etape-3/item-etapes.md b/user/pages/04.nouvelle-section-1/05.etape-3/item-etapes.md new file mode 100644 index 0000000..6620800 --- /dev/null +++ b/user/pages/04.nouvelle-section-1/05.etape-3/item-etapes.md @@ -0,0 +1,9 @@ +--- +title: 'étape 3' +media_order: etape3.png +--- + +Bon à tirer (BAT) +Contrôle qualité +Impression / finition +Routage / livraison \ No newline at end of file diff --git a/user/pages/04.nouvelle-section-1/06.etape-4/etape4.png b/user/pages/04.nouvelle-section-1/06.etape-4/etape4.png new file mode 100644 index 0000000000000000000000000000000000000000..9ffc0684a483c9de7e6001306e11d9ef84adc745 GIT binary patch literal 94396 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

    4Jv(_5YFyxf{8Wt#DJi< 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 F{{tk6HL3sr literal 0 HcmV?d00001 diff --git a/user/pages/04.nouvelle-section-1/06.etape-4/item-etapes.md b/user/pages/04.nouvelle-section-1/06.etape-4/item-etapes.md new file mode 100644 index 0000000..59ccf65 --- /dev/null +++ b/user/pages/04.nouvelle-section-1/06.etape-4/item-etapes.md @@ -0,0 +1,11 @@ +--- +title: 'étape 4' +media_order: etape4.png +hero_classes: '' +hero_image: '' +--- + +Délais initiaux respectés +Budget tenu +Document de qualité +Client satisfait \ No newline at end of file diff --git a/user/pages/04.nouvelle-section-1/07.fiabilite/blog.md b/user/pages/04.nouvelle-section-1/07.fiabilite/blog.md new file mode 100644 index 0000000..a1a3421 --- /dev/null +++ b/user/pages/04.nouvelle-section-1/07.fiabilite/blog.md @@ -0,0 +1,10 @@ +--- +title: fiabilite +published: true +--- + + +### FIABILITÉ - ÉCOUTE - ENGAGEMENT +_Pour une collaboration rassurante et professionnelle !_ + +Rapports d'activité, plaquettes de présentation, dépliants institutionnels, cahiers pédagogiques, livrets de formation, livres autobiographiques, banderoles, panneaux pour exposition... \ No newline at end of file diff --git a/user/pages/04.nouvelle-section-1/blog.md b/user/pages/04.nouvelle-section-1/blog.md new file mode 100644 index 0000000..970c0f3 --- /dev/null +++ b/user/pages/04.nouvelle-section-1/blog.md @@ -0,0 +1,15 @@ +--- +title: Méthode +content: + items: + - '@self.children' + limit: 100 + order: + by: default + dir: asc + pagination: true + url_taxonomy_filters: true +blog: + config: true +--- + diff --git a/user/pages/05.nouvelle-section-2/01.sous-section-2-1/01.kakemonos/Kakemonos_Solifap.jpg b/user/pages/05.nouvelle-section-2/01.sous-section-2-1/01.kakemonos/Kakemonos_Solifap.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bbf1b7b5d2b55866af7cdf78abfd4661dcd2bbf5 GIT binary patch literal 167051 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�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 Bw}Jow literal 0 HcmV?d00001 diff --git a/user/pages/05.nouvelle-section-2/01.sous-section-2-1/01.kakemonos/item.md b/user/pages/05.nouvelle-section-2/01.sous-section-2-1/01.kakemonos/item.md new file mode 100644 index 0000000..4fff743 --- /dev/null +++ b/user/pages/05.nouvelle-section-2/01.sous-section-2-1/01.kakemonos/item.md @@ -0,0 +1,18 @@ +--- +title: '2 kakémonos 80 x 200 cm' +blog: + config: true +content: + items: + - '@self.children' + limit: 5 + order: + by: date + dir: desc + pagination: true + url_taxonomy_filters: true +media_order: Kakemonos_Solifap.jpg +--- + +Réalisés pour Solifap. +PAO, secrétariat d'édition et fabrication. \ No newline at end of file diff --git a/user/pages/05.nouvelle-section-2/01.sous-section-2-1/02.4-depliants-de-mobilisation-3-volets-99-x-210-mm/item.md b/user/pages/05.nouvelle-section-2/01.sous-section-2-1/02.4-depliants-de-mobilisation-3-volets-99-x-210-mm/item.md new file mode 100644 index 0000000..2c635d9 --- /dev/null +++ b/user/pages/05.nouvelle-section-2/01.sous-section-2-1/02.4-depliants-de-mobilisation-3-volets-99-x-210-mm/item.md @@ -0,0 +1,7 @@ +--- +title: '4 dépliants de mobilisation 3-volets 99 x 210 mm' +media_order: montage_depliants_SC.jpg +--- + +Réalisés pour le Secours Catholique Paris. +Secrétariat de rédaction, secrétariat d'édition et fabrication. \ No newline at end of file diff --git a/user/pages/05.nouvelle-section-2/01.sous-section-2-1/02.4-depliants-de-mobilisation-3-volets-99-x-210-mm/montage_depliants_SC.jpg b/user/pages/05.nouvelle-section-2/01.sous-section-2-1/02.4-depliants-de-mobilisation-3-volets-99-x-210-mm/montage_depliants_SC.jpg new file mode 100644 index 0000000000000000000000000000000000000000..07e50107949819572af299e7758725cba06c9f28 GIT binary patch literal 604181 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

    9^(Vv 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�t@=2wvx7W9V*{WG58_+|ig-+uD-p*;sv;o~aAq8mF#;sN}{M37}-G zmY>vjmpR4csO?zWbe^O%Ir<2u^3nOF;>r|dD?U40oPuqK=d;V}wDjQXxVOdI2?1{+ zJ*eKLpZ(pxzG4{o*XP&>vHetCMHPWf;Te z0Sx{iyktZ*8jn+zb*qF|tYz2}wu2oP+0b%t~vFb`{dBvcWc z#T1Oqd7o0!)@}G9i1JmD76A#nf>-=cQ?p;|2EGtEJi?7beZsdxKtd>`FWTpYCloRw z-H=l+v;erFD9I5opN~kh8tkx@_|v_Li>i&Zt*K)EU9+rebh(SX(w!W!YIZuxCWmqX zAq;JyIT%Q>U{p8dt{tzRTV%tQCseq-c zu}ql+L>9X$F{jkcD?dBFIcR}TI7^Ofoo~aO>u977S}~h4NiNT1NM>;$yK@g0-eShG zm9MTmb&nNO*goTDTIJ`iQHQ1I@1*0@bW5>0aR7#Dlvhs(nmR}R9mld6HOMF|urGmH z>PRaxiH7Ic)ZCR0ypN$0~ChC7gSmX%MtEWzExv4~2M8tW){q|&U zg$w?r(okqNJqz71Sz-uf#Ad>8RCWfGCSTUis5u;Dt#Tl!Sb4^&G{7}ijJ3&+28)A9 z7Ku(fz|fuL(7#_=E}x16=r&4srwx!^j+G~Qt!n08L*Jw&NG?UZJStAOYd+sD^95DW zwUlmNFUvIL2m+o1C;mK)3wqZ*FV71#8#TO!5@*mBC{8$DSG1>Q+P8br#Q@-tJZjjL z^S;De^R0tI-o-} z7_oBlYAI~8WZj!f`GHJ2Ixh<8XJ5Z!n9hO7@Jv9Q1T)rj6q8Rdbb~~DcOO1L2<3I1 zpS){XDD-U16G|h#l~_dg1uO-h^P-L=n8k3TeWp;tIlC_B?3wM0+|&n(2Vt`QjtlG0 z1D<=OU|rKp+`va=r3JxF_1>bcKWheIP|J-$Q*(VK^LG(u;k7E#q4k#dgOiK6ZbvQa zCMN>JP7Qlh{=t70AgZPJ5kPE?CWqXl>%oq7FxN&UX|eLF@z-?Wv5b=#mwEf#kw|1I zqG+r{)ix`e))Y@|`<FxV1gZ-n5)T3rvjn);k<7yYMNdAu+%9dhV z8bXgx>al?~Sf3=Wk&q=7+V%D%r!W%@`XHI0_$zKcNAX=s4 zgBgetZy&w+)#`>Q^eK3*r^P{UuU_2I_Mfjg*1ca@l)t zo_-Acxx3_l)hOL&5MeIfEUxvUq)LpiI@|7i&wEs$`LX>w^McPa|BS+IFHaR4wj-{- zTI76@Mu!gus#9$)oE1=ZuKZq8U0n*nscfX!lx7-APbtroAp1fbJ@JHpgr=t2mL!kY=Ut9J)-g0l-keM;6ujhQ}dg+{%B2BY<#Biah`Qn9x5u zeBhFjDV0Hg7!wYn3FWyUBCJgA0bGz=S^5-G^FD$oJ@*8{R73W%Et~%Uu7b!}gQ53U z0#J2f(5ig%EL7D$X4X{2r;5io0fwU)7sV3I8)eayjMu~@Aq~J}xrdtA2F|U3)I1!~ zuz*5@ECC$RePkj*(p9|KjKmV}=XZmEjWHk^drFI(GU#2urVU1II-D>^?=%h}?NtS&}Wm0Qcl^^X=@p4jY_Co!aw>^r%eG;lMKFb}-{O}PteBLXI zq|BNn@VcqJR=M3ZWk5V%_tSo{ZmX8pfo_5gO$b2UrI`|g{&=iF&bq5LIXb$MHiC+{qFlTj z!KXuC<%91kI{3|d5VBgyf8o&FL+#QRLc#VspdIWN82$QXoHB-R-SgBj|8GyL!(aW{ zVT4UOR1L(SS7x~kMk&QGHf0#XI-mh+u=Y`QcLj^0GI}s*vpjoKSUX2DZ2MUy2{jNa zux)L+bKR`<*Hw!|(C@SQZgaLazefoC>@v%==ATA0`wcN>SsH=L5BgZydPTvn^$LF@ zOYd?rt=Y-7N+4b{PdU-tTI$CRiOtNb?UDNSqLiV@haGbc`R@utKmWD%CO4X=*R6N; zAolM%dEe5WY}Odvfe;7K9c<3n_+AOYW6KY>*Dq?r9IZcPx)nA37UPTQ(;iiR+8Umd zYtW+rFXlhIDv#Ejc*XAUEkrB`G9i+Gl(=fp@78IU6hBKtGEP`7NCWT=TLHG)CjSZI zrkS0Lb0#dUAUYq^8dQC}6xHVUc11CKNF}AoUo)?egOo(nE7p4QEfC&VGlmJB{{c!{ ziJqdjC9tE#$GI~PCXRm6)#t%|5p5!Y)4#>ghQNGJjpm2@lmD9k17tjXw}Hzp)($gz z;Ei3~rt5=3<*^Wb93vy4k5Mj{*LZ6vgr08JaVkDZZ-5Y8ZtBsVWYa@3#wgn=z1GDb z+V$l({$0~!#I7`fft~fYpUY=R*6{#^keL15ak%Q+&RK7t%utcG#)C^Tby;U>T zCW=^{!*lm+M93jf!P!TMx!E%F%)Yxo9qU+?JG>n$9y3;OY^J?woM@MOctp&Vk~AoD zqAZR^^WN?zQ$$0fJ)0{!TBvdS*V^FW!9C1TW;ZfewPvQIm(P{;`bw;dpU}eTv2F9( ze`RFH>=R%vzURI9A3`&W9K@{nOW2+wG_2Fuupj(3!mV7EXxZ+8^_e!hlE0#J;A_fR z0(L$Nz#qC(t*ukjow_aaH6y3F<^pPa0zWrD`@tOCbJnra>U6fbD7>3ltZmT{8a$iz zJi!$@@0V#4iN7*7q59*S{~D0yx%T#Ao<04w|+z&eL^Gm^gRlN6;m1=`M^m>x7#pq8_=q8zpQq8P| zViZyKwc=H1DH92UxQFLA_xsIShI<QLv_R-}gN-@A zI~U)x;ARvZn08m2eJab-_!YiFY@qUX_dDceqR3~>ilr#t`j2Rbx47R3>+Y%=s6W!M zM~>?wn85og742=JO0wa36*;*qv9WT?;yxmv98YgE-W^@A>s_e-CWK(6skE*hWuS}x;WTbxN0q>V5b zECnag#X({??Kf(}`(I8i-tftzu4?h66N?s~k-2DR+HA_$^hJ_~de>tRk{4yqT3Toc zMY4k4;3b{IE}m^8*5tNl%7{z{XO+@r<(D0b-lj&Q zW<`LKjHg3LyDRyl+usFC39Y!w>WY#KG(Ian4O<@{*BoZ|Zv}k%3Rpn3GmM0cF6|W@Wfs!kDk&W90~?3l(gz=tNcJTZj$R!4poM9O zqtlI{?na&nxS|Ff!E%fH^)<66(yU=5qtKHq1Y zEa-J%C)15_-xRUc4hyf6@i)@0zQDhgG??w2JIjf3G^_KH{>QSGBx;}j(y&AmTd!{3 zjiTmqMz&=#!288u&Cb4yDa6~h3Gh-L&)+Jk`eIMIPLdJqbFTAFu6l?TZRi_qQ|PVG zq=9dqkDHx`Ke5*HDaed|^q+kJ95P3^BE4lX8%benXRIhybbx!<*crvi8B&Q&8Hv7m z0eo{J;Nb1S4hvMqTAItZSK@_&#TC+6&CbS>_Bgj<#KvAKA6soBd~?sPSI0sTSvhGD z7%zZ?Bx%c8h?27+_lA-~P5ozKa$f%u=7TxRb!l{ff62|Y!bPPPX=UkqxxS5c%~z1y&}D_96Zk5|GV%BCfbpao%%#)kcm~ z%;gs!acC6+_W;!X9-A}zbNXMy0-id2@ZB7keJhLmwv;{0bT&UPt^Dz}0JF^(z6A;_ z)#6#`gW2rjQ~226?>1o$s~>dUNxz^sM|}~bf=B(k87+|)V!5d%d|U^=7R=h)>uOrb zUR&C@HMVPeDcQqO(|n(KHH*|+u6kI4=qW-X>&_->)^?WTbFv$02s~4`7@YV`P6MYa z{+^uod-(6Hkb1AT#>QvcuqBXc@)G?rI~P&w3OJ^g)s5cQw#1R!3Sve4*ys3WtvVWZ zUq3l&-f5tS1h3lWFac3Q-iUCE=*n&3LN~K*P4;F(JBxXL(}D0wrjt28m#yx5r9m@| zGbzvKt@OP;mubho$T|1BcO*$}dC-fuGjAux@JH(uNw>>knt>IfRII${ZMOqafweqDW@d7M*pq%b0~etIN2F(^yxT`z>U&8KsUX!KrXKa~1d zSvRaPTTM*_)>~FYBY(MVl*+e!qCL)8VPOjYAZAlmJzBPAtf2_`N#4s@#)qD9`j-&r z^0i{*V6UcTDDudn&unyB12m>BoW8$Vp1ce;b%3^t^tTxEB4NG+VjVsWxm12TA1 zZ4-L@(-Aw9G!6k{Z~N4;c$&_EzyR_oEiMa^m5%PZ!{lBl5<2!sa3siq1OT!xfwKDR z0#x$HM@L6hT9Y)&UkSwN(Nr5AVYE%a;^9ecdRzSw@LT|!X@(FQN>%=m==-2k=1uKR zIoTtvQ;y&dA7(jKz60pGm|xLef1V@2|NJ0~b(7+*p>a$6Et!;fRhNbXz`U~+==-oL z4%E=MK^ZAbDz{}p(n?99Hr)Aa;&0Ww@ZX^lHaEHU?O;K2pt|nI=}j6j&AFL{zC_KD zs#uJXIPsR2R;<;j5cY*MFgc%b%iJ#xN73&2YkGfZe&f^OLP<|PX7avp4SIYyKL>sQ zU9g+ep+B$)8a@-SHzG`GCIg=1dt5pigG&0OzFRl{N^**g9NlT+a#QSb|DFCtOLrHA|R+49R2G}pU@FKPF=uJQ4oqr zu4>#O)Vnvyr!&3A5jJO_-lMZY!fK6Dh4nGH}z%yBmT3`Ek<=rW+EsG)GUnZm6cQe@Mp3#)ErPc+h)_vKCM;7O)`DhyMjYjwFr zhE#2Gyca6gD3-lcq0BWcRRG?_8EVh`o@);wQdjwTFmrF_&7pc(_dty-|IGG6O<6eV zgi$LnjTQ~AjW}#+mJwss6JeY^5ouIRC7b;PcW~^fqU=$97_7aQDJ!SKV?#yr6Z5p2 z;w_+kCn#!Hne|H%pO$P9!PCiCZ7GTFCkME) zMi_>TD&1S;?iw*4W=m8LeyuGv2K3l3=%~|?22K*DU5Jg+<;qVVLByN&#QKBxt5Z5? z_?}6t{Jjpcp*cA>OP%Q}UtT6!PyIdTODAj_uJ}7TQK;qwAI(XC}QP*N26}_@eUkgad9Uu+a|fvsv;cc!YlYZ z!J7L@=A#r?Bb^k-Q~YAXjDpF`k@AGdG6UO)m?wr){7x7uXOrj<`H^*5co4X}<>)tb zPF*kz8!h#7U@s;Wks~NY54ksyLq~f88v5G$NZK6#Bzm0q>T8n$8F&>3;uQPs%=_H`bUJ3V$I=no(*=lvv`;v(hpx_xti5t#}8xL zKK3(DF4tI^m#4_fX2@-pt-Hcka~Xb3#~J3|c)PO`VNHZo@U z6F!{$kFRv0iV`(AJgBpc9*4eTUKK`ca0-=qUZ@{Jrt!O`Lpp^B!FiE z5(H=RFY&3)^b1P^hDDXK*3;`FE{F@&kX$;Fnc3} z|6Ploz{!=6>_0&KgK~MJE$Q&SOqO5UZpzs7)T_PyOGw|I7P%lUiM=?7y*TIH)-$j| zW|~TEQ0X@42ied4UBstcm*p=wnKWz}%aHY^e%`HR9?+)-XxoH84za;gSaWb>U(vU^ z>24?O#{3*0ry=TTOKjV?E0cFo~eZ7oCY05WYr5X{rpb00A$0b2Dhe zulYX@Daq1k-jmSavI9RwdbBgT(@WsdNLZM?1*4~y#++#0;OtN|?=M+OR3Nm^6-v99 zlEdhAai}o+Rrq7(cm4(-xcP7>N?Ed( zy&$o-ctFv8dUorh`{{35sX(>lS`cxZZavkDOSC7qV_t0-wOhgm?1LTgF_NtR0Pt*j zH}a&ywMGi;*H2v=`C+8mfX204(533ZY^h{DSS%LOTCLTRU-+(CIpoA?!*ov5uX``t z4JdhzW(q@uQvYXoX&H3E9WVh?psHS-P zkLK<7mqx9X70r&cM3ohI8UB+c*?!Nig0G5;V|lgGgi|z$@znwL+>ZER3+vL=P3=^p zP8fglXv|Z3#vk&!6BL)Qn;00vzK?FJrYiBG+OZpL$z0QN;&|&z-BVbXjL*PiT?cgs zcKR?T7@bN{ehbox=Qd<0M7xMitobpU!-e-{-a(x0JzBAs72N^Icml0tLnK{7;Yf%}ZQ#1bzzRCkdoeQGaqf@c)}&ZY`WOqAY2 zfBQq&z!f!Vge1xuQJeZS@|6MoZA1z z*;z%k)dpNTxJ!$>L(vv@FYfMA+=3N{0EObNEy3O09f|~ZcX#-T1*emlyIHg5=D*EF za*>sjbKbr8^T3^`umqGfKiy>%oTF!-TwAqbEBe^Ku_Iy9CrI9ZvO)65rh8Ru*j%@4 z*(?fc<@1VTmR~rPdduyy3zxhZF)#}xD_!(A|4mek?@I;+wLaiD5~pR z+lX~IJvf^p1#;9$Mtf41gR3wm}yQA$cfo5~)?>Q~ zO}1C7m&nsNmtZ}f$xX|}ivN=~QcbRdM$-OEHevoAXay@DnyqsVv8q+;N1orF)%wJI z96T}9I8{4RLzqD^P>I?gAT1~x9{o6Kk$QKX3`MNFp+3+L>UuHSpCrNmUKa2eAG^1n zM+kw`@qP>O_xVe=oc9ml?a8NWzrP_Y)OclEYQ<&2WblDT!#qG4IoMgQWLX3RN_6%I zUM}rAc3duRQEW)>1YN9XiSt5o2UK}ZRO-L0v@ABOjCU?Zr2w7SV$#(iaK9!H{$vl# zT%XPV1Eh=hVfKDIG&-pLZYlS7ve$Uwg$hm}t^iz<)i9Y3docWzM!zR2eL8)-#p^#X zVYIqI<=h42LV9JY`&@7kYRY@&cu>in&R(+xESG3aL;#Rcxj$s*nL(4w(eR!IhVl=sj_l#|!uN+&2mamzIXYlV zeET!PodkN;y|f?CSgO5hR+*QrVeSlOVMBgje*8d0h)-Le#T0a*Etj%XNE<=qiiwzi z!|A*n6cOY-73q7774RIOG7w1&8nuRCNHBj>k1^0SkK3*-9Ne>t}wXOl2kQMSHw`ww~^qSvm5bi-A zbI2k*3vUTf)w|eLjQYw^KN8F9KPv7_y z6>9mHm)_EKy2PAPjO?L-&Ie>i{FN0J_cp`q_Sn+0P2!H+z2*>7!TNhofi*vYdldqy zIvIqFOVD&<`sNiS*@6yDTC790M&cptv5`gklLZ7(D^IW&YIrnfS7mta(w5X8x5&u# z86E%c>sO4jc?D|(dd&>nXE~IuW`StXMd2r}C2q6i=~{af^DL zx+^sIftTh`-{Zov(o{`7ZF<7FKf9oJQxl?E``()uLq$~U^cAZ_d;!J^=Bh+2I|-Eh z2=<}L@|ONK_hW9kwzVcJ9&fAQyktx2GFz>J*#6-H2ORW!KQpuj;aaBvjmv~Y(fCX! z=glFL_M7qeRrh6?(4zG>vV^eEENk*ElETY6hOvdyga9$gjBl8+S_@ z&Pl*^M|r26=zK7EToExmUx5HnHswGzp*@~e<8pP8{-0+&eRtZ44vU7AmpY-2AWfXT z3B7H_cK$_GR-+bXx+rtblK1d5 zVa?Q&jx#M^@x4mZ#iW-DU#@#Xh1W7tj0ngVn==e6{9XsNXuGsMqU&W13j%5NnZHRC zt?Ga;iJ{giwNKZD9w z88?vkmWt#BkZ1s}sVupz`KgpUCIf&LFm1$QSkOSyJWy}seWa$+uglt*w1DxRCEAW4 z3<9vL-}!Lg4!wKdzF8c!U|pv@zh(aikn~vl-f~c5xHZ71oxxY-Gc%h%j(b`{ef#*mHfW zx=0*?;iHf6xELi4#Cb#t1X1)Rt?Qr8>0n3=`1ZK}j4HHCGc1#7oeidoK$6|l zM9^rX66!FXlLJW?_{H?nixbKXie5fKw5?v+gwJJlTILcv7~5y9$7|FR82ph6qD*Op zt{!qdh0*mvU*>1lKFMWrs} zqZX~m?+YqUe5pqEdw;X_1gM&{F#X(_d%Bwbru&TcKl#EEhPGNoa?BM!1G-YMgZ+d@ zu}yjYBCVsU*jzHNW+j@;*y`#;&TGS94*6U0KjPwI39Wyw zS~os;VcFbN*Zd+2fy^tJQs$57#tc(@BaI~d5R>vq?vLaAi?c}qK6+e3Ed%A1g5qLH zlVP+Y@g&UQ`|09@t+2N>RBbr>K6&kyt^~*B(9Ye4;X|{G)t8ZE)o~JrP_7k1kzjE` z%47BxhKOJ6h4@I{2;S1pDV{0}IDCJ7@1TAJ($HNXhdyC9{oe3MY854{ zZRh2qzRI&q)@%<*D0M#3@x4~8=JS)Wi*tYVWp_$rUD9-HNW`ajR#vNIWuM_iX?k9s zY6Z3sT+fy~;3(h?^k~|bT+#I>4>p3SO6E*rzx+nY%!}NF5T@`VJVz5cys=x0f*wT1@7lRu+p(^=iqa)VK1S)(;P0o&rPuVSOA_3~=oY$H^;MX%}AYd2anf=D8??^q@0QS(*poPyv zT|8i&UVsq}I)?UJ8|~5P>jhs==OrqM@`n5ng~@sXc|G3(rK?-Fz3;;zTNz`1BG_a= zXZF>|0c)G2gO;%Pjsh@J#;f%rsSJqzBYD}th+5mR<%j=;kyacR!Msj`C}o8S<88>EnSnhGYe)5 za!E10Tzr-Kk{mk^uWQ4mwTzw=2YL=@?rdr5hM6vhmjz~wNkmUNE!t0zeers0zvRfF z7_ayd{SiCh{P=1A$NucRGQt|QrV#SHW5ABlw%m7peukHOpxwZF-q@3 zKtT?t#GRan)IF5YjY=wA?Bj~?S~}xlz%Uj}*xeI!_WI1VfWNxcRaWt*7*EbjPPjkq z<6zw)yNa-#pAnV}VU7%K-;F}=j6QE07g=CkO=xc*3$MMX->F|f=TUh1g@zIh&eMah2&S~(jhr+0|ACD~P% zyP&=|?-YO9dst-qqIJdI+4|j$BZ*xH38;cO7c5~3y=b1qc(p6WgGr9z*G$kV{vO%*VPz9kkL@19mT6O-pEXv9P0kP zXsp@(boV>tcZu5VnJPue`k1l;{fr=+<$~IRaRVr5oll#gD zxt9;xYj`ys|8h>TMm%p88AE#S11Twu4k#w{;?o({w)mR<&5*@FqMnF|>b%#*d_A?& zj&(D{-jE%;0A&RIt=m+1zg1}K7eKZz8tjet!z}l?+mBilqZ|55-cyzTQS5efznmqX zS%XlQbLV5ZewX{>Yp)BPptzFZpjm?X<@EZw@c8HjwE8A9is!=yoy7Ew?w>5%V~vGH z%PV0+eIu1lr&u^1{2iT;#o$_Ub>DmYTw?R;F{g|8m+A_`QT}2>y?HLhh6;;a zWK!AK&@nX&810hE<1oA0OV~fIXD_A=O?au9I#&I)TL}64(oN^q*)QG8ia}XKCjrvv zlo!8%C!}OW_5=fYt64?~cG@s{3LUjwfKf`n*a3S19>X8YvgPlo3|)CUl+j*P&RTPF zvhmSPD_tJ#Xr2JTJn_t6vLMsSusfpW7sHf<)mf~L+Bg@2FO^zQ@cfgf>AH9k(|=bd zV{Lx=p06j@0N^-KF~QM7$bvamL6ms8+GA67TAAM)o~n>ii4<8E+_q*KV4qx@+7OX zFP4`j>Dh|W$3g2Sk?fGLn3tNisr_v0pIMorCIT`l;uG9-=d=&}9sn$PqsOPv1pU%Z5})!Ld1#bZR28hI_o| zNO99yVleR>dFldb2`oSs!n&nczM2FpD*esZAt#W$qb!Y~8vH&RToewjWgzGNupiC& z&1DWGu9int`qo+x`qQQz2LhZSty;!AF1J}I6sujIlzm8|pug@_k1nKf1b%ajosK96gd@U;j^Tfta4P$+ZfLC~dwr78X32q+UC?a?n zA&xb?p|&y+HTmkw>rRsHPT_Lb-$C?g?pIYJydPxjHOhB#1X+{{LdL`$wvBK>Kii$p zuFf;qy_O~Ko?J%V#rtP^zk8AS6FBclz0cggh6cE8%yCr}IJ;T(5%p5K7jSu^o~e{g>FF zRw(XK=3~{R$Cq(j@$tEHA=b*a8i%0KrBeJ<;#fpnP$TQoBw_Rq_dc=QOT4@Lt?kS} z(czDyZeCaPJdvcaFs$UoiKIw9ZJBaA)h;CnolMQ+GP}0n_O88ycl5|zhcUo{M{-$% z)PA^xC?0hqdEiE_m6y8MvyRAE2U_nk~o{3_E9sBR=pOkCR5H&Dy%yl=Ne;c|A%-y|O zQ?fGmbUU8sRomKQnM-CSsE`fMP#Gbb1G=J8<3RS;HIt;!hJ^fZ4@1fXMcJ+!bi1t) z(=;6n$c$KO5-rIc_@7~aL;h?@GYgb)`t|@^$61Pl>!g|yqHwDnYf%-Z1xb^InsW`UEWz+P+PSraDAyOm45R?R;{sm;ur#D_ z{I$U^9kwPnTYglG)~g(_VqQ2lTLoGYN;=X!HHPHM zP$HyM_0|qIOWUJqb(6qUQa)7c%d@4mWhW=~`ey?0($ewy(aAZuz+%fdbq5Ot6XUhl z?^jx@{NohRA!jGG9KA`mzB{;WsM2Nfv;5~@^vPtS9aNlC$b>aHqVlzf;XFEbp9|;z z=zls65fuN=rbEG8p5mikzO;SaMmHxPgVlG9h#X5RzNB;_d!CP;gl}fc*B3ozGaJcj zeLFbQ#k93Jloax7V(NC28jI=$d`aVk^UlDhR)lMphg@glWFq2fzbfio!Xv*cxhMev z;%;CQHQ`>)2yHBXm~(u$Zfa?Ej4U#Mq0S|}HZtwz*1P+x60r{?o|LE< zIVtohCrtTUcoc>T5B|&_1jV_Ad`80_gDs}~`%-wl1_XW?O4YG-0W^|NGKnB8n-d!_`|C;Vw2|WG zS3lXoEr~`^AIuAW0`J;Cg-@q|g*3DH-$n@FtF6S0^7pt5B7s2b+ z5e7A;O*&Mcxu39qx?lPevD0++X5LBUVHO?FH+fT%+X>;fm`;5dYZj!oDbMN z_Kw@=v@8yZM3eR!!Y3W0@OCN*q6Nc^5YW>`Jz`EM*Y92Q=%QAt`#=*0F8`w*bl73D zbF?D3=pR7X=oFkoJCH-|Ewubh=D#YFXG2hn1N9TBTb^Id=!Y?N#Bk}@g}M2=1OUs3GY^4{REEKugxKf5Y=eF9** ziSM3>dvffzn~1b7Pu&RnsapmE%!9=wJPOAyF^42I%zD!Navdi1JsB|AE|a`mUPZy$0>%$nI5w#ODs1m*YIYf^%W7 zG#+&&HTBO0I_LX5OULJzQK%1nOQJ)(dXQLBnkNs7-{4-=)H!WQUS1(f8j=D%LLizZ zWOG@<*t3H4hibjzFsG|_8r_K`)0tRUnqtV-1@}_9YU89_)a3pe=F;a6DKgd=*lJYL z$Ws!us%?k*R4>HMi^oxkG;kiGPo=7RFu0am^g=rp2qz%_2DC4i$A5;$> zKVKuXI8+pFiBtJKmlVjCC^Q-ceaw^-nAe66JTvZD3ea(u(pLdR^5^Ht{vq6q=1LHUW*-NzeD zt#;m*>09RwKV$WX%V@$_hqL9XFQ&FFJz7Otdp1}3BT0Wm<=5EBV0rBLQHk6M2Yty| zSosG)75nHkRW}^{3}!35%qd>;Ib;{J6@@vp%iML!*}uBc4(aJpaxt?o1t~-oFDT(+ z()74|dLS~Yeu7shVv|bXQUKsk3*gWwYL$;$uSXa0C2Ci3hLw-f1vABi{FWj6suDP_PQtQWJ&~*=T3<$oZlcL@Q6RP3ceUN~EAB9d?uYY#2 zXi~!)5@*45yRE%AIRkZEq1t5Mp{nae)joCfem?rK5&Gm7KsaG8#-m+BRCg0W)XbeZ zS0JsIX+4ghWMZVo8dA^26SoV$MjZM`d6?_s)hP<|rB-$f)%-!^z!Oq1B@pwxr9kFz z1}~8?qLc2#Z%e3Ui<#KJU7y#Tw<_6G@KY)V$tt!3@txNZ06!trx$E@t<(9We7%62!5N5pcMQ{E}3-@$0wLfG>Q;ystk!tCP^t-OWM^Aow; z^|=8WaBX?AU};&>t~#OJY^1F8nd5uVmd}I6M_I>Gl;ziKd2j@L`Hbo2IT+rbw*w{f&k&iTegS4OOH|; zO`Du9TV9BO>q#{1zF{SoSX5KaYn3?#(>f20Ub=rQb zxv|^y&Do|HcYssT+CplENHfd03Coa3Lr)4d8!v8^g1DJ`&vwfikQ4QCztA`7ctNt$ zg$iE*AxCnkM$s=uOWjNH@?>OY_38LJjWwn%Ou zRn997xx05`S(ukc_|xBg_0FGz7Qpg2#=`mX{r0rFLZ0x_yaVCXIG!>1%Z}PqDW!>> zzP1TL3>?}m z<$d{>!XI3T+ClLtM>Er6tW2BaExv`r>diAQcbrGgK6JeVY1yGuxabM3i3MDZZ{_I% zX9bjvx{=PaBNO>jghbD8F!Bh3Gmt5ASk{3YuP>ndd}e8iKB}yqWk8YYHw9`hO=o&c zjo(tIt&f7h54lrNHSe&q;sY%o!u36{Ho=s)$eKECc|{xpa26sZ1s8faZ)iQR2n?^6Ey zs)Lv9i3B9}PHoC9*m&-xn%@!~?;dS29QUZ+LW9WD=vX9GWW|U3{R2b_n_&@(7JykY z&S@3kk`=6R(-X#|G2#GU{Iu2_{g0u{r?5h=S0KRXb zmB5?9?0Eor(C6vn#gl-~?P=f`=6=)tGIY~lsj z+EjbgR1$t|+o^Ao&8*j=DEiE&)CFfS13J42TBTLmPI1Mm?}VegDM*E9SkW$&^PW@e zXxe2us(a%XP&3BMrRfY79*TSPX6XREH^wd8$bRV4IZ+P4qc_6?ouA+?(JwEpSNrF`G6#+fBhohowA~W`IT)wJMOz zO0Y2a=B#!8rgjfa%Iq*e?IS)tM5qrU_&!@YAoX`tB_>}-Ap*pQf$HKJulCqo+`1ja{KrdgF-t`wh zK7I@b@}Li;c{ddNymZ$*IZaXT-$b>Nw#8W=-kn2M#3xT$QX$&Y~H!g*wiOz#DH@d5VTYdL)1u$(n-Tq z@CJ7(X^3>65!^1qp_A3Hp9_tEsFE<~W>XTstpA7cQ$Vk+!fQ@{Q8mpj{w&=Y_prxr z9sRN>L;gk?YQ(MK4ZL@;S?o;{()X;8pYTE&upln9=x4-;bYx-Nowl|dPeSEf)u<}{ zm&!9l48nTY;<9d(91K=RyE_%8WB4i?b^fjz8uyUA<`c5u^C>ooTXCB9`Mg03ncdT( z&(4dV9|@l-|Cwk(qyhkE`69&9mLqK9hsps8=)kC7xYo0_tg61&*5mv@&p0=`zmF6d zSE$2Sq0wJg*Sqi+rJ1upPF+UgB(6AFN}d;nfDp^{_O`UV;aS~`3;nF3mQa@O)FUOU z9~3tcr9C&NJs!k8H@7&C^VL=%P2$@lV@n^ZLG&zfpvOtgNy9{0QMy)c>)|bhvE0a2 z$OeUd{Nu4%Mrj4_=8tQmVs9ITvwZw}_SF1-vAIeEW~r*ANIS1hdUyH#Q4QUcv12X% zy3bsaJ6A$K@IA4f{{90nJ^BR-B0R<%k(a;7aKBTn&k}6Dd@D^EG{39JwpCz+TG~7( z%Dn`AYq#-PNL*l=FF90)uSqgZeDTK8lQX1^POkZ?xe9*NS&zuikH*2N~Fq1N$|wrLDW&~JvJL3ukeX}l^3Nl zi>8{eZ0ZqTR^NG`@RIYrkV&I+FgSdv%0?vplY~~r{(w828{!ENfC3#mDHKzd-@d@E z6hWhlJPqNWSaKZSEth7xv2Oe;1EqjMn9!MtdG2x2sIoH>`wIKxPaS(cR@NR#z8y*T zP*%42+NaK2IbIw0 zX&xWOjRC(~5d$TTc3=t@J8kv0T3Pf7bt00J)PP6g?)3(*ZG&+mGZ~|tY0ZPfvSFQW z3Lrb>r*r#c`4J&Xi-Ji{{%5y~PS0&;-@wlmjn>a0Md-n9uu@@4z8s5tb1jcam+(&~ zrPQle-(j*HS>-oxG7DsgK992J{S7nibHg4mmdYb51Sg-P6t{Uw#j1w2Vd zV6cL699@EqnV#$d?BA$|5RG2|!;d`W@A=S?6U5q-C

    ae<&1-2~+Blst)<35Qg<}?7syh~iq zPHKgUU5-eK5NCy}T@>d-W~>Tc+8B~fvIrbxXo_7KkN~eQxS94$DuCDNV_1OU(DC&@ z?)kPEZEeeu1d+eHTIX}7B`U3BqmCSMaru8{6IGw1ZWLWp$FekkReLbSI z+?Qp2u5~7hOy6Id_8UiPZMgWN+Tl}9GPjS{K^Xc%{%u95y0kAT80<=XvZHbeZXGGD55x$mW=w$q~yn_sG z1+lzFl&Zl@75F4=o^wgLKlKoodDsVAaef(225dbhC0}6IR9sRem}qppG&Xs);IKEp z{3o2b9;egNXatV3q}qJ%9kEUiSB&-Ah$m8DDD~C+YJ{Vqj#ldh<$};_EX);ZJVulg zKt|N>28m+$BX=?9sXskivUPNY@N(y2@5xsS`z;wc-3Q7hd{wxA-K2}`Gvz1rRW>*J`H7_!P#J4R_URR{6jco z=drLK^&;R#vOn8)4t^!%cD@pdZDCDOiyenN^{CR@`MI*>;`gWHG`3T7#y)v6MVF9bs(IE{{ z-meQfJRidp^6jXGRr4MeaYx;eyrU~v?y55wdlsy$ zYib-Nq!eVV1hXPgrgG>=wx*?GT;GwuupJ4kS*d?PF+7a%_U7`jDu_-woo#$qdr@

    TP1(TH~(^%OsAp;3-kOAF;G?a-P*L;aX%mV+*!7bScBJA z1F>Y@*EDl~QMU4pO)9BHeM%0~)*xZ&`&*%nEeBZN2xsZhKGzJ^4UH0Yzn{#Yoy zh7~fr@bqnc<*eM40VI9J;6j+L!>`8~>MS}Ka4x=NwzgiWp}p`vI~xYBvegd7M|d;a zIX4Y(-kPwz0Uz2#S)_JFq>-X=0G{C?ZwU>RnVm+g-(?o;XEVpia3cX;)Oy7wMlPx} zT1qr!9%77l;q6Kw!evC5pcC(+W$xa}f&@Tr54{^A6|{>GM8r|;`3+lgN?TGyy!Q0a z?0|o3j_S;H%6U)1$I-9|Bcp6D5*fi$lx$QP?mb8Kw(~nnr1Ryu&fr{5Kl$;;7vm;@ zv8(sdgJpkF1+#&w&)!%dGeK3Nu+_#kY%KDBj4c1(!N|Y)|4F`KnQDRqJMaa;R9mnZ zWe&krvVx!RmFi&w^uMV%*#sg_kl_VPjt^)xOnh)jS{J`ioTZGe2gb*gTT;raNQ^F<={f? zoGdz<^!!y4XRrCxfc!fnp*R}?2fMYyWq+p}t2M5&o|XzUlP~K0d+?Zm z9X9z=&ri8jSyUMxPNSkB%MkTDl$05Dc!{bi9;Jb})`IO`5G9}TxJB?=9z5&ed(|C+ zE$3=I_tLV)G@@orn@NFnRPRo#OkCuvzhJA+p}Hk6N?!G4@le+fs{~3DdKNnQnLH-# zA)USj`SwP5v7Cu;89=oVQwC}|0pfjt*@&6_LPDbdxJc4t{R*fa)qX7Qv#9d+kx~xY z>}16J3R#x^mqv*VG^TR7^$~PApJ5SF*K-f{>>QpaVuIp-0EUYBj|Hc2p6+q}*JsaE zPB(;iFQ)fMo#KyG7X%U0BX_pbo#@U+?1PoW&ynH9VyQPLlQ1v615uno#-X&0dktaV z=b7rIy}s{`3BE9qww^xZ=2T@~FoSbZaD!Kpk>tP~A)W6dGaG?IORXMXcfvDd&Hu!q zzO}?J5GDVU4`n)!b=fU4eOel!4e}1Wb}wBVKf1v4_BwF;gIHlLI_s=qXuh}ap$hWG z`l3wMkeNo}vsuxp)!KDuipY<4l#i+$s62;rU^e7vAYJ9luZ%)0?^IWV#Ws zW!aIUyGc?vL(J-RTK{??bLi?ah}C3VA9t3pSzT1ElFBrK#opeH=TAX%ABeijFV)S` z8t@$g!=cY-%jQTI;Tn$I|D9*dn11Srp10+f65+vK*#M1oYbF1fxjtcBW`Yg$yIlzjf`%jZXO=}q�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

    {DkDgCoqQr$!KeHCJ3mATcppHkKVjib?E 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

    `pnm9e|^jU8^?r7aB6VUH^VHL`k8Rc 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℞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

    2CHKeudmS&{tt}p=Vun;ck)mtdl~TYEYbG ztu3p<(uO7i38~ci!Gv>K&vrST!47%-20xsrPCC9w&-BsU%byA3oXg7dp9xsGicPay z;pVR8@#UVz=aj8cT7vsYQ?(8K2$3&$prgHS^b-9&Fbb`_oJV;ohT4U#UUN2y$!r*2 znF3hjetBnZ3QGkZO@hSsicxd~kIk0qb!uK=da1+0d!7brbv00Ce&{FuoMm=K!Ryhp zFgBy_VRW44(>WPZIWAP(3YzBpVf%c#fan#^$JZ5S`=yY)_RvgW9)l=Uww7gc`%(;Y zq&@|-E7tD3q&@cN!JOca``PMlato4ft&Mtv-7%5 z?&xrQFMDJ|n2vR%8a4zg8n|3UuuE3Fkdcd6pa*>M*y`s8*3S)< zjiM(=_EwH9K%Klb+?umu_jt-x+tj;98cdY`M}~` z&ekIFGBu>_A6^zO#64%+Wh^n2z4y(5^K}4!kyp`Jvj}M;SinnDUGR$s_w$caVVpou za(I(ROW2zDIM1+)P+RqtST`rtoW*;{C8M~uUu3x;du6j=ojP`|!&7d{dYDwYM-4Nr zoP%6!64NL-F>#Iw$rldac{1OD+EY6EJiV)6hV*P$-p(6ij@EfcB0Ks6-o zWsmiw6E5kL*0~vVbiI~D?I@PK!YXLc3cj85NM~CoiMJMYFjU-7Pu-QYfC;(S?-+G* zce*-Qf2f5M&FgIju)?}5dFl^>m(fz~Q$bZ|jgEd+9&DGic$qObr?KRRDGhUix z&IH}ON{DW@nESiaKou)sUfJD!Z|Pa_eofJQ?@&>2|EXc;b{qxxig2j9%+|~2p{Pn< z9s>J!WtCyx!uaSNa%Jur&zBN%U#FPtLZx&I1v}bg3Vi(?;UMI(2kQ55d$#k8p|K$s z1-FhqgHdE$RAEwa)&8sdbKRosN!Ck8M-r)RriRYHmv^aK+rXx~xjrFe3vypMY6Y`T zjGxTZ3erTh;s-Q|O|B(?942ZEV_ZwZ*YjO$Knc3RKAY~9$$ zCF6|4S9mBTUh0JQNc-OcuBZ%4*E4U)poQA;yk0t(0##=1+jy*p;Uuk;@V|%e|8Y6}XT|iVF8k5(>-hxmoh8oSSSV2)|1LfyfHhn5GQOOC z9WJflM{tM2ASKFzV;DDPaps1LqW{{rbMSlq7TEd^FW`S39Y7*hKVj^2{K2KdR#J%B zP-Jyt4=p}DpV`U9rZTfl!;toEtf=G2Mt%Dnd(Q8TrgGVg_kP*ICX~QW?NkmaU<`?k zn9pIy(Gl|!%BV_2{$Yqc1JikA!i8S@5k}}LmJZ!yX!cpY-}Am!1?F@49ijK?>zUX1 z{IlLRgYiiGmqNn$vOoNBDhHjn&%~Y5n9c$59)shk7!)dPn(ZpjUnG)2m560KjZM;! zC+1KsMKrWM0$G5v+N~&UTa);)W58ooTNd@3TAp>`PZRlZ)m~+9Q$C3=kasN_GccAS zrtGo4-S7zG8sws6g^OiOE*{s}EBC|Zasne7Ah(ojevg01`0Q4x{NcSVUR<8Nt8u06 z1WFcl_O_|5Mp;`eqlGYzhF=X`^zwO!xW~ZCYSKzx4|H)Hi)0d+$J~17%f<%ZCTX>d zXa}T{zJUVMlu86tYpCeF@)HoUTosQy)#~|#!w#*N=O+K0Jl?e2>Dx&s8OgK#hEvoG#r%?zF)e#kJeeX`g-$h-#zit$ zl;d-Vc<`s%{Kxqb2D<9Y*(+v?O?D`P#NfDP(y^<}VD3%Fp9dEDAy%@l?*Fw(uMI%@ zHqV>FFzyI7W{iK6CwIL{>!6^=Mj^kk)PX9*kd1ll_!IFnVzn2>!sOF1Kybt6nA7;` z&v3FF*q7X;3H5@+ISpP3IZ4XLv*7hb0KW;!zB{?46z(YSk?$x~xJH$|Byyj4jCzyy zG!>=;(0(CejeKhS?Ylys!wr?&{tMGtcqQ@p-OQ0;4a6X7LRyGkB7HGFzIN=$l|3He zY4)3wW4{8$uc1PoS?w_^%UnOqAb(a_LFRPZ;M*pL0>2aeIJy{YTG)m&ShgRd!Z3?x zu3Ub%1)~&GF4@DL{PJzhE>C@~${n0RUx{sOpU~uctJ6?{UYgLpB;5Y_|%_Etjy1+3Drr94qEB?^l_Xv zs4&dlzKyALpQoLH>6~88Z&VIh+wrBF)HOGxN5a2m7CMM$6hr(aM{<=im}0;n24@DI z+D|pV+KUm)PFD9hv$u8@M7CtxES*Ld@oF7+eg)p(JG3f02i0`3|tDlD1W7EKVEw6wBn(tF7tMvlBsQ2EI`7ok)5-7F{yYp$J{VR(&WJ$iX}03de;sC`Td+eV(%aT>=3{6{uIJsAk!`c zw(v1C)9IsnqJI@(zgu3xagT{xOxz40I`Rn$x0t7p9L>Zon6NA--_BRvMksA{!gM&Y zLItHFy-9XO-HNVR&U|gP@AiyumygO%1)9>zAT9^uy2mnVg)8#6 zbHUIY&AwWSBZhNjrb$RqItCw-19+zHS_mpUu5PC88{=D06fj+k;iyj&_H z#{Wi?URVb`nkItRb5X9`1@~NN+1UK$(Fc~|#ZM$l82COKx^vF>co{nm%&mh`{fop1*2)_c-xU3CVLcni-~r!k6ancLPY@FP{@tG!>A8>b^O5UII%+Q1Q&yGq4feD7lp_C4==Rx*@V;bfg=6YWGwGj z@&oD3?JVO(U_@77yjx^4H*WBiC#T+&!ey+LzsJzf(0z_8$7&6m(+%PSk_hRU9sueq#mX}UL6Ak zvWYey9S>FGu0|K34jniL6+e458~ItK{f6uXshcbkSa*Z%!|73&#~IgO=B4dSUoE#{ zlDR+$7jU3fLoh5=ft1+T;>I>sZF;S|85loabHppS6=~L&@w;O4F^%{QN1CHP2f+(T z6W5ogOm;X>8bDI)6D_-y}U!BS1}raXw>Uw^kjuXA6Q#cr{F+&l)sqm(&(8z;kvU@jHN}bJPW?_K1QwoA-=VfK zK9Y&!zwUBa%AaK;C@#3w%kE;iaMWf}4Z=9|)&v(2auOF+gK^!!sNH&9yaDj+%ly|@ z{-3b!f2?SsIBOftF8hsa{hp;|?zx)w)AgW0jNZ$NNekO7@&J4d7{jS<_fETem$kDY z+&DgS&Y$|0c!65-I+by94d#^agecnaG0-`-gMK%n>Jf_VGUh+f5~b693p)YA=y$5l zP&Dd_MOATniWKxn0*|lnaeWq3x59cD5)aBq;Qi#y^*)Wf?~3EKtzFY@Y07uZVYf;WP= zQ!RH?Ub{`DAI#R8Dju|=E-#KyH$B?mY86@Q^mKtcj{)auqEp8&H$NtQ85jMSSkx~2 zrb8rQ9XD7F$gQ_^*hbX4n7CN1iA3+$WctLh=u`Rl=;*!)vw9?!d`~T70KX>88%wbl zb4NPed@WhKFByB?yC~MXh=u({6PLOK@r;$8_GB zN^8i=stK9qk_wnRK^zZ_u)Kt)>+?aQ9sU%q-~zw9e~pKUI8YpEr!tqycGx~s?}{<7hy z+}}tvF^sh_c+0>k0ZA6R7CO`#PFoP~>^Q=T<09o_C;0`t+Bra~pVj4_m2b=54|x=z z?#0y!6=`zIJv;LB&K4hTLDoDO2~K@vWw2$L!T3#}vCU8k#P>udBtIm8Ti>(@Yd88G z5j$>n{tu6A`VJ1&MCrOn#a{s8g37uvzrkB??{P=>y#L@}+5z>V<|O11c1D!jeRX4} zYs}4Mah7cXkWO|2Y`2_s8$8~dI<-c-^lA^)(bjhXU%VN#;TJTye21LYzsq^C>@2xS zDeQ=;buluTK2TIPVg|{bXMN@yE&g06==$ufj%b=`43!s`OK(KRI4ZvC8a_?CwnQuO zH-qkYiLyvWZ-w@Ct5&@t zA3~pX)U)INi@5g=YN}n^M^RBkMWjnt>0OYbw5Uk$9SlXJm(Y8FSV5(C0qMPWLXSxA zy(JXsH3>BVLgLB0XTE*D@67Cd-rslj%=wedgtb=Iv(|Ip*L{@^W0%VrZ0@L^oTV1( zwGcuzu7CYWCVII{JZ>`e>ynaFq)>NQbw&5cES7m@c~GWM06ssGT!W~|C8rmX{Izn& z)`kiPjfXO@nXTa4t*k`p(W(pKKoNeqXKM77TmG-1?- zCc(!E`%BCF-#uvD0whDm7Hd(2()l`Owr_<6Rq64ei_Do685z;;7?6=MM_MEUGt?o~ zf2U24gf8#l?MnY=HKs1s2;XowT7^}W56{-csu~?ksbXkD->Zr|xl(#5>(B-V|roUSfQ7P$8z`okesO}DW6$vo#$6i6d5Y28&~bE zq_~zEvT?U~tSG*H_1xBU!qzo_seE4o`y*ly)DLauRY|ZP)KMzj7)wJ<>`{zL&I?Sx z>_2Mx1si2$N8+Nxlli=W1ytpRkOi)L|!gU?fVq&eTsCoTKR2bnmvwy&zGcd*I zDO!^C*Fx>R+?&H{sdoisk7pX?KF%_K^goeTXqNoYmxe6|BuaIbpUMeVR}pxor*>N9 z#eLW5+^K6u)zv@#8Z)}`mUegTG4nZ+Uo1i;oaFp4$ zd|uvEFG`o2@@N5wSQ|F72C3gpgXiLU>vvuQc6a4EGY}}iG|CBUH4lDZ?8`nDg;t;4 z$ev@%XZIw|#P%2jz*=9Hi`}=sElt%9F!F%-%4Zd#f7i2O;oeiqq zu}F+@<=g!4Bst)F_oyA8J7fxzjTV*s>h)f9Isb;@)tH_24G;9b>cdQIKN9R(O)e(c z%-LDoER8OIqAAde%<5$_Po5nPw!*$cjMf~zOxx=gO#(~s_49v7m}(aF5otNWu!J6k zgkDfvwz-*6DTgkL__+ESgsVwM03~{q)NfmBjxriQW=$3uQ7h|v?(atLfA29!@aW1X z(t3fY&`#InG^xS1C4_5Zd~&7V8LjBo4nB$87cz}pRn8%w%QPOl-bA&8i&FanvU>UQ%4k3nzXChbgc*>RdJcp_*h;@i2K&cJecXJz}iYrB`E`E~eHm`<55;&NLVW5g4s9TM$Y_9BaMWsN$5Ox~<;A^rKgEYm}nMslqOGDhaLPMDJ?3Qu@oh zch_MNmV?0co+%`95DwtOVc+;>=rbIG-GemdWTNd?pf2Do$bMNp$R(i#y)NwMqsfV@ zg^Z64vZ#%z3p!*K#k}|B-?a2NciM7jfS&`c8XLYs#oH4(Z4OprpWl!%d`{{?qaP#C zlM(u(4Y@4(qGiFgb+E0&gCALG%lwLSmeW;}v&oU)Lh<#jT{lgoL}3Z`0ec9vm-0QU zW_`P<;VH!Vl6nvoF*1b;uAediO$s}i4}KkflaU(l=(;%0%|lx^*IJ@vQM9h7O^(kO zyd~bggZx7>BOJIW++<*e1i~M+wT$!^zR=g(PEF0DQ5;hY;ZQK7KxS;#z~v1} zXIpHfOJcpDKwLQj=lZnDANq}a;(AodONTG)#qz6*t4D+G3n;WCvRbe#y(Fge$(L@D zEI*VhXW>V~vuqt;meYOJy3F&W}__5r5Xf9j0-;jpx z(53PDwU?#kuyLj1a>IJOf2)L+F0lcjb9xM!1Ct*w$OE{&WW7hn)gVhc&~xcT{I^zm zwj;2u`|FR`=@RzyCjMR`&A_LS7cW2*e6Sq|`YiUW&4%Eo1OK(8jObncPfz-|fHw>R zj702GoeHqe^&Qd$Hl@V8A}TtD#}zk)XE#4y@)VW;CSZGzE_N4ydd}0GL4-NqKfnGz zTC%@)#AZU~$_bHG@rUFQ7Cl($L;TN>^4>AvHkmwjlM-0G$3HA~l_SZdK@E^lqvd|Jbj3@9{vrSGQLDo7lPz!HJ`X{Dr6O z=i~n5EW}BSagtUpvBz(LRs+ALpyW#C*Wz9*y!l#g@?%o6lHzFw?KaE8GKKULAGU3Mz^y7=MP3r#vnC8lR4Djc&~D8<%~dq_iQt4y9>(yTF9oN}d+Q<+!Q4VQ703%7WU{ILeP?*o#TeXMnb|9O#i!PJ#uQA^!1(+Nu^d1g>VVu)9x zZ?BI%R`PXz225lY*YDoA40RhPeM-OZRI*UbQ#jixwKom-qhYy?j5m);A-FHO6p&Un zu4!2%HJMR8>x26UjsW49NP82Y zwa%M0{%V?06KSeVIy=ogEO{3esQjqMzvT(#DgN7j$YIFzVsrjR{&0B^oKaJLk|6?+ zviodNev3UIxKU*$1}XD_5<9$4k~y#g(pKUrzJOW1tuCZ|PjGI*DXNnsAZmTa-|lfJ zTo z*4NA)z5r0}uI+SD)sp5#!cRTaRPuxjCvn zvf~pBZ{6~_viE~I3(mPUmg+&=tsew)C7FWJ;WPod&AX~iwH(orATMX)60_EkzCke5 zz5MkPB7^X)NwBoHFYArg}Za_Q4g1T|ynuFLmH; zhjS5?0-)wKf~w)ndo9!1N#e4x8B)IH=yg|zUqr25@+4cT-~Yk{Kndr zN(YyZEI!AsZG-O-30>hWQ+7w*jeVd|!HKDN@=(lu%`CH}PA99p=tqSk`Naf_de*5v zqi3`%la<*G19?$5`Le%BMDgZEJzdkG(-Su|FueWKP=|!=*zvgzog(es@Nek_O{8b{{^Ns^&i8u{+hc@((B3TLP-uFYkz5uuV6oOO<0hP9lM?76Ez+_ zr40SZLi`|lY2w$-F8B7`vf+tG;g57t-r=75%B=6$o<17*(t9%LR)qavu>yiMH%)#o zzdBAas3IpmM4CkzLrDy?+rlq5MPE$rk3!RmgY_yFl2Ac|aQgbUAud)z$K^zr9RE@J z`@c80*{P^SuK3*q{3rnoj%jBK5lZ8l zYHryeiO1ocBO-8>8E7SJbXU-FSI1%aMg-vDLA6W9K^dyObrHaRDCgH$T4Tr@W^0IK z?XH*NmZ~~V^Gs%Z6_+nzCShaR2X(1S}4c04K=)6GH7-*pb&Fb zR-k^y!=)BOcFm$n#Cns>AT6+;=R-w~C*5is@WS146R0>T#{lwiI6Tae7b*@Fn#Y!=!1}KC(LA{TpKv-`ZBs` z-%ZZm>6%TK!+!AQ1X)0fAWnP_CG4N$+>0Q6O zxiiu|YKtYhCV3l4t%D>uW%gW=+izSX$$S)PPljdb7@1x;a!P%=^45^Dwjoy0(HU>o z%IqIHE&S*OQ+|IPpa7{el=0#N^hz%)vnHCWE6hDHAY^VyqI)RmNWQ_@!}F#st&cH> zzN274Y7}qa3!C=f%dNe1qUQy-d|A$(T(xoB+3b%w{QH#Mw&NR1i>ENA=D^Zo-=N0U z5#&IB161otkc&oIf8*OiQ|n6MXpO1rK$9N%7wf@2L^hf$es@+%4I0j=E~~i4kbE_O zKla_Wbs|J1?pB0k!KkA4s4TLf6Y5G)e;aJ)EET1H=e>=j?icand|}R?Zq8tT=xHv@CBvZ&nBZQLM~8O+TzV^q0>Y)p0eu zeg_=zcwAkyEXvm<4BcIbpl6$KIh4n_wP;Ih&U<*>IY>^mERIrHbyydYrt>P*y+!*z zx9$Y$fdzuoCDqFddSo<5m;rNb;(b3Jv-5ynkiyJ~w(^A*&w2D85;60^ zW@yhU+H#g5@wxkdGZH-8%pNnjX-h(e#+-eVVE78}M;nILC(pNkJ_Z;RurspE_WETTbH3W0hN_4K<8#wJH(4YjIa9V%lh4gCkL_-HRtP zxQLpC#VTP^RV5p9l9HV3derX{NMgG(%4Z2QL`6JozL+T89O~D-1iGJcNrto<_Pi-c z7FC5g0KTZ|YxUD8=-5;yG$-hlsZ?EnzqTJs?%<6!QnIggMD3{*JlChuKfjVG>%)(S zSJ=sp4^^8{+r>>3wE75^TApEn{E){Bg+~Xy`|Yp-g4NR~=nzs3KW;2#Hcsq8)#Y^c zn?=2Or^nw|{n9tE&HJGUFg_u`b*i0zEjsOitd4v29e(zJD0RZFq&er(9W+ z|FM>GEUOJfZsAC%KL7nz;wMB3<>yranzCDx>DP=DbfRwLWStm7jgRRF`f_0NPra=1 zmtG?67vL+?X<%lkJil9HFR(4p`b-a{A!Rt0>%v0-)bV+o!o0X|W8b`M5w9xd#L*(a zU{wBv=7aWey0$fqjY?}>){$~N@H-saDOm&5p74NqU`RV|%G!iT5w(Rp7{N zMyuj)k@xSAN5tjSbL2id^4gqz6{J1lt*k$FVr=VcvAHbc3H3TzHb0p)w8m0sF*DQ_ z^Eui){h?9wc1N;nE-2WO)A8o#tWSwdMr(7rm%uIXE<#rst zE0m7VKUFebv+R?ruE#7p_}FW>WegIKE@!^Vrs$E?Z%Lro(8Uw+mUOTCeY>0GHYuwG z39tIrZ?NFxEFJuu%kx~vz1WtyhLR@D6z?|4s^+}Qq{`(IPt|8+@jp>(M}pi@qjgYW zOGP)jE**8r?_KWwk4re-T_le*9z8IKxwXu2Ir?ysC~j<5xTK#;e`cPrZ;`!=+-Z^I zULSJZ58-g}jedg^WE&rVA*voe2lGBH)^KW`^H*Uzn_w`$E=8lp&RSh&n4L< zg;{V~s{XoScW{N%=f2K|l;Zr^SCed+6p&I}?Rx__CojYO(I$9W-lIhwW)GIKn`M!z z5)YUtNmR={#)RE`nnvU*Q?Snhj7DxYAhMl)E1Sek7jE*aNji+0WF_Ns#_qY{ z<*4+Q$N{#fuscWzL3FWbsm4uSi|Fsvo|EaUc${Wm8JOwdD?Aick}YNuR6M-7n@t?a ziz!v!>c&Kc@5F5|D+}Ok8@q>FijsYk?chjaT-@6zy8!z*KHgh3JGv|PC@6dk*1bKN zk9nFJ+y-#=pX+*CU7swxd!D3X^fc%5TJcnQ@%I68l5Y;;Yvb$#5NWprG1TbSl-4Dw zxBC_?=*(~F{l>7|F61{j98`M5>}1!n^=2PG{eEEMsNP3sf1&4mZjSPXd~wOm(DLzJ zE>5ZHI*Vb?vHH!%2LW3Pf_^{`D*J2Zx#eXQ5p>TF>G^C+%lQXx>WGd##IJ8kW+w48 znF#Hp8=8jR>%>5H+opJTP2#ijqp0a3uO?mp9uw%hW0|u2p#7C!r5aLxp73UBnHJN2 za29>Y+#qW3_>FWleOooq_1;I{`^!%F09WacJQTX*pWBOm^5`l2!7t4d)8i> zr0SY%O_Aw6MlyOI?(koYBt9;ggUpRGfLfwjRICB(f|l($9X%BpUPA5dbJ;oat`&Fg zr!rR4$ymBh=F@R82?OZV1Z{r?kbm%TA8)#E81(<#47^pL_9L}?EkCk^k($4kU8ts z#LVz$)h6r-ok!h1opSbVF#0Y8>mA(B{r>h4LveH~$k$5*85#Bx?S^U(%Y4R-sXOok z6P@Gy8zW);GYJpt`KvBJ5-`EXb3P}xekHIH4X};>HSg`eqboZ?X-v+=%y@%4up{+& zqHGUmO!kv#C^~LjHkKnSTDZm`K;?s2L^VvNO z!qSh!g0Z)Uz|NE6!u^$rRJq00M>+9~^yo#$@Dy+LaAKU;{eHcfac&uO_iZ8A4H>XZ zH4)fG+?4Sp9*695vN44WH_*sFm=$%{*BUv*zX$Ww8U~ks&FGmi0wD9grk$VsRCVO% z7VL4#`W2uqnxylq*C1?)l3jPSZFC5@F;(DPKH-?p!PVy(GVwG1Jae?D(+gLLU-o;I zpo+9WkVc-Br>>3>Uc&tiAgw38F+V44avx7=n^{-u6lB{Nl7&~M@~PIJZ6WmCq-M!i zMg}_ZLV%7b=jPy^wup9R{F2`wIVI(-6Sdr<<`2J#cFWCoo&*bh9SC5$Q+F~UahCdl z>C^SmsX9a2NWvkK$*iWiik4%H$Syf$a$R0L9Gu_`dyCZ~@EiftczM{<6y%C8PeRPE zF+*3EjCmA{8q3|GDGbbx>AgVi*dOW{=M)1hAo5)ZH_;B#n6#petOs!P$VAu5vU0Vlsf~Z9l^p|iHGU>eZu<&}L^rW{wXu-{6KcZX9Q^PFr z{(I%RngiEwDNX`AiiXq^gEv?cl6`JqF4DmIwIZBoV8OiPa=Ym;WKG~p=lh5JKC#&! zs>SKDSe|qi#s3J7!!pG0yFx9jFj${D1Zey9N|w;o=?}$@xwF(Cx=2iaa=!0L55C@z zAQ>eLxE2Lil^YIz6-?oOS|f6?e8>W6BZ8tk|5(0%t>wS^ssR6%fr44tHkwg5g)GCL;|B&aE?13*5Ie1dvgbCF+p3?_=m*L zR&w*DztayWgFs}zt`O`>@M?5B&TaCTn`jI-E)4RH-#rv1BRoEg9;_${?mmykhCyZf z2R&6yG04f+(JP_561;$CZ+{Sijg1?n$`=1Uz*_+Ca92KqbWyq%s^;%7JR6VA@#;y1 z8v*uieIaUc{V{bAo3#s`OIB(CXozfl_L3u;dEV`%*57-zl!p@AVs3-s$>9D^LXefk zrW=|@e@OD5Ff%yoTP(jD{p^NWI!c>ktao9?w}ssPy^PlB0c?#l1z<5XRL5HnQ6v!O zn)`diprlG+=1c0R3c$kY%+1rk?&o!LWGLa#JIoV=XVYG5Go14W(YM1^!O9|vIm_u5 zV6gby#(`9MM&KobuGD_4wjy{Ppj(4FfUuU8;;gL*7VVzP)Y5|Fm<}^-voQ2!Alyud3 zeas`&+2Tdo64G-ZbHg;^Hs@}ikyK!$&+Cat;M$KFP51$@O)^VU`(XXPDx|fnsG>lG zHSUJ#HEAy97Zlpl6W&ZL-a)v^bH56NJMP=Ns*8Ftu`V%vbtvru~t_$y_L4!zAkz0yx(xgsP+uZ1FEk7UcnLWUX+1 zt7%CzqF|02C>~cnk0eH+Co3_mu{(hX?-p2T!uBar=F#*W6$qJ+&c402e%!YTJ?k=@ zg8QRKH)>l%TvpucH*VU5#yRZJ3f9|WSqujlLVgbq;mmvR*Z1Z$olO-=J1AO6f9sT# zMGe&-Ta~V8kvtorXNd+4%A~iCa@F}gUeXiGw~JfR$k1Ypa4PYC!}?UDtDu(sskEka zsVnH4;ru+s7L<5e?4~}#l-{lsi7hSsL4Lt++B+TB8;0)=@26^ZPqj!%e46v8jY{*d z^0-d~$Cr{axg=gLaozLO!s13YH@fy5c^(hTJW^$O0B=h*{A$pZu{Wy(?-W!uOuvGgld~7x5)UBs{ z80Lse3Zt5ybBa7voq7tYZY+Q!ydbN7cKdLdF!}H1U%!aN^cdLk604n@I1|PP$0`vv zS3pn%n-i=({aGBGeIb9-?dAyTJ)Ar08I`)qoHTRW=~eQqr`xK{xcEV4pU-ta+I)D> z?^&*Oo8;crwKZjvvZZ>bB3$@V=L3D7!AS~Hfj4q{4bz2Wk-VHg2r4LqH=;7Nvb(%D z_znFhH9-@fRdK6kCD|xbK@pExryr_50qgH2Z z)34!fAPq43SL^pca(H_KFPz`b-*9O_g@IQNU!z%x5Vk-RxZ8%V($Wh4O#IqG0`)+W z@o=XLW7tly08i-N_Lawjq$qa=ibwZU%=hBdzf$F*ig|GSEgH^rV~lOk*mhD0fSR z^n*w2gr%p|BBcz@hkGz636W6lbxUoV({TE}wSmNqtb1}4l!hY5e$JST(eo$A%l^|C zZV`@IJl~w<;4BQ+Qm{Ec<$X4S9aa900Gdn50(&x`xc=F?r-D<*>(n12G_?&_t1}Y!?;wYJM3I}7KnX(*)LQdN+ z&#AaA$+&+JP;U6#_q$FNwJsXk_;p4zB`5yC-ck4QkuKO_b5$QUzE#*MF1CO{8Y zgKrMy;?VF4o`6e`<#k4<=8%WIVMfq}R76H*%A|9;3qz{yXVgcLPoyO=_f12@l)FoR zSH$+T-ECW`sb!QeBJy7Eo^AptlllyFEX`E02%XAcidfK{1 z%fD{(eR>jB&4QSx?+4!jLaUfR)jrBK(Y!{jND`$SEg}14Yb^dd$TrOZJLn3Hs4Mon z^Ye;+$&1wxI0?jRC)~@2y%&;bZh6@r7@yZ{zmc@IgMWVvajTS8$WX z&@SdqFCDkC&I#9DPY_K%Ogn`|bF&(J*2j}Z1{EA!0rc%p3q%K2?tk|Cfg8kWPH&!Cw*bX!mqAi-$}I0A zLRIpjP94Z|xvs>DX2t4egzulz1TBL08^VzVYn>k^z3aZNN0ekm86*vV<>$J1xJsjdU1V+bs>|-QsPH;SjXWs1B;dP=4XDP>73t~zXmzjG(?*7 zu|+WYT)jUw_WPqn=3Ic~4@vXRB&ZkiU?Ei~@A>$kP^ESbCz$kAI*pfv(7}k)t41m}<-RV`jkh zs6JwEB5;`EU&0Zkx|vI-dABN?Rl5iCLm|2a#davtbQv8!sI7jZLoCR4U zusHLdeK%-mtU{kEvFGu1&!_NRda`Y!ilo<`6lc}cV7t|a;xxbfrRnflQHgVAX)=2P z)jfQ=#IOz%sdMS^nn1t2R43Ex85sdt?*0#RVq>B)q~I+XK4ov&7aZrOC#o!^vZ5NW z+q@jdB&XqvfzbcL6aIa#G2tvPBq;~$$yWVCQcOyTg*lZI7|G@d7U5ENfr|9RQ}9bNd3e5DdxX|cC_1PI()mX8Yi zDa&C?&_FU}rN+Ch`e`}6aJ|}otCF1g@r9|=6BXqXXZFe_?fDi3uhBH`x-Ke>KP0Cb zJ%F^RYA`yinWAN`!m43fxxJWSOW3j}^`$?mj=@cDwP zhVm4)1X*S$*7}BUC^Z0k~l z_(6#c!JZj_zL<4(?aLO?t@nGEm-_t5!CNfr^;Z(YCZ5;UtLxMWTx}f$91^BG2y|U9 zH5IBT(#}!KV?TrUNDsprVWI>ymi_y=r>b{H6UcT7LOW9<@Zd5h$?M!lrTq|4QTp%K z))Z6qUw$umWhhOw>c+|h4Y#*S6rlPM;4*Hdtup*Ubn+`>^9ssrqC()McFoAAw*Nu? z|CcSYaoc5*82^+d$KwmUj~1Kj#l9k}6V4n>wE1r+PX5twto=L1@|?SJWBfC;A!N;> zBx@tR!zkgZO8#>)oGtCP4+7RVdtTytFH-Z6UFzGXcR^_%>!f)|bZAbUf}$N?mc+kIx!~EFJp(Fd`rQ`Pkw|t)>W9E(C;dLBEvts6QD;Vg-i~7 z-NMtwA8%hQqq-aK$=9Y>Dd0)%@u?rYpT2>u@PB_gB-AYLw&{7hSo4((caZTl9Gezl!d+I8D`U^K+|1nnHrT59W3mE=Onz0S2Leu)no( zYOvVub6M<&UStl57E%l^%Nt#-TX&SDvg308b=b$kapQUb--ZQf@m$8eaiPI3yf^N~ z=TBca^`Z=__}xROdUB(rB{!oC;LqB7mfe=yokvaMr;*6nBHFU8C<+Rv)Y0ob@oRFz_-K=)a zL?R>o-8Fd2NYEy*tqBRu z%%)t>nl@l#kgBbn=}fbwQI?9i(wAv%!|iUjyZL({;+}qi4Rn)B`LqBoEk5>XiLQ9k zByE=gv)}UcpBI&wHxqn6?YPJ9Q7bOk#je1fj}I%uf(G5{7X#_^7!;4&9UuJFWzaJuo@AMF|9F=hm>1|Qm$>w70juxR?)7Bu`;agL z#P*2{2gueL+s+OeNMr`nH1C!k)>CgCewY3-qox*^D`;@U>+q`z*3#XEmOM1=xUuKO zVzfVe&(!=Car_r?gUK|MG3iqjPswnt%kf}P!u`LjH@a3De5bosw}uQ{`3@V0+rDJ=4ma{|(HWZdJM1{D7Q{c%*T=;f(jB*4 zgwr6!p|iDpT&YLK3EVO2qS7Q;I;wKH?_N(1=2Mx>D=;fk{7|JL+C}m*^%px`(R_92 zDj&@M5`OUHiTP|M!mf_lmi{2`$?J2FXaBaMr;n3Mmb(-Y}Y?C~7kl znB5>rQqnG(&=nyLlCU>laELA#w+5Z*dsZvO&&Zq*S*P6cs+>VztH*ij0EGR63 zLSrd6fS)gSj`pnZwRCavWMhy@0t^QU(47^!pmj{@1I)0aVM}sE$eZV{@y-8P*#!AB z`yVZtX34Kl{UhL#@+^~B#67GX+a=yZS$1qC@h{`vq4G35YCCGOtISR{2SFDwU~4#q zHm+X}^PE(s3$5flT76}Gu?HQ)-N1c@hMcaqTi0E!5K4WqS3=E264b9260BkAhk8pW z1rH;ab}cnD8}nN-A0%6qn`Oq8bw}q5Y|PZM9Vl09o&L+(=C2=UiodcDM|oCBteP~` zCuqc4rPfWNomY;wznyq&zxrC=%}flEeC2k|_kw62iFvI^&U!Ou*U(LOMmuo#Z!BLk z=#f?beXx3)`$d@;kj&2JgXJlU@al+OEfAk)PaO1Fqk=J4K{BIaz}dC>uSAh!?j<&96o(QzvaUU*(|#U#aj`~UHH(v7n_v-ytA6X-t*RRp9(TS6BgU!`m3;e z1Ipm!k`dOuA2}YrFN9o_IWBIo3oEE)2H?^@cXXK7dZwf=e$O!rII>xbbuzSlJTRUY zhcB$Fanh3H zS~kAdg{rGYo0BHoSDV7vz@|kwI;x&zEas-U)NxDhYq@BB%|l?F=R9i%9G_S(F9VnF9M)uY8UWM(Z-(b{ykB#AGh8OG;KEpZ+y*$rd>2W^YY=BeNL!Rr2eU%V5_i7 z^As=7TBt5+OA1(GA1z6{Q8l?HFAq}71u8(jChUHn^VHVVrTICaYe4$Dzcoz?Nf9`zw6YJM=S%K<5nHC<|w_mViFD+bPmLVo9 zpl0EC-36I|8XQ9C{f@@c!N&lM9bxx%CmmNXD_s!iPW(APudbED`ke*O%m=T%SR`Z6 zH$bh*-r}l$AhsstvWC;F0AtksLOL5eeI4Ek^{b?hkL>~GN9#~M&{fu-{Z2m0jvm}! zglP;Sl7=6|Ild7$Hne)_)JKv{9!MDkkzyMwK$e%o&tx~p=O-`y_V4(a8%&>e>@AI# z?DP7b)FIfxcl%|+85F-QAwK$lwGJZhnN*DG>7`TGihP8VSaxYEg0I6-4W*w_w_We0 zD2K29dNgZlE$aAoT+mzo!CTYaI&nFMedDDalrJKZ=&~XBIE}H(#hOaPW{gyrt%TYr z-caY=)q7xv+Z@Fqvc!Okkvd}V;TftC9lY1#OIU$F)qpwth6=mAb!Cz7TWBeXW>jcB zs0XgKgRL8I>nNd6rq^&r(WdeasHb76Sf}QfT=qby}rHG)MG zIrO5iFc2v{oaH4nTViiVbM$!8_Ht8mzfiG*7R-Iuzzf{axoX zb*rvgrku)3tB0*!K1lT(F_petBPFa~4dp)E>qW|9_V; zEpPYnm0x?^hKbiPr{j9-j*tY%M|i$__00$E>hvX%EA;r`ACb-b$qnP6@ovaTN$h=> zwd)qo>~4NgWsT6i-^v}E_}bpH^YuG;R0EsAR&ZrtZF9Uw9PpawC~p$#C8GtePg9h* zF6S>@{vO6pH{WZ0P?_|dVOw$Xd2+f(xq}V{SM2|_BmLXA@c-CL%@{v?7#jGJos#n9 zR!LUeP}e(>YncaFJ;&D>tS(o(cuC`TX5v}vQ*sxAE8#NHEVI2R;ofD_T{cFLV#*?; zStP%sGac3BRLLA(2%XWg*yWeDbR58d(OVo^+jnFPJCX~&?x`8sGu2JbJ2qk=jTcmYVbuRqNvxQ@~3Q29lP?`~^=d z9|ahky>)HJ60?k^$2O6%)w{a40ivGEPoA{8@4*81g8zT0NdEhsm>wXy2VIg!lf%;@ zDj8WY@LxpB<|rEWxQbYVIYi{oJfg9y+&a37K2;KB-Cn?%%KL|8i>a3VqFH*=Z+Y2= z`j`v~yzkOs@AHiP*g_?jj4&JtkgpVR?RJ=a_mq7vI)H2za6x57|AK(KgscV=7eey? zrZgG*&z2_2G0JCu(FC4+4>th0%ZK6L5lew_pJo3(0Y_&?{rPRocvo zf-V37P8VVUK&>;%!T?01#HK=5!# zmj+E5dIb>e7LO^bVn3jnxgUHXIJ7kGV*CzbHFWP9M%6hG@T+uYK>ld9LhGMpnj(b# zAa_+u3|3R)9^}2tl-j-;|Afa;(%NRl>%gtL5lZd4e=5J8J2GkGP$O;{IZkanHCY!z zUNUZDBUti0Ny~Gy-x`r4+v!U`s{Ot|$?`UlPN7pwN~iVHStswE*O;BW=7viCf}Mp$ zotXLVVYpKH>Mn%pV<_ppk!!JP^dyt4LLLC-b~(^_@ooe9mG{z8S#DXUO_8&^xmER{ zL>;3X^a}xv97?A!ym5=%QA`FxDnAhF{YXts=h2tEkW7dCP2o2`=o*)W*CRqn#U~!~ zBa5d#^kgHN-gioBY6Surg!k{=8*@pDt>S-SVy$TMdPDWmDrSUHY#v^cvfV&f%q~vhEpogx7-QUU zPu+-3(IN`|m|fDh>kE%s(ELjcPj z=&8NMz|I{4b`*y$Y&%7@S)mPB!4-J)|H*6qA4M#+3P1}`DUUz*S&NdDE?eGYKNfKH z&a|+XhS_iOiLrLHd(fGD&dEuV4x9hZ@3Q#G>QI%#SXnOq-=xF2A( zGs^?O&W-bBg~rRSIu$X_zk7a$#b6D4-%>X*?uq`!|B1DbMKy7-O~8;fn&btn(jh->WmWg0k6 zL@s8tZ;;tJ%`~k4Tjtpqt98aGb`DdpqT?##yW_AFm}^Qxw7+&y#i!qBTHcsHzUCGn zyQpfK6eU2|TpV1jwR;W_?N!z@uaN&Ri=k`Alx84Rr>kq<6L7YW1GapjQnc#6-F9(q z`r7B{gu{M1`H4ZTcj+C6duiTVjtu}U7LU@E?+O& zLU*MDdzRP9iaA`cGKlo;hs2SO^A9Kqlxh}3Eq!aZIz^4aVXrzsn&G8FxvO+dOffqU z-$eyq>d#=z;Z(g{d|u4H!g?pWrLIwD1{>2?cxDbHNNa1Zs?5!s-;e%j%Y(0yhZjAq zR8yUms9@Tp^Hd;@L{o^QZ7WbDq)O(6W z^)0x$N{@Hv#BD(AEhv=!rabdYEFCB*3Hr8Hm2 znpTbazrL^0I&uIstaEYp%TDoAwpe0(NIi`GP`k3e>fBp1Aa)}64*bx7>_R^WGF6>R z_=<`1P__0+OV?F|%raW3Q~%-T=mmvy1uWN!LZpbnVMNW5C;3^B!kI zdI^HBVRPWb;P1(uTYFr8NJ4;GutTED&heH>J$9h}g2>G*=F@j;GF8WftJc(C6~ zhSOV-TTp8cxAO*1Y2r9lE-M)_mo@d5>KCjF9oM6?%N@EFi2gt+`4<3)*abc)r^pd3p7FRv7+0Mjy~D8%EYWBq~by z;zbNvKjEvvRpR!7U;cRS`7LO1#qyxva$_twhTsUe=TPtO7qU9A1G_(5YAIX_DaIw| zu@F6v+LF}KJdb+KrH)`1CUbvCLet5SAzKz_3;JDiNUJ|2smV71YuU|rYhc6ZHAP0- zp5I_8e#Mha)F}nE)XAxOV$3_p48~BZ{YN%ykbpB$=b!cl^0}FIKDbv7{^Oco6OyP( z9L9QG=CVHU1dJG$KBTx5D1!Dp58uX>^>8qkUYIcj*2odhVsoJWz*i;-XKH*ImMv7d zAoas6x@;@5`62#(emo(>;$uYSaaK(7{g5zk`V&cQe?^|thWz|q#S`c$MqdiHg};{6 zNA}*)nQ(pE&=Gs%Im2FCAL;paJqL171(K=wu>p_@?brI1RniHvM2#A(l}xB`5-C*Y z0#MF`qjwcyPa1g!l$E)|qlGwWkIGSH_pj|Ux8cTzTk`Z?ytS(NTBV_2KqLidT@+(V zirJK!b}iRoO__DAm0lEtBVlZ5-Gk4K?o~HfC_mqfXk0-EG-pb1uo{ghJd7Efow4J|MBDpf94T`WXyg>i$H{y8ynRd+m z(S$aD9#A`8E;g$T30XzBNqn0m5*~s#U~@Qju%*=d(bmS(H31Raf>!1+RtK=;Ik^}7 z1xwFltXZZ984>u-MR+YRGYj;Afhboyqp{WKr_HNUFU7gHiKcW}#ExUek_d%z*C3wQ zZ+#T@asrk0fx{SG=tUl}uvcW8sy`-*#iQ$p0on_*yDr)BcrgLUC$`8kC>{%XfJ96$ zHnGS)%Tt52R&6sZ0I1}}P?-;hy_0_a7z_rfehR1FGM?J&s=xhzQTN_aO}*>3Fo=R8 zf+DDZfC`9!fJl=X73m_qMnIa>1nE*EDxh>wKtKpe?>zwmL_~V;C4}A~p%Wm*yWD5& zJ9s7=PzyBDEk;Telt@oYJGv_lWP2X$`kjJjFbiR|UDry!Vcu|z(oyK&C z4hY0f?2`e_L`uk9f&LA0eAw#gDef+sdB#_r!x(N+#I%-0F{;*GV)A^Du5+}qGI~_8 zS=yp^SGc#B!}*u?wpueuwl3bguK{TD%6SKi-fQyCBm?7zQI<%R=r@5)q_1^Gm7U&W zw%)YVDU_S$T%w9`>7H*n-8O%~N;jpwHbq6%^CqEVy4>kWzo|0(;-&h~KA=Y#(5YO+ z^We5e@yxLGm4}M6l&7gB+(HnGjV2>XCOwoB1%9Y~61x={Uvmmp+z?vQ5ZqvHsoX7w z%&8LkO~qNNr!qk}oZx;q9f+=t8E%pVZ8D!;rJLgJv|N(n)fi8fVq7y|(6J#fZMS`< zhG{I{%AtY-$xVf&w!XdeU)U#I_e*mr@^pVrGkOR;%4pz7NS60%ny3Cv^&rBN2FmmX zEpj-XP$&y_vt<@mhP!Gir|T7V*b&c7#aWRRfD5WvDb!Lv4l<@WItu`!tfJ0i*}0F7IH}nvUvT8YMar&M5b5XZ(nU$4jSzcrBhoh4i{yV{YL`N^w=A3} zvB@ohP@q|XNVqSz?+`IJ^$-)jJ>UiyeZa#WP3>13WQEsh)IF}hSD2lbeIusnavK|0 zXELYagNdMi)gwO^RS9vO=KBvoKbz1$v~@=YfIg5AtjR>0IH0(CR-Wlug5CVtjii4X z)&AGp>HnrXnSjrZ&OG3bZqQcg$Qs72iNj(|pifJbUKMi53@6`%jS{|6Cd~q`-rAj# zILg=otq4`Yfm!P3io_0RrZ1su%DHUhTmZ1wR+wZWcy`6StiPB5j?$pf>oJ6w!|67K zM`WR-RnRCGFcSaIzuNz3HNk%W`+|4=4tBig%O!7~kU=wln?hLS!?K*jKLgQ`2?xO2 zK5`Z&j{SCs2`ffc>0Ty$X6q@od~ltAdp#upar?GwN77NYBMmu&*b0Xsu+s8CpeRY5 z_bzNOb`_-H9@JZ>NuXa=@b{^?p3MuN&~o)(Yc_ zCIfg)N!;ERJUKI2K?Z(catyKmu!2kBGB(nafJ`;I_30!(&+?#ZbD`5~TB+ zszjmPVnln^|6P}TM>@dU`5`~Ufan?kE~Ep|p1}k*7>mwiJ805!@-nG#bn?C?i=c%g z&qunEMK5LUjmnF3_1L>Ch9783?%a|Od+K1?Kvk-~-m_AcZhVT(bh(VL2D7@|)^ZdYrG~$=daM{QQ_SSM{8e zM6ESsa!VspZI=-M9A$@=()V`{(1)0%@4yxf5Ly{^7tQ>g@vO(EhT;hJrP)RM&->y2mIxROD z2txYDmF}oqrYIU`tO$|X6tB-m2;i@K`SXzsCcl)m;<&my zCQmfy#fIr;hLZ1#v!YL?J6{qo33}f-H~{?OR0wz#afKMc-C{iLsIXh9Pe8Wupd%gt zzrcI#OTQUWm{k-=j?%3}6{9R5aE#0Y*%GjRr^N_vRU&h`|5=K$a$cZScSpVzY zJ`sWzHnluxJjv04P!v0t2+d#N#0NP2&Bw5xek^9>j)t_i>GBw$Te_A5bl9%z_WLJN z?779Hm)}Qng}jT zSV>0DCFx7=jsS@CcxQKmzpxKW{GJNjtNC$zh(n8*W8OjG$2W zr;On-n}ON#AXk@k_*Rb|tnJJG^(93;QcQQEjL6<*XPVD&u9xxmRC1u0tiM3&*V>Bt zMrpBW?&BI*M}I-z#Fmo_)s=KC?wt0qj}qmg-=jr;?TX#GP~$QrLdkfYSlpHT$&do* z5(Q}{Tu`GsphHY?b6|z^@d>lpE=<5=X!Y2}H5}gT3gB3{pSo63*Kqav{p0X>-`fE> zj{z7{x|C;yJFhLbgy#i01A}U!s=5=VPXt&a=@oT>b?MXrtqRaQPa6>>RVyk{uoE$e zKA#piGF#}$(HX^V*t;TY3Ckg7Q4$b-972cn%$ub%5^0Ozs_-Dw5n)GT4F?u=2e2@r zHEdq>k6BCK0XGhaeg!s$gO~%*7EsjzK+DJVn7jWsRlOUaVJL;QxB`{3!d9uD*Onjf zyFbVNvzyj`y^u}=XXQ|oGXCn?uK2m&LKZBWGwx}RKQ(92T*kN0pU9`ZZUgZaoBAEh zN7olRca16hKR~zR41k%=VXG~>(oug9K7b{k+~T)@i=I}e+tVGzf*~K(+Ce%Gep7Mh z9$b&xQaG92dJF-ra&Ps{&yi{_#d_1bHhJs!b_GC_ z+H-~yPPycehA=3(VG-5;Gsqm7Pq}DJkyX{ZGD3JuNPT(7rQzq)oyKQf0EbWzj-^6{ z9UBFx_hfy4M~#yD72_TijFmih-S#(?S_R9&$!C~mj8$r>-7(iJH{0i0%{_UoeW{S(OFTYTT4Ct6&Dub?}}XQZsU#PZr5$w18|~cM{b2< zyy|2_Q{`?5)FwjaLzfMo+Yx(SJc8Brpr;`e-|!9_d)cn>2k^R&0M(A*f1Iq-y`p5V zeQbN|W2o994SDn1pL2EQE~Q`M4e;i+$G_Ly3&%(2${{?fRaPQ&l zmlwz{OmneJi^B@)9F{ZU6ADcU(9*3Upw>hSW8V;;`h`7ITsV5P+w7bbZ(9fQGiYNy z=n2V;kvvPYx0I2nqgpmHgM5yAc`hjldX~#UGG=Kwt~zioFmamAXlP2I;rTXm?FUL5 zO@_G4sCgXXyvY1GM;Cpknq51tzKUJ#WGY4P`^*NB@%bjPI$Z>T`p~zZX+?RKrG-lM zHTI#x1$0@xV%paJgF5S!pT_H_8ng+EojB%4txW=&y{DZ~FuQL0fEO`H?zz>6krm6g z8A0D40XBAit!yUdYF6Y&r(sC017I%UMl?@}EbB zhCFTl`*rQl4H+gG84J8?A9#5$nY~*D%n6#(vE3PA)-%?9W)lyD;63HD3st&al$GC@ z$g_tVf0;h%fQMw;rrj^f3e|shBl=q2n&eVK&Vr*t6gkUdLZj;S6s;;NZDj6g0~)1e zI_+bwrkPsnXZrro^+V@GNx29y0crW^1MdcML6YaxN@-Lrz^S-I!dCDR5MTSm&4*V4 z(011-k(XkQ30cF**CT%=SIEe8oFs2-@ByXpQWXy7$WVc75r(5(6Qqbpn9t8F$t*C47qGF5mtnad`%tmv zd4vZmT+ZEVYPFaFT%1|0NZt>x#ye>#gh~u~aU+Wr^=*7+_?&{X2j*xoh(P5e`&~vuE&Jdt zOR77FZd{Ro@9C_FM}TotA_1vNKz%i+s>C5$pDUpfKIYF?L{hxC^PB1(7?h*}K%k$w zew4C@*pMAfKb;}e>*aQrhK+Y!gN4PUbk@$Hg>-$ktAZTHWg%PGP?8fF+jFm+OHZW> zXq*UB7())xzNxH((uyVt9DPsT#H}=qz?uhIfqiH@t8Zzm);5&0kIBvDoNbwRmy1lr zepxL^-SBN;kvR=nhg;i z;7bF|<1@XmV~4G^o9{SxGp*;GauMO?Q_1G#QaROe=U?=&cUY1}!Gkx;cGR#qd*|#}Tp*hzIZn}=J>|~WANo>3fxnyKr zMd90$jM6>@3mMyxUvX-k3*F32I8HiWeCoP+Zw%MmhH%&yW=rrGPX78H$Mj0?u*D0l z-&7YiOIEBVM5(WWm8%jccL10xYy1sRCw$$itU!$QU_P_VGB3XXy{vTViL|La8^O9R{?wWiwNS!L^A5)?N3?K6jIZ%gVaa+#wyQG^9#(F^DOE9S}4gs%+ zH(p%~Ov z1rJyaWfCpEm%Zo#Wvc06amnK$UmLt3c=b%ZHgoQ^wkJMh!ajl1EB2to@1N`aXavT+ zmrL@4T&THf+J}#%y~tNuwB%m(`6lFe*dAHQnKQIOFt2D$*eT(OA>)84tR$c=k%DGg zFG1~Q&g+=s2$#o(nnD&!N%qC{hXJyBLT*1Ppn0aou!B8pKQ8j&CD(&8K-+i%s|Qxp zwT(ZE^q-Zt;a}1|S^oa_8b|)^&$omCeG4FeHSiDr7B|uEr9ui~BK8rXfE>qDE9miN zb3@$>4EN-Ny3{P-nQV8%?)2@)xg0t*Ys$bd+8LjyF_M8l-?9RV(Ad-fd1JUz9e0&1 zrj$j|Qabh&Kiv3&E|4d7)OYt9332vL+aI^a=O+ZU#^}N0HVki_<-Pcb_7~S#p7pbo z#^ZxA*rU^@7-b0!UX6cQVimaueWDO|6*j$$<_5vH6)sSa)oyO9C9B@)m5`S}5mjh; zAla*W(sKqx(tvx_9RZKJDk--RqPlMfpo$-|`b5ov-2a0+|NqiQM%m^xKHScYwUC*Q zzsfzr_c#(XUg+<4E`9nnln0d05z6h960|-mC4du3?if+8&bKX}NS|a?CB~jYWHBRpl z#U_((Fz`aHTs?lQ84ro7bi=5Gu^gb@l~oSnaCIL3i3k_(0nFZ#^|#W9OCn3{gX)0e zM7`czKEIeS#7?m1a)tQ<3^@^!kvQ#}^`)AbZ}h~#aEiX9m@4#6U6z&JhhLWl)8I+V z(?Qt_b#JfD4;dv?mE`aWu4kSZ_E&2B(ySwwC%N9^mcXVRZO*^z<8+X4)!H*1Z;`WB zatH*#nK^RvmHTX&Y>~K)51$F084r~$;2S@{-p$SASHs|2 za3r!X(3^33vSQ)nGF@zpYiJve5`#IKv`Xo+<0*&^M@s5Mus)f85QjHYVqB`VaBm&X zXT=CA<+VfR5g)&DB(kGYmLgs|qmj7yD0x{^_qVt9J@xjOqL z7dfrd^cUN4g-Y$SLd*pM^>kF{s7y}<-+I$Y^G1Y4a{LZ@W$KrZ8L(^i<(cQl3gzS^ zEF2$f`K+gzjO~6Hk99>atL}(ibTm@iA%Ba;8ftvZsumf}&Fgu_YfD}4=jaR63Ni#I z!m2{u@{y{VOJ1Py*Vo`GOnr=I*0G|{_ zqF;FnX?7W;3A$MKkDiE%W-cQ-KBuObuzk# z(maLoFZH{0q7AA+buIez?G2_TRR9%>3!_c0qUhM1)jGava^pjfb$*5aOxa?51#7#} zQz|V69&66vyXlkeS|QafloQcRWCaF+&NumTMKhv*TB0u>{M5}mjb1_dwdd=`g}rRj z;USnI@&0oQyj;>yRl(zih78(kIzl4(yf;7BO3-O9J4&hUu^#t~lgCVl{4dX`^mO4x zP-~Rv>4qJow5aQEDmNc#3)g4eEs`oLlSk`*U%6nM$uX{@Lr?ofr;6hB9bP(Dw_ERF zrqwVAgK5#@URz`>;1xJB$i&JQedW7MCXYy&vX+2Z^n0W9*}amv2E{()uIK&d7&DBz zXEEsgfcpKBVMCL9Mi(Bc@i_$aaF<#3c4hExh^Ck$>!m~vF&L#e`0Kek?fXX)+qF|k z){97y-&Eb3ce%h0y4eus4+Xb>YMM*1GF^|;J=JV_+FuJ)$+5L1@@%r$^_ze3d~=Wg%h14O9=yE&^hVUhg*fNNVp>e=wAR6tr1%)asM7JzTEl>9? zmV*=1*=`l)eY{n`%=6$9>Xf5G_KGML>0ey@Re$mcf&Q^Z$hcYOj>ZPtO{`&TN}eQ( zqIHfgvAm&j~MqawE2+$MqaMjD16E?e*8*eP-wWaOl>HB^zZ^|i9FwF zUU5FH&M@VWH~via(|m#N_o+V>g)`mvV>8<#N-p|;1*}W8E_^O!!I_;+7c(~IKc8j$ zDLTQQyYghFQs8#!MlrFHFv9xa!>}PlxaDJC6IH75`@Y*EC0WXg{hsU9KsUK@lE7L1 z%Rl6Ozszo&DQw|~XF;0>2FZILLfGzo_c3Y&y^ytEe;ASd*JChdi7+v(P9IQr(DIji z4)=~Z(TG{(04<&4?9PaW3}_e50CdZ%FK?Y~7(t!%2F{EJh*hY7CRM^=3l9%4Om(A! zQZd#t^!EjLceG`WkH*Ah;e@y7q$inEzM~KSAr}4bckOGSa1-&GAQdl0c@Z?@_V*r> z^W%^_CuufkSQP`%Q~x>L+Bh{C=qm5tEpY@j(mwvhfZkitK~M90k$W~{YNb>1OChg8 zoB4^8aCp=+MA4+1=`GSLbj$&oYp=9~!&9RF&RO&r1t?Z7xdH`%%>UXW`6o-~f3x%0 zKQJeMMY&T{4e4))boKN!OOm=4I{$gY{*$-*|7xe>U%0U6 z3QNi)(SWVHkYbXYH&l?5hX``~Qk084a@--F=o}s%;R7N%{9~QSDkJv7upvw<&{^7; z@55qC3H)^yOD>a+`>B+1fSYm8+$Q zNMfZwo(_{*7vomK!OCfHv`MQdKjL*=B0^_(%t%Q-f4A0=D$^>xHKZ+v>ls&<;~a`(F=ywr|e9fS~b8M>hI-JINvix)51avX~e-@MR3Ys?K8s+cEE+-01UAj-KK zd6v)wEp+eicSt_y>ZA_kk4pQQs@445^)mj|CMtlK)Gtqw(76WJe4WqAxsDfMm;NRp zOM8y?4H$)K0W%PI#e zMWLC~DkE_W6fp#$Gw9pVarlY@Co+Ci*%| z%w!#$vOHCpnr@Fu*#VKpDso`3z?hwz=jg!4TgJ-i{Tkdq?QTVuYh8R^u5*sgqj=BN zy~zso9k1zew!?6ND_s7F-IK7g%MpB_g z)%i>F2RB=1?%2F~Enl+RZCieg{o0#Tf-a1*C4v%`-#-ZBpD(%H-(CJ$+1_`5;wM{b zL|N1$8_JirGqPiOF)1l@%L+TVZzi+OwHn{IADVyAU3DHA9}umbHffn;3cKl_+)ue6NTHonsQrRF-15?@%#BwXaRLWPWAcd zH&ZR0&oMn*45{f&5Etu7>9aqT1nXhCA~95XvS!6OxrlecPU(d_-utDUly66%ouPT? z+)?0^7dAL#qn_V0z#cD>vq2i2pGgziv#4BTTu738vsru)(JMt`h0{nc&&%|UdQO{O z(|t|zW-jfy+he{{nyCD8j5{P1wZkI!ez@<6P+^A2 zG)n^YGd0&_7oTK>swD_INeb-TXzpy}Xz%rL8R=+WaIM3Q*F`V5Dt|#K{S>1qdSafy zlOlQ?;agj^%$=_sefmDH@p%>r81o0+AFnjl-J1KCgQZ{6`7O%IAx6V+zK z1M5V4o<-(6!v}O)u61c}cjOZfhzA4`w9j9s&UNP@QAi?6Tj^(-S^B{wI9F(z{7uT) z4KmTldnmdWcC@x57vME5#}#`BT`D>n2yU`LNO{oI7L1m1YL`oO&MwG2_k1O6t}K6l zHJJu$y&+dEZsD zr5+I@fL*%aODnnnrf^0%&Ug4-v_j}om1)ENqE_ssIUK_Kavh_k}(^p{KUrU0I9{$$Uo=h+8o{NCtO?Rv&g}ChI zec2_dAtD^^Z(sy*NmPkPb9^o?$rDq*7n+@W*;)IW7*j2{hq6@vC1-^ddw5b+et$#Y z>Ia<3>a0%QsSE>sEhfD-1V%Y=rt)ZD*B`?1(I8x>NwU*MnXK{cMn3Oif8t1txE*C7 zI_s}D>|$ZXM|k~u|CKsvnHOs*IAMbMv*xwKc>MFEiICq^j%GS@5eE}eqhAbO&n4^etHj=d^rN5ea~PnskAyP-A2{#uoc8$dIVBG5l{r`~ozg0+AY0VZhlH`Vb6i0CZmp?G=g6OKNo zx!w4#oX+FxU<1hdhf;EGbQqgP8;O@|=lnDoxq95?#_n0 z4c}K+{(lAr{}Pmzawl>#`uP;*x%(I1oNjn$I1`v&75J&V&Xsd#!F>^7g#S&Y?jO78 z#sQ+n3_t}n=%!4jMARA{D@Pa87SQJEF3S7F;FtQqtz;Y=c}cYbOj)R&C>CC-k#^u! zf;h$1$GB#s-Q9^j=hZa)O7>WSIO9&+*VRb&pR}8{=UD0!$4iSnL`2(op&AoymEk7r z3B0V|FX`q~uNJ4*9Gma(luMN;iH@Yj4P#SNT3;@V^SimQrMelADI(7ep_aBoi(<*= zXcw9v#W4?#>4?tEuSa_P+|kHuzH!-O3F?9=v5xRW)?swVS_bY6-WfT6Q%~+%F@3e+ zXu%^rRTBi!QeroK#c2>y35JRk&pAiFb*j@;Ee_(lpwp$Il1a-zy|za^sqhq~>3pEt z!I+EdupU2F=+afML8#i=NQtcfT=EHdCU-Nbb5Y8Iw81$N+4Hh6R5k`r!N1Nf%FPa8 zof|4ng}Y!I3syXru%iQJUXd(`mv7yR{$`+lz1>jRq$KunqK!(itS;?R_0biKu^7Y{ z`ohPlMKJT!qPUn!_`{YrIwL}c^fbakgSpE|?NP~7oZsr#Phi3|yAAgBdl>%ef&%GQ z`czibPT&ByrS)Nq!-`u1OJ)1;xp6j^r@nX5?~7#U+w+q@lM}=RgEW_jJ-IHG=93SG zUWLls;NrN}Ws{lbrg~%^KZ^1z| zLqa!HNODbKFJM22E$I4#HLXvHQnSNjuXZo(KFK`-7v&HuOr54>!pUJyU_qKy3k`sq zOtWa~n_fAVjz5;!fz82NdI!RCkW4NI1b-hc^2{(snyz7Q8$!u#TIe0ZJgA4x8f9c= zW5FdT+`8b!7Tq;v^;5ojYND}+L1qz&$Em5csV*n&!uAMcI1f*2cCIzAd%Kec|0@=r zk2%zrlN9g)J)-yAR|I!km+vmshR!?MUCN5S!cyc=aCA!bjC!8@8Aly8u04tay4%tY zLSI{fwIAY8@+BD^l@2vv_UIfBEx2Djs`F9#O|_Z+tHWhoAp~&~imi z#ZsW?gl4f-DKPQ1!^I#0bCx1-)FvXeWJRIj-OqO2TcJ03)J}%0-YD42-xKuczxs+G z1TPY{v$1)Z1UAB6XgPTr%{grvAo*kv5X|UlTrx{x@RSFZUOC_Lz}!8W7d->}6Avh$ z5t3)dMmW2|*AEZ(t1JWCOC^4{>1Rs`b`h3nQ z0XvB7zGut-(k~AG}~LAtUYkPPq^erUZt?Sylw=QV+!q& z{o_aS=9B{{A?*uePwYl6JbgBD2~d-A-Z1_qUZ4m9%$uY8 zHWl)BOY`#ToFyj|s?pNLBE2&Y8h=hnN*?!4mSpCYV%yGDRe}?9nW8qQ3>DSaXIi4d zc%Iy5ep4_TPagZCfW>$d8;!6QIH?Uao}F6`v1i^~ysTe9d#{|`eTn^Z$7xTL%eX?$ zlq;?l?i4+OG^P3bH{HN%~=3UvA~et2YR(sv)wlLO1HnNJVW zv#?%A&+!~~jGLIWsIgR4zA|LfwD#wTR8{de@$Wcq;qzz~d6{b+Z?Pv|ld+-3Z;6Aq z5>e9|onU8tS)q{n{uWCwUrh55Z}@=%oQfy7MfKFyLDo{oAvi6`c^TIsm9J6Jb|4@j z_GNMOsawT>Kjr=f=j97dZnC+#ip~c~FZP4z6n1;j=#v;WEle_WaSF3gR5t{L1`xH# zlez0rg)wkv{bDEWN5W7Q-wmtnu;|FUP2KI~@1?aCK1nN}{n8l?z?>7^=b>>u;@|a6 z)7m|r4p8ZvUBU6F=b<2zzI~7>Zxj3FPk~i;(n{FXtW{m#JbaVmW^DZve&MVnmB~Xu zj|1A&E~8ov9252b55dddTZW#^b(Olf;?i2_>n%?nFfiIk3b+pPwAic*WeHOTuh768 zOQC17)38GUVo!Qullh><)vlMA8SiPS;u5hL4-Xb4T-*rVk>9}l_X4N&@bJk{VTI>= z2HkDzgMB>eJls1ktpoS+u~|NGl-s=Us`SRt`A|8B@5m2&ygHeiRMexQUTgo2UjIL1 zg2E>hV-s%F=Ch6|zekkI)vw0Qz3H?G??m~$Q{g$K_z}P>z#mS2TQ!E-J97Z4M5qBS z4Lpgzsfx^BsLqUeZ~JP;N-0?4pDoDm|E5ZR{ltsZSa^I;7CIR|&_*dExdFT?;j@Cr z)o-$2sNT->!+rr2_WIwHwEwy$4*l=;k@`D>u99!A1_KsIKOiy=xV}~4sj8FAPccn^ zYW64wK#qF+dk-hMAmwAI!3Sg$^NvrLYKHHdFQ!c9VnecTIPEk`O$j1rB@idbdrat5 z*NCc3a7ASEs~zqN!(pLaTEW2Ly$yxNx%#&Ksj$%vLo*j{^E56o7eiEYRQdD%y=?qMY$3%NoD@bxve;@?!K z({KI>c?nt|vJhc?g9YgJe6)Qe;#TM53NcDAi*_*pWzjH)&y~Z~N|6JS^Tg-O{{Sad|9Bb0&V_^JT&9d_` z#egu*{leFMd5x!4#YFGRj8`v4 z6N=#T5p%XzC|*oV5?4q=mQGKhZYRPg8wXlD%NJ-Z=zcbakx-o_yF z#jtU^NcR9zyLS}K#8wWps4_m8Dj4D5Y1`l$Ih|@Qy}XDq?Lk-Nh2DP7qpQwR4c&_o zsW1W&?^~?E9bk0?v>7W9Vw-T?TS z!Wec$M!#Z}b4S2IGvu}jxy!aI$aozap~dc&@du>~ecHyl#!o-dLU`jLICHcD^osEn zqG9Wrtm`E_CaP!n*>wj1y_sH-EgPDX3K3)(8p=XGk3pE@aJ3jnECPFb%*xsImLtBV zCVpDjleY1W@Qpwv9r=K|mlGfs3Ka={%()v@a>(8KJZGfCi~l88+PVeehfkliOJD=W z(6V*Issp+(?!{@@D78E}{aH(`Y9H)fQV_$<%X&)PDNwKzw(d9@JU=z&%A8X zWeM>cuUI`>TdvlRL89pp0xpU)3b;24`sLlZK4;h z>sn$}8C>G-MxKhlmREYp_;fTYClqLsoO7QLTWFLeMQ_sPo`OtZu3bNEc*doNaR@V1 zU(R!>^VmZ}jgmQiJ#b|!z`|+?L*>SrDaO60+eW4twINRw1qi?UBKqYe_(MN;{7ukY zP&88?zVtXBsc5^ga z&5F56NWbG`0kW51H!U@4q~oL&pVlm{ES1`V)n9gRaA zl<(OuA;qFhjkG7RBu>yZjed4Au8|e5_@8?u)~(HR^eZkdE^c*0tKlua^*y+-AlhL;CMG z)6nTpC12`Y_@;>#aLg*vkXa1Rd|tMuJao6(t*z#3b!{oXX;;G!n`QHgb>UijEzK)) zPVMac<`3BzY(wszxi`X3Z3}ljPJ&WuEgn@qKj-W0UY$t#*}|oH{&OI6ChOfxwlsR- z+X9cCmOseQ+DWDu&vb#$S4gE_g?T4+ftF2c{HIfGp*PpSsX_q^bPjf91V}uVdP1U%78bs?8bFFI*HzF&9-Mfn0ujRAs zt%?@9)g7*2epObgOGCQ8Ff8*!ZtiPJJD1OvX47!ra9$c>YH{h2TG$eeG_Op|ZJi^C zfCFLT+9?W^6|btq1|dOZ(^%g(-J4TJ<3H4yTQn_WTFeA&ilXl%s^;Ag$#!+BO}~Pi zkV$p^m|Q%1Ar<;oMKazY+b%AxFc!?C-k#g{9dD9gKV9qL_3DZ@+;@sU@`33ddep%-v@6}R(Nds8NVX8OI3CEXdoD)O^oP$OQnv=tt(PxJ-qR3Hx+5B zr!s$SMHyB}B~raQeNkX^0(3!Y^BUJjO!b$(cyQN}HwK&FMMOFfXbDNw`U#zofM!*a zD4UikQtV3#`{v7g`eotv5xtwZA~IDA^i_=`0rNR2>E>jK^(h(Q1%^{~q$gp#p_1*z zv;w2L?g8f++gy1AT13`d1w=W2rKsCV3{pR&KK0d6PrWolQt>C5UiLq;(5pyN(^OOy zMZ{;?k-JUMD`=y2sA1D67ZjCBtpSW^6%r#;Fr>iu$M~()TIpmc^|uolmcWv1x;<#N ztBq7#1F;#0nC>!=YpIF^Wiq^d`I{=T)o&=)of-r_PyEq{LcC5#{qw3%FHmPQ^}+-; zu2v$3Ab{F=t>t|hxy^8YYz;lUM%e{s)rg(iFN!5xFb4;qs=7a@p4|yR^$i|0TWhG- zQ%misT%`mKmqb5U-;-s~%09ZQunsdY35fnixi?^C1VyjlhO=(xfmU?j5f{+e?fBQ> z{NFh3-~VR+wZB7po6qJOWe z6m$DfSH+^u2+eU&-uOg<@dby4qs9WM(0f50DYuCRUd4oZ?hQo4UydS~bNg?o2Cv1} z_yM}QAqo#>=h!nm=(K0kds%T?SYb{YXsq(rZ>oLO>dVXYq&DTl+etG{@LjH?pso|e z|GP64|ANxsKNph!b>XmmI+ltzo$Ayge3hO`z>pIxt@qb8k&ca~PWq zw$U6V;_Y0sK345biyq!jp}zK;$~rKmrGqq~!0^1X=H9`Huj3ydn1(S_me8PT^-*sJY5TS~5SQ98Hm~cGf zV)pT&$Sh-E?qzAN>vgXy)4)SmIz{OZ z(e~=zWj@1$@zMV^H1Eu-eKf`xlQXr&756k(vu(t@W2eyFr*ZITZ0~WQ?TR?Z*o&8l zU;b^cMW&h|&nmH|F%{v_@u>=k-Q$2L5q?QNjS)jtiN^*2$8XxanTrfq=m;8{*zJ>X z@!5XFwFDL6`Dn|l0xiiESItUOcBZfVMH{Qa7~d8P_v`bP;Q+j&U@~Fp4d@x++u<9K z*vSsXFB`WYhf?V*;p_CFwrO#9CJ z!>TA-l3FQ?u0}Oidyj5p|JuZLMNM7AVJi`i()^wlxojees@fbvYTr&3ZNKxL^a*TE zzAFuGU#eM#WnMYpV(7;_Y&Y%CLAocBORgDxf18tgHAn9DS~b`m+lq1It450iTK7KM zvGz|s2w}W-tDxcM`r~vLrglg(>B7-OncRwzz z+ic_Is&beVxYa-~tt42SN~NZi{FIxWukPkCJlJ*NiSteR6Lrt}gKku48|-@h0P7?k zED>Mj*81V_exJvgDz}f9A^;DAYxGavNIv4p-e~_?iQJNV-oHCFItU@wyS9o`Lnq!QARqga4xzZ{6 za8}#z*Yjr-W(;JFwLbe1BWt?G+f0osyw#>3SMPlNR5{&JF^va*GJ7bDquPFMoOSKv|fOX-qf1C;vm~ z50b^F*H#33tF1_HX*pxngXi<+<9 zso$!k%QOiB+|^R)F30ziAXFVP)FWS9;u^j1yTr}FPu2cHZ0R_Q^6xl@^>qZ7CTw&3 zo7q@KNoS18H62^MVOKcy3UO^13T zu3yOaZ~-=f_$ZxPi!-+|i7e0R+=+t zx%J}k%1-=agztP3kLLT3kDz?RS6QMbE7M%$*;1{U8baJ?;hB0}a#}We1z$-s&cS1k z!)C&xos%sZGj$%3l5(Ikl$Q!yWj>(38bmtH3%nC!+_Bd7#{5hhiA$d&K3fK|FtvwU zf7Ykf_xW3UgUU0rGhOmkLJT@&l<-$IQCv?hCMx`7ERKEMbWjspLD^kP2p-~WM4$d1 zr%d}sLA^9Vc6tF%OLp|_6L4l=;>?+|b9Ts98{T6YWmNKEf0y$)mzjyNVTijojC|W$ z+R1A~TW5i{9Rg36vzZ53UgyFmtouCc!UB^p*66{+$LUB`c0H+?7KlRuU{LL&9;I#& z>mZHT*&M)llaa5?N8Y=;xCV-3{Z#wN@%lz+FA)5^I~40Y1U9Z0s)1f5`a_%sZxc8p z&1}0`cQtZep0;`1dM!_8+|BAVBxOL^bdTwP|OEXoxhL{fH1zp2qtMZlx9DZ8)5!B0M-v)LN2R zbf~jRa<6N>a*GZf17@4Rd!MhTxazkWOronzV)*C*50s(%<-5#=~zctLu|}vCz~6y-qyS&Ycv0N%g4H&@741cfG=C zB?F(Z-ma$mK2rCa>N9sM4p&vzMcqHcCkM+dlp5{DrRDjk{FvsDc6&+W$)h~P3;4XG zOkyJN+u!L)DlfegWuJyfxEW+iCS-q6$$m0Ajq~73TVC>L++E6^)RbWQZnCHx>Tj?; z@0n?Ee?c!L%9Ps4i8E=k@p)}k8DgBU5#b)&n-c%TJCP$t^cLcblEE8gLG+aZ;hTp( zyDn`jyC@`?+k4~+-Ag=fW!q1@(j!%)APYxHI|_lPg5t(mYER6Y?j}d36FXZpO{(4X z^p!Lv7@}B$-+ydCPoKN>c8Cxxi@cQ5gsa0f39DvKt($_g2|D!sk;7DJ3nYZ1^}JlP#rB3m@c`$1?(s)& z)$Y3JGAsu{v~s7mI2&YQBSmKjsn1q1w(E*~=RTj^zO?R6{dB+4FgVflSH)d>lxWS= zH^u%`ktMG{YgN%^MXDW-RHllcol33Q$$A& zc;ggOTv)Gn8vj3Nd+(^G+J0>iL_twNq$vmyX(9rG0s=xnM4B||(z~?Kdx?Sq(jp*T zdheY8p-At&6PolEkd^=`&i47{Ju_#Wch)-d&78IPhrRX+H+%0S_f>w^<$9stqzGNg zH6AI|Y5oN@jQxMHMXsYJ=!^TAOG^BzVtnGsx4n2T%U;6h)<ty#r&b3xR2%G=_Z`qJci=0@rwjft$Asr8 z)WE^sFumDwtvWzh9a&5^)zn9Q7|HJ3-Gy?hPv<82SsKys#CGWPtd@0J@Hod+f=b-o z=mg(QzHuDM`Vfj4-YfQY;DhjT(k64?yXzwuLv_OJe*=~Br4Chx!j`7&RyPESs$J%U zF{^Iou%zHC#}EDsP-(=p)OfKZ^Mp_kuqUYPONFOxSh2U}Q9sVOu*M7Af7>DQObN#= zlYNA>)(rynm?7K&XDkNHpq{p(jYot2)8qMHUj2XMK;siyz*CD?AcDdrG1Fg3*w+f) ztshlD(|Xl99LwX&(!`;CE>xb>ip#g`p==YpuJ-B7?NqfNftVXL_C+QL&)$e>8%V8z zQO*=-r^+c=TA+t>eL)a9CMX(E#oYuDrWTMX)i{>LRrsfp^MrvhXZ1;d7=3RNLs+0^ zu>MSTL3MnZ3SZ29u~fdHK_K$^#AV??ix<6-_lGFnjjjW~`Q9r8PCDo1)lIeu9+{vR zOnLRYo@-zG578rLsn{CyctD~{HFQ8smkbXn4qxn^aP#^ON&*(MBkrm_-*iU<4P>(L zP-ZG1b<_M_lmL-as@%EZ_?EBva5(9h$Z8xJ3V81Fm{J_T*GlqHbxZuF1(N)I7BuN;OLYBL65WzyYn5O+q{kT4AOxQ*VzF86nbUep=l8q$h~N^ zY$$dC-+Bt`Yu)C{RG39J8jooxk>RSczLfqU(ujBTWO7Jc%^^UK47nf{i^$KRt!A*} znY@>2xTVz>i_csi9A9&$W03?akwD%>>gtC3LnS9=;j@!LM89?cHI4~*6~FNkc&Bxr z8uXLTSC*Z{IN@XKs-{m+W`l}j=tj7lqo;6um;fZbI#0)aF=qgBhwxVJT#Vj_jVWQt ze{BNmf?)k#mfMdu8jNa8_L(mn&t_Ii%j#YK6)$S(=9SZ<-hcnLw0=-eb&FnQUDGCS z@aWHEmgC2fY>)3hqrCq-2pGa@#yHPQAht@U95-oXY7A)|9JD;Xj0;lOUiWx+eaOqb z#+`E}C!0RIXZ+nG`YZAAcZvQG-FzL&d-!Y>4*&S>IyKp;Ce?4s`Wg3n<7H+Y_{7_# zvi(0qN2@;025eEUSfCvMm9faS_q0tupa5`kQ$mrhe@%+D_5|C0Mk3|PFT25EHHIAVWwYlm z)80f?3xuP1yFi$wayn&%aRoxoX3Ht5DVWPb>4}R&1gEo+aI$Tf7u#1O_1%-$ zMPrC@Gvk@I_LZu!H2>P#l0aq)XOQGYO9=WBzM{5sFUnQH}| z3;OySnHfluB#HHObaR1y}t>E?Rwjnlww}?F+aciCa`@{M-HaPJ; zea4PogSy&!!*MZB4a%NJe8U6&yCGKn)B_^7ZoTilfmC<;cQI$~okdbn%MIDzKHst{ zSRuO0zkxrV;fJGzH};xCB9><0sb*a3)JRIS+d-><6m2ncy29e1ll3(u$zItI>etx-^LYxr=aFmkTz9TXUNEP3;Oof z@9U7K+MK~GG6#)ON7uN%J|({Tg@b$}lhp?KNHJRaJtJQug5hMQ(pSd)tkeIfML6L2 ze5P8YR{K}Mp(JML7kXI})wCGEkS!8S4iiCCCGE2;#kx&;7zz{btQ^VcF?+*|VyJ4c zIZa>dQ1L0SgGW|13wbd4x;ky|MHz$cE;UmBD>S?+nx$T+)wV{Siz2>=d+<5aMx<%1 zdYa2uasm3`S}XG8!S*K_+C}%>9{PC_ET9|#T$sGO9%vVq-n|7Qy8=QyM^OUCOy#�i$s(fUU;R? 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 literal 0 HcmV?d00001 diff --git a/user/pages/05.nouvelle-section-2/01.sous-section-2-1/03.affiche-danimation-reseau-40-x-60-cm/Affiche_APF_DEF.jpg b/user/pages/05.nouvelle-section-2/01.sous-section-2-1/03.affiche-danimation-reseau-40-x-60-cm/Affiche_APF_DEF.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4e6ec4f3bb680ffb3b6a53afb6253d264595c0ce GIT binary patch literal 1468596 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�L!ead9I#VAjgVEpIGo(UAv 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