├── .babelrc ├── .distignore ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .github └── workflows │ ├── codeql-analysis.yml │ ├── deploy-to-wpdotorg.yml │ └── update-wpdotorg-assets.yml ├── .gitignore ├── .nvmrc ├── .travis.yml ├── .wordpress-org ├── banner-1544x500.png ├── banner-772x250.png ├── icon-128x128.png ├── icon-256x256.png ├── icon.svg ├── screenshot-1.png ├── screenshot-2.png ├── screenshot-4.png ├── screenshot-5.png └── screenshot-6.png ├── README.md ├── analogwp-templates.php ├── assets ├── css │ ├── admin-settings.css │ ├── elementor-modal.css │ ├── onboarding-screen.css │ └── sk-components.css ├── img │ ├── analog.svg │ ├── blocks.svg │ ├── elementor.svg │ ├── gopro_frames.png │ ├── placeholder.svg │ └── triangle.svg └── js │ ├── admin-settings.js │ ├── admin.js │ ├── elementor-modal.js │ ├── kit-list.js │ ├── onboarding-screen.js │ └── quick-edit.js ├── client ├── AnalogContext.js ├── App.js ├── Header.js ├── Modal.js ├── Nav.js ├── Notifications.js ├── ProModal.js ├── Synchronization.js ├── Template.js ├── Templates.js ├── api.js ├── blocks │ ├── BlockList.js │ ├── Sidebar.js │ └── blocks.js ├── collection │ └── Collection.js ├── contexts │ └── ThemeContext.js ├── filters.js ├── helpers │ ├── Empty.js │ └── Image.js ├── icons │ ├── analogpro.js │ ├── close.js │ ├── error.js │ ├── loader.js │ ├── logo.js │ ├── notice.js │ ├── refresh.js │ ├── star.js │ └── success.js ├── index.js ├── modal │ └── Preview.js ├── popup.js ├── popups │ └── ImportTemplate.js ├── stylekits │ └── stylekits.js └── utils.js ├── codeception.dist.yml ├── composer.json ├── composer.lock ├── freemius ├── LICENSE.txt ├── README.md ├── assets │ ├── css │ │ ├── admin │ │ │ ├── account.css │ │ │ ├── add-ons.css │ │ │ ├── affiliation.css │ │ │ ├── checkout.css │ │ │ ├── clone-resolution.css │ │ │ ├── common.css │ │ │ ├── connect.css │ │ │ ├── debug.css │ │ │ ├── dialog-boxes.css │ │ │ ├── gdpr-optin-notice.css │ │ │ ├── index.php │ │ │ ├── optout.css │ │ │ └── plugins.css │ │ ├── customizer.css │ │ └── index.php │ ├── img │ │ ├── analogwp-templates.png │ │ ├── index.php │ │ ├── plugin-icon.png │ │ ├── style-kits-pr.png │ │ ├── style-kits-pro.png │ │ └── theme-icon.png │ ├── index.php │ └── js │ │ ├── index.php │ │ ├── jquery.form.js │ │ ├── nojquery.ba-postmessage.js │ │ ├── postmessage.js │ │ └── pricing │ │ ├── 14fb1bd5b7c41648488b06147f50a0dc.svg │ │ ├── 178afa6030e76635dbe835e111d2c507.png │ │ ├── 27b5a722a5553d9de0170325267fccec.png │ │ ├── 4375c4a3ddc6f637c2ab9a2d7220f91e.png │ │ ├── 4529cac82a2d1f300d3c4702b7b5e8f3.svg │ │ ├── 5480ed23b199531a8cbc05924f26952b.png │ │ ├── b4f3b958f4a019862d81b15f3f8eee3a.svg │ │ ├── c03f665db27af43971565560adfba594.png │ │ ├── cb5fc4f6ec7ada72e986f6e7dde365bf.png │ │ ├── dd89563360f0272635c8f0ab7d7f1402.png │ │ ├── e366d70661d8ad2493bd6afbd779f125.png │ │ ├── f18006f6535a1a6e9c6bfbffafe6f18a.svg │ │ ├── f3aac72a8e63997d6bb888f816457e9b.png │ │ ├── f928f1be99776af83e8e6be4baf8ffe7.svg │ │ ├── fde48e4609a6ddc11d639fc2421f2afd.png │ │ ├── freemius-pricing.js │ │ └── freemius-pricing.js.LICENSE.txt ├── config.php ├── includes │ ├── class-freemius-abstract.php │ ├── class-freemius.php │ ├── class-fs-admin-notices.php │ ├── class-fs-api.php │ ├── class-fs-garbage-collector.php │ ├── class-fs-lock.php │ ├── class-fs-logger.php │ ├── class-fs-options.php │ ├── class-fs-plugin-updater.php │ ├── class-fs-security.php │ ├── class-fs-storage.php │ ├── class-fs-user-lock.php │ ├── customizer │ │ ├── class-fs-customizer-support-section.php │ │ ├── class-fs-customizer-upsell-control.php │ │ └── index.php │ ├── debug │ │ ├── class-fs-debug-bar-panel.php │ │ ├── debug-bar-start.php │ │ └── index.php │ ├── entities │ │ ├── class-fs-affiliate-terms.php │ │ ├── class-fs-affiliate.php │ │ ├── class-fs-billing.php │ │ ├── class-fs-entity.php │ │ ├── class-fs-payment.php │ │ ├── class-fs-plugin-info.php │ │ ├── class-fs-plugin-license.php │ │ ├── class-fs-plugin-plan.php │ │ ├── class-fs-plugin-tag.php │ │ ├── class-fs-plugin.php │ │ ├── class-fs-pricing.php │ │ ├── class-fs-scope-entity.php │ │ ├── class-fs-site.php │ │ ├── class-fs-subscription.php │ │ ├── class-fs-user.php │ │ └── index.php │ ├── fs-core-functions.php │ ├── fs-essential-functions.php │ ├── fs-html-escaping-functions.php │ ├── fs-plugin-info-dialog.php │ ├── index.php │ ├── l10n.php │ ├── managers │ │ ├── class-fs-admin-menu-manager.php │ │ ├── class-fs-admin-notice-manager.php │ │ ├── class-fs-cache-manager.php │ │ ├── class-fs-checkout-manager.php │ │ ├── class-fs-clone-manager.php │ │ ├── class-fs-contact-form-manager.php │ │ ├── class-fs-debug-manager.php │ │ ├── class-fs-gdpr-manager.php │ │ ├── class-fs-key-value-storage.php │ │ ├── class-fs-license-manager.php │ │ ├── class-fs-option-manager.php │ │ ├── class-fs-permission-manager.php │ │ ├── class-fs-plan-manager.php │ │ ├── class-fs-plugin-manager.php │ │ └── index.php │ ├── sdk │ │ ├── Exceptions │ │ │ ├── ArgumentNotExistException.php │ │ │ ├── EmptyArgumentException.php │ │ │ ├── Exception.php │ │ │ ├── InvalidArgumentException.php │ │ │ ├── OAuthException.php │ │ │ └── index.php │ │ ├── FreemiusBase.php │ │ ├── FreemiusWordPress.php │ │ ├── LICENSE.txt │ │ └── index.php │ └── supplements │ │ ├── fs-essential-functions-1.1.7.1.php │ │ ├── fs-essential-functions-2.2.1.php │ │ ├── fs-migration-2.5.1.php │ │ └── index.php ├── index.php ├── languages │ ├── freemius-cs_CZ.mo │ ├── freemius-da_DK.mo │ ├── freemius-de_DE.mo │ ├── freemius-es_ES.mo │ ├── freemius-fr_FR.mo │ ├── freemius-he_IL.mo │ ├── freemius-hu_HU.mo │ ├── freemius-it_IT.mo │ ├── freemius-ja.mo │ ├── freemius-nl_NL.mo │ ├── freemius-ru_RU.mo │ ├── freemius-ta.mo │ ├── freemius-zh_CN.mo │ ├── freemius.pot │ └── index.php ├── require.php ├── start.php └── templates │ ├── account.php │ ├── account │ ├── billing.php │ ├── index.php │ ├── partials │ │ ├── activate-license-button.php │ │ ├── addon.php │ │ ├── deactivate-license-button.php │ │ ├── disconnect-button.php │ │ ├── index.php │ │ └── site.php │ └── payments.php │ ├── add-ons.php │ ├── add-trial-to-pricing.php │ ├── admin-notice.php │ ├── ajax-loader.php │ ├── api-connectivity-message-js.php │ ├── auto-installation.php │ ├── checkout.php │ ├── checkout │ ├── frame.php │ ├── process-redirect.php │ └── redirect.php │ ├── clone-resolution-js.php │ ├── connect.php │ ├── connect │ ├── index.php │ ├── permission.php │ └── permissions-group.php │ ├── contact.php │ ├── debug.php │ ├── debug │ ├── api-calls.php │ ├── index.php │ ├── logger.php │ ├── plugins-themes-sync.php │ └── scheduled-crons.php │ ├── email.php │ ├── forms │ ├── affiliation.php │ ├── data-debug-mode.php │ ├── deactivation │ │ ├── contact.php │ │ ├── form.php │ │ ├── index.php │ │ └── retry-skip.php │ ├── email-address-update.php │ ├── index.php │ ├── license-activation.php │ ├── optout.php │ ├── premium-versions-upgrade-handler.php │ ├── premium-versions-upgrade-metadata.php │ ├── resend-key.php │ ├── subscription-cancellation.php │ ├── trial-start.php │ └── user-change.php │ ├── gdpr-optin-js.php │ ├── index.php │ ├── js │ ├── index.php │ ├── jquery.content-change.php │ ├── open-license-activation.php │ ├── permissions.php │ └── style-premium-theme.php │ ├── partials │ ├── index.php │ └── network-activation.php │ ├── plugin-icon.php │ ├── plugin-info │ ├── description.php │ ├── features.php │ ├── index.php │ └── screenshots.php │ ├── pricing.php │ ├── secure-https-header.php │ ├── sticky-admin-notice-js.php │ ├── tabs-capture-js.php │ └── tabs.php ├── gulpfile.js ├── inc ├── Consumer.php ├── Core │ ├── SVGs │ │ └── Allow.php │ ├── Storage │ │ └── Transients.php │ └── Util │ │ └── Migration.php ├── Database_Upgrader.php ├── Plugin.php ├── Utils.php ├── admin │ ├── Notice.php │ ├── Notices.php │ └── class-admin.php ├── api │ ├── class-local.php │ └── class-remote.php ├── class-admin-settings.php ├── class-analog-importer.php ├── class-base.php ├── class-beta-testers.php ├── class-cron.php ├── class-elementor.php ├── class-formatter.php ├── class-import-image.php ├── class-onboarding.php ├── class-options.php ├── class-quick-edit.php ├── class-tracker.php ├── cli │ └── commands.php ├── elementor │ ├── Google_Fonts.php │ ├── Promotions.php │ ├── Reset_Default_Style_Trait.php │ ├── class-ang-action.php │ ├── class-colors.php │ ├── class-finder-shortcuts.php │ ├── class-post-type.php │ ├── class-tools.php │ ├── class-typography.php │ ├── css │ │ └── hint.min.css │ ├── globals │ │ ├── class-colors.php │ │ ├── class-controller.php │ │ └── class-typography.php │ ├── js │ │ ├── ang-action.js │ │ ├── ang-cpt-tools.js │ │ ├── ang-typography.js │ │ └── cssbeautify.min.js │ ├── kit │ │ ├── Instance_List_Table.php │ │ ├── Kits_List_Table.php │ │ ├── Manager.php │ │ ├── kit-content.json │ │ ├── tabs │ │ │ └── Theme_Style_Kits.php │ │ └── views │ │ │ └── trash-kit-confirmation.php │ ├── sections │ │ └── background-color-classes.php │ ├── tags │ │ ├── class-dark-background.php │ │ └── class-light-background.php │ └── trait-document.php ├── register-settings.php ├── settings-helpers.php ├── settings │ ├── class-settings-experiments.php │ ├── class-settings-extensions.php │ ├── class-settings-general.php │ ├── class-settings-gopro.php │ ├── class-settings-misc.php │ ├── class-settings-page.php │ ├── class-settings-version-control.php │ └── views │ │ ├── html-admin-settings-gopro.php │ │ └── html-admin-settings.php └── upgrade-functions.php ├── languages ├── ang-analogwp-app.json └── ang.pot ├── package-lock.json ├── package.json ├── phpcs.xml.dist ├── readme.txt ├── scoper.inc.php ├── tests ├── _data │ └── .gitkeep ├── _output │ └── .gitignore ├── _support │ ├── AcceptanceTester.php │ ├── ApiTester.php │ ├── FunctionalTester.php │ ├── Helper │ │ ├── Acceptance.php │ │ ├── Api.php │ │ ├── Functional.php │ │ ├── Unit.php │ │ └── Wpunit.php │ ├── UnitTester.php │ ├── WpunitTester.php │ └── _generated │ │ └── .gitignore ├── acceptance.suite.yml ├── acceptance │ ├── SaveSettingsCest.php │ └── StyleKitExportImportCest.php ├── api.suite.yml ├── api │ └── CheckEndpointsCest.php ├── functional.suite.yml ├── unit.suite.yml └── wpunit.suite.yml ├── third-party ├── composer.json └── vendor │ ├── autoload.php │ ├── composer │ ├── ClassLoader.php │ ├── LICENSE │ ├── autoload_classmap.php │ ├── autoload_namespaces.php │ ├── autoload_psr4.php │ ├── autoload_real.php │ └── autoload_static.php │ ├── enshrined │ └── svg-sanitize │ │ ├── composer.json │ │ └── src │ │ ├── ElementReference │ │ ├── Resolver.php │ │ ├── Subject.php │ │ └── Usage.php │ │ ├── Exceptions │ │ └── NestingException.php │ │ ├── Helper.php │ │ ├── Sanitizer.php │ │ ├── data │ │ ├── AllowedAttributes.php │ │ ├── AllowedTags.php │ │ ├── AttributeInterface.php │ │ ├── TagInterface.php │ │ └── XPath.php │ │ └── svg-scanner.php │ └── scoper-autoload.php └── uninstall.php /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env", 4 | "@babel/preset-react" 5 | ], 6 | "plugins": [ 7 | "@babel/plugin-proposal-class-properties" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /.distignore: -------------------------------------------------------------------------------- 1 | # Directories 2 | /.wordpress-org 3 | /.git 4 | /.github 5 | /.babelrc 6 | /.eslintignore 7 | /.vscode 8 | /phpcs.xml 9 | /node_modules 10 | /tests 11 | /bin 12 | /phpunit.xml 13 | /build 14 | /client 15 | .nvmrc 16 | .wp-env.json 17 | phpcs.xml.dist 18 | 19 | # Exclude vendor folder, except required dependencies. 20 | /vendor 21 | !/vendor/composer 22 | !/vendor/autoload.php 23 | 24 | # Files 25 | .babelrc 26 | .distignore 27 | .eslintignore 28 | .eslintrc.json 29 | .gitignore 30 | .editorconfig 31 | .travisyml 32 | .codeception.dist.yml 33 | DOCKER_ENV 34 | docker_tag 35 | Dockerfile-php-build 36 | output.log 37 | CHANGELOG.md 38 | CODE_OF_CONDUCT.md 39 | CONTRIBUTING.md 40 | CREDITS.md 41 | LICENSE.md 42 | README.md 43 | composer.json 44 | composer.lock 45 | package-lock.json 46 | yarn.lock 47 | package.json 48 | phpcs.xml 49 | phpunit.xml 50 | webpack.config.js 51 | gulpfile.js 52 | gulp.config.json 53 | scoper.inc.php 54 | 55 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = tab 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [{package.json, *.yml}] 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [composer.json, eslintrc.json] 16 | indent_style = space 17 | indent_size = 4 18 | 19 | [*.md] 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/*.min.js 2 | **/*.build.js 3 | **/node_modules/** 4 | **/vendor/** 5 | build 6 | coverage 7 | cypress 8 | node_modules 9 | vendor 10 | -------------------------------------------------------------------------------- /.github/workflows/deploy-to-wpdotorg.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to WordPress.org 2 | 3 | on: 4 | push: 5 | tags: 6 | - "*" 7 | 8 | jobs: 9 | tag: 10 | name: New tag 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@master 14 | 15 | - name: Install Composer dependencies 16 | uses: php-actions/composer@v6 17 | with: 18 | version: 2 19 | php_version: '8.0' 20 | 21 | - name: Setup Node 22 | uses: actions/setup-node@v1 23 | with: 24 | node-version: '21' 25 | 26 | - name: Install dependencies 27 | run: npm install 28 | 29 | - name: Prepare release build 30 | run: npm run gh:release 31 | 32 | - name: WordPress Plugin Deploy 33 | uses: 10up/action-wordpress-plugin-deploy@master 34 | env: 35 | BUILD_DIR: ./build/analogwp-templates 36 | SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }} 37 | SVN_USERNAME: ${{ secrets.SVN_USERNAME }} 38 | -------------------------------------------------------------------------------- /.github/workflows/update-wpdotorg-assets.yml: -------------------------------------------------------------------------------- 1 | name: Plugin asset/readme update 2 | 3 | on: 4 | push: 5 | branches: 6 | - develop 7 | 8 | env: 9 | SLUG: analogwp-templates 10 | 11 | jobs: 12 | master: 13 | name: Push to trunk 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@master 17 | - name: WordPress.org plugin asset/readme update 18 | uses: 10up/action-wordpress-plugin-asset-update@stable 19 | env: 20 | SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }} 21 | SVN_USERNAME: ${{ secrets.SVN_USERNAME }} 22 | IGNORE_OTHER_FILES: true 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /src/js/app/test.js 2 | /assets/js/app.js.map 3 | /build 4 | /assets/js/app.js 5 | /assets/js/app/ 6 | node_modules/ 7 | /assets/fonts/ 8 | /assets/js/blocksLibrary.js 9 | /assets/js/blocksLibrary.js.map 10 | 11 | 12 | /.idea/** 13 | /.idea/workspace.xml 14 | /inc/elementor/js/ang-action.min.js 15 | /inc/elementor/js/ang-typography.min.js 16 | /inc/elementor/js/*.min.js 17 | /gulp.config.json 18 | 19 | /vendor/ 20 | /.env 21 | /tests/_data/dump.sql 22 | tests/_output/* 23 | tests/_support/_generated/* 24 | tests/cache/* 25 | tests/error.log 26 | .DS_Store 27 | 28 | analogwp-templates.zip 29 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 21 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | dist: trusty 3 | sudo: false 4 | 5 | php: 6 | - "7.4" 7 | - "8.0" 8 | - "8.1" 9 | 10 | env: 11 | - WP_VERSION=latest WP_MULTISITE=0 12 | - WP_VERSION=6.6 WP_MULTISITE=0 13 | 14 | matrix: 15 | include: 16 | - php: "8.1" 17 | env: WP_VERSION=latest WP_MULTISITE=0 18 | - php: "8.0" 19 | env: WP_VERSION=latest WP_MULTISITE=0 20 | - php: "7.4" 21 | env: WP_VERSION=latest WP_MULTISITE=0 22 | 23 | branches: 24 | only: 25 | - develop 26 | - /^feature\/.*$/ 27 | 28 | script: 29 | - php -v 30 | - phpunit --version 31 | -------------------------------------------------------------------------------- /.wordpress-org/banner-1544x500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/banner-1544x500.png -------------------------------------------------------------------------------- /.wordpress-org/banner-772x250.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/banner-772x250.png -------------------------------------------------------------------------------- /.wordpress-org/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/icon-128x128.png -------------------------------------------------------------------------------- /.wordpress-org/icon-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/icon-256x256.png -------------------------------------------------------------------------------- /.wordpress-org/icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.wordpress-org/screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/screenshot-1.png -------------------------------------------------------------------------------- /.wordpress-org/screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/screenshot-2.png -------------------------------------------------------------------------------- /.wordpress-org/screenshot-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/screenshot-4.png -------------------------------------------------------------------------------- /.wordpress-org/screenshot-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/screenshot-5.png -------------------------------------------------------------------------------- /.wordpress-org/screenshot-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/.wordpress-org/screenshot-6.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![WordPress plugin](https://img.shields.io/wordpress/plugin/dt/analogwp-templates.svg?style=flat)](https://wordpress.org/plugins/analogwp-templates/) [![Installs](https://img.shields.io/wordpress/plugin/installs/analogwp-templates.svg)](https://wordpress.org/plugins/analogwp-templates/) [![License](https://img.shields.io/badge/license-GPL--2.0%2B-red.svg)](https://github.com/analogwp/analogwp-templates/blob/master/license.txt) ![build](https://img.shields.io/travis/analogwp/analogwp-templates) 2 | 3 | ![](https://img.shields.io/wordpress/plugin/wp-version/analogwp-templates) 4 | [![WordPress](https://img.shields.io/wordpress/v/analogwp-templates.svg?style=flat)]() 5 | [![WordPress plugin](https://img.shields.io/wordpress/plugin/v/analogwp-templates.svg?style=flat)](https://wordpress.org/plugins/analogwp-templates/) 6 | 7 | Analog Templates 8 | === 9 | 10 | Your layouts deserve more. Use inspiring, extendable design resources for consistent websites and sharp workflow. 11 | 12 | More information can be found at [analogwp.com](https://analogwp.com/). 13 | 14 | ### Build Commands 15 | - `npm run dev-app` for development. 16 | - `npm run build` for production and release files. 17 | 18 | ### Bugs 19 | If you find a 🐞 or an issue, please [create an issue](https://github.com/analogwp/stag-blocks/issues/new). 20 | -------------------------------------------------------------------------------- /assets/img/analog.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/img/blocks.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /assets/img/elementor.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/img/gopro_frames.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/assets/img/gopro_frames.png -------------------------------------------------------------------------------- /assets/img/placeholder.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/img/triangle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/js/admin.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | $('.analog-notice').on( 'click', 'button.notice-dismiss', function(){ 3 | $.post( ajaxurl, { 4 | action: 'analog_set_admin_notice_viewed', 5 | key: $( this ).closest('.analog-notice').data( 'key' ), 6 | nonce: AnalogAdmin.nonce || '', 7 | } ); 8 | 9 | console.log($( this ).closest('.analog-notice').data( 'key' )); 10 | } ); 11 | })(jQuery); 12 | -------------------------------------------------------------------------------- /assets/js/elementor-modal.js: -------------------------------------------------------------------------------- 1 | /* global elementor, elementorCommon */ 2 | /* eslint-disable */ 3 | 4 | const analog = window.analog = window.analog || {}; 5 | 6 | "undefined" != typeof jQuery && 7 | !(function($) { 8 | $(function() { 9 | function modal() { 10 | const insertIndex = 0 < jQuery(this).parents(".elementor-section-wrap").length ? jQuery(this).parents(".elementor-add-section").index() : -1; 11 | 12 | analog.insertIndex = insertIndex; 13 | 14 | elementorCommon && 15 | (window.analogModal || 16 | ((window.analogModal = elementorCommon.dialogsManager.createWidget( 17 | "lightbox", 18 | { 19 | id: "analogwp-templates-modal", 20 | headerMessage: "What is this???", 21 | message: "", 22 | hide: { 23 | auto: !1, 24 | onClick: !1, 25 | onOutsideClick: !1, 26 | onOutsideContextMenu: !1, 27 | onBackgroundClick: !0 28 | }, 29 | position: { 30 | my: "center", 31 | at: "center" 32 | }, 33 | onShow: function() { 34 | const content = window.analogModal.getElements("content"); 35 | content.append('
'); 36 | var event = new Event("modal-close"); 37 | $("#analogwp-templates").on( 38 | "click", 39 | ".close-modal", 40 | function() { 41 | document.dispatchEvent(event); 42 | return window.analogModal.hide(), !1; 43 | } 44 | ); 45 | }, 46 | onHide: function() {} 47 | } 48 | )), 49 | window.analogModal.getElements("header").remove(), 50 | window.analogModal 51 | .getElements("message") 52 | .append(window.analogModal.addElement("content"))), 53 | window.analogModal.show()); 54 | } 55 | 56 | window.analogModal = null; 57 | 58 | const template = $("#tmpl-elementor-add-section"); 59 | 60 | if (0 < template.length && typeof elementor !== undefined) { 61 | let text = template.text(); 62 | 63 | (text = text.replace( 64 | '
 
{ 76 | const { theme } = React.useContext( ThemeContext ); 77 | 78 | return ( 79 | 80 |
81 |
82 | 83 |
84 | { ! AGWP.isContainer &&
87 |
88 | ); 89 | }; 90 | 91 | export default Header; 92 | -------------------------------------------------------------------------------- /client/Modal.js: -------------------------------------------------------------------------------- 1 | import styled, { keyframes } from 'styled-components'; 2 | const { FocusableIframe, Button } = wp.components; 3 | const { __ } = wp.i18n; 4 | 5 | const rotateOpacity = keyframes` 6 | 0% { 7 | opacity: 0.5; 8 | } 9 | 10 | 50% { 11 | opacity: 0.1; 12 | } 13 | 14 | 100% { 15 | opacity: 0.5; 16 | } 17 | `; 18 | 19 | const Img = styled.img` 20 | opacity: 0.5; 21 | transition: all 200ms ease-in-out; 22 | animation: ${ rotateOpacity } 2s linear infinite; 23 | `; 24 | 25 | const Container = styled.div` 26 | position: absolute; 27 | top: 0; 28 | left: 0; 29 | width: 100%; 30 | height: 100%; 31 | overflow: hidden; 32 | overflow: -moz-scrollbars-none; 33 | background: #F1F1F1; 34 | z-index: 999; 35 | text-align: center; 36 | 37 | iframe { 38 | width: 100%; 39 | height: 100%; 40 | display: ${ props => props.loading ? 'none' : 'block' }; 41 | } 42 | 43 | .frame-header { 44 | display: flex; 45 | justify-content: space-between; 46 | align-items: center; 47 | margin-bottom: 25px; 48 | 49 | a { 50 | margin-left: auto; 51 | margin-right: 20px; 52 | color: currentColor; 53 | text-decoration: none; 54 | } 55 | 56 | .dashicons { 57 | font-size: 25px; 58 | } 59 | } 60 | 61 | .button--accent { 62 | font-size: 12px; 63 | font-weight: bold; 64 | color: #fff; 65 | border-radius: 0; 66 | border: none; 67 | background: var(--ang-accent); 68 | outline: 0; 69 | box-shadow: none; 70 | padding: 15px 30px; 71 | cursor: pointer; 72 | } 73 | `; 74 | 75 | const Modal = props => { 76 | const [ loading, setLoading ] = React.useState( true ); 77 | 78 | return ( 79 | 80 |
81 | 84 | 85 | 86 | 89 | 90 | 91 | { ! ( props.template.is_pro && AGWP.license.status !== 'valid' ) && ( 92 | 95 | ) } 96 |
97 | 98 | { loading && Loading icon } 102 | 103 | setLoading( false ) } /> 104 |
105 | ); 106 | }; 107 | 108 | export default Modal; 109 | -------------------------------------------------------------------------------- /client/Nav.js: -------------------------------------------------------------------------------- 1 | import AnalogContext from './AnalogContext'; 2 | const { __ } = wp.i18n; 3 | const { TabPanel } = wp.components; 4 | 5 | const ITEMS = [ 6 | { key: 'blocks', label: AGWP.isContainer ? __( 'Patterns', 'ang' ) : __( 'Blocks', 'ang' ) }, 7 | { key: 'templates', label: __( 'Templates', 'ang' ) }, 8 | // dont change the "styleKits" casing here 9 | { key: 'styleKits', label: __( 'Styles', 'ang' ) }, 10 | ]; 11 | 12 | const Nav = () => { 13 | const context = React.useContext( AnalogContext ); 14 | 15 | const getCount = ( tab ) => { 16 | let items = context.state[ tab ]; 17 | 18 | if ( tab === 'templates' ) { 19 | items = context.state.archive; 20 | } 21 | if ( tab === 'blocks' ) { 22 | items = context.state.blockArchive; 23 | } 24 | 25 | if ( ! items ) { 26 | return false; 27 | } 28 | 29 | return items.length; 30 | }; 31 | 32 | const titleGenerator = (titleObject) => { 33 | let count = getCount(titleObject.key); 34 | let countTemplate = count > 0 ? '(' + count + ')' : ''; 35 | 36 | return `${titleObject.label} ${countTemplate}`; 37 | } 38 | 39 | const onSelect = ( tabName ) => { 40 | context.dispatch( { tab: tabName }); 41 | }; 42 | 43 | const tabsGenerator = (tabsArray) => { 44 | return tabsArray.map( (item) => ({ 45 | name: item.key, 46 | title: titleGenerator(item), 47 | className: `tab-${ item.key }` 48 | } 49 | )); 50 | } 51 | 52 | const tabContent = () => { 53 | return null; 54 | } 55 | 56 | return ( 57 | 58 | 61 | { 62 | (tab) => tabContent() 63 | } 64 | 65 | 66 | ); 67 | }; 68 | 69 | export default Nav; 70 | -------------------------------------------------------------------------------- /client/ProModal.js: -------------------------------------------------------------------------------- 1 | const { ExternalLink, Button } = wp.components; 2 | const { __ } = wp.i18n; 3 | 4 | const ProModal = () => ( 5 |
6 |

{ __( 'Get unlimited access to the Style Kits library and features with the PRO version.', 'ang' ) }

7 | { __( 'View Plans', 'ang' ) } 8 |
9 | ); 10 | 11 | export default ProModal; 12 | -------------------------------------------------------------------------------- /client/Synchronization.js: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames'; 2 | import AnalogContext from './AnalogContext'; 3 | import { NotificationConsumer } from './Notifications'; 4 | import Close from './icons/close'; 5 | 6 | const { __ } = wp.i18n; 7 | const { Button } = wp.components; 8 | 9 | const Synchronization = () => { 10 | return ( 11 |
12 | 13 | { context => ( 14 | 15 | { ( { add } ) => ( 16 | 32 | ) } 33 | 34 | ) } 35 | 36 | { ! AGWP.is_settings_page && ( 37 | 40 | ) } 41 |
42 | ); 43 | }; 44 | 45 | export default Synchronization; 46 | -------------------------------------------------------------------------------- /client/Template.js: -------------------------------------------------------------------------------- 1 | import classnames from 'classnames'; 2 | import Image from './helpers/Image'; 3 | import Star from './icons/star'; 4 | import { isNewTheme } from './utils'; 5 | 6 | const { decodeEntities } = wp.htmlEntities; 7 | const { __ } = wp.i18n; 8 | const { Button, Card, CardBody, CardFooter } = wp.components; 9 | 10 | const Template = ( { template, setModalContent, importLayout, favorites, makeFavorite } ) => { 11 | const isValid = ( isPro ) => ! ( isPro && AGWP.license.status !== 'valid' ); 12 | 13 | const fallbackImage = AGWP.pluginURL + 'assets/img/placeholder.svg'; 14 | 15 | return ( 16 |
  • 17 | 18 | 19 | { ( isNewTheme( template.published ) > -14 ) && ( 20 | { __( 'New', 'ang' ) } 21 | ) } 22 | 23 |
    24 | { template.thumbnail ? : } 25 |
    26 | 29 | { ! isValid( template.is_pro ) && ( 30 | 31 | 32 | 33 | ) } 34 | { isValid( template.is_pro ) && ( 35 | 38 | ) } 39 |
    40 | 41 | 49 |
    50 |
    51 | 52 |
    53 | 54 |

    { decodeEntities( template.title ) }

    55 | { template.tags && ( 56 |
    57 | { template.tags.map( tag => ( 58 | { tag } 59 | ) ) } 60 |
    61 | ) } 62 |
    63 | { template.is_pro && ( 64 | { __( 'Pro', 'ang' ) } 65 | ) } 66 |
    67 |
    68 |
    69 |
  • 70 | ); 71 | }; 72 | 73 | export default Template; 74 | -------------------------------------------------------------------------------- /client/contexts/ThemeContext.js: -------------------------------------------------------------------------------- 1 | const ThemeContext = React.createContext(); 2 | 3 | export const ThemeProvider = ThemeContext.Provider; 4 | export const ThemeConsumer = ThemeContext.Consumer; 5 | 6 | export const Theme = { 7 | accent: 'var(--ang-primary)', 8 | textLight: 'var(--ang-sec-text)', 9 | textDark: 'var(--ang-main-text)', 10 | lightGray: '#F2F2F2', 11 | }; 12 | 13 | export default ThemeContext; 14 | -------------------------------------------------------------------------------- /client/helpers/Empty.js: -------------------------------------------------------------------------------- 1 | const Empty = ( { text = 'No templates found.', ...rest } ) => { 2 | return ( 3 |
    4 |

    { text }

    5 |
    6 | ); 7 | }; 8 | 9 | export default Empty; 10 | -------------------------------------------------------------------------------- /client/helpers/Image.js: -------------------------------------------------------------------------------- 1 | import { Waypoint } from 'react-waypoint'; 2 | 3 | const Image = ( { template, ...attributes } ) => { 4 | const { thumbnail, title } = template; 5 | const [ image, setImage ] = React.useState( AGWP.pluginURL + 'assets/img/placeholder.svg' ); 6 | 7 | return ( 8 | { 9 | setImage( thumbnail ); 10 | } }> 11 | { 12 | 13 | ); 14 | }; 15 | 16 | export default Image; 17 | -------------------------------------------------------------------------------- /client/icons/close.js: -------------------------------------------------------------------------------- 1 | const Close = () => ( 2 | 9 | 10 | 11 | ); 12 | 13 | export default Close; 14 | -------------------------------------------------------------------------------- /client/icons/error.js: -------------------------------------------------------------------------------- 1 | const Error = () => ( 2 | 3 | 4 | 5 | ); 6 | 7 | export default Error; 8 | -------------------------------------------------------------------------------- /client/icons/loader.js: -------------------------------------------------------------------------------- 1 | const Loader = () => ( 2 |
    3 | ); 4 | 5 | export default Loader; 6 | -------------------------------------------------------------------------------- /client/icons/notice.js: -------------------------------------------------------------------------------- 1 | const Notice = () => ( 2 | 3 | 4 | 5 | ); 6 | 7 | export default Notice; -------------------------------------------------------------------------------- /client/icons/refresh.js: -------------------------------------------------------------------------------- 1 | const Refresh = () => ( 2 | 9 | 13 | 14 | ); 15 | 16 | export default Refresh; 17 | -------------------------------------------------------------------------------- /client/icons/star.js: -------------------------------------------------------------------------------- 1 | const Star = () => ( 2 | 9 | 10 | 11 | ); 12 | 13 | export default Star; 14 | -------------------------------------------------------------------------------- /client/icons/success.js: -------------------------------------------------------------------------------- 1 | const Success = () => ( 2 | 3 | 4 | 5 | ); 6 | 7 | export default Success; 8 | -------------------------------------------------------------------------------- /client/index.js: -------------------------------------------------------------------------------- 1 | import App from './App'; 2 | 3 | const containerElementID = 'analogwp-templates'; 4 | 5 | const waitForEl = ( selector, callback ) => { 6 | if ( ! document.getElementById( containerElementID ) ) { 7 | setTimeout( function() { 8 | window.requestAnimationFrame( function() { 9 | waitForEl( selector, callback ); 10 | } ); 11 | }, 1000 ); 12 | } else { 13 | callback(); 14 | } 15 | }; 16 | 17 | // We don't use a variable here because in Elementor modal the element is added dynamically. 18 | waitForEl( document.getElementById( containerElementID ), () => { 19 | if ( window.AGWP && window.AGWP.wp_version && window.AGWP.wp_version >= '6.2' ) { 20 | const { createRoot } = wp.element; 21 | const containerRoot = createRoot( document.getElementById( containerElementID ) ); 22 | containerRoot.render( ); 23 | } else { 24 | // Ensure compatibility with React 17 and lower. 25 | const { render } = wp.element; 26 | render( , document.getElementById( containerElementID ) ); 27 | } 28 | } ); 29 | -------------------------------------------------------------------------------- /client/popup.js: -------------------------------------------------------------------------------- 1 | import Close from './icons/close'; 2 | 3 | const { Card, CardBody, CardDivider, CardHeader } = wp.components; 4 | 5 | const Popup = ( props ) => { 6 | const { title, onRequestClose, children, ...rest } = props; 7 | return ( 8 |
    9 |
    10 | 11 | 12 |
    13 |

    { title }

    14 | { onRequestClose && ( 15 | 18 | ) } 19 |
    20 |
    21 | 22 | 23 |
    24 | { children } 25 |
    26 |
    27 |
    28 |
    29 |
    30 | ); 31 | }; 32 | 33 | export default Popup; 34 | -------------------------------------------------------------------------------- /client/utils.js: -------------------------------------------------------------------------------- 1 | import { requestSettingUpdate } from './api'; 2 | import Filters from './filters'; 3 | import StyleKits from './stylekits/stylekits'; 4 | import Blocks from './blocks/blocks'; 5 | import Templates from './Templates'; 6 | 7 | const { Fragment } = React; 8 | 9 | export const getPageComponents = ( state ) => { 10 | if ( state.tab === 'styleKits' ) { 11 | return ; 12 | } 13 | 14 | if ( state.tab === 'blocks' ) { 15 | return ; 16 | } 17 | 18 | return ( 19 | 20 | { ! state.isOpen && } 21 | 22 | 23 | ); 24 | }; 25 | 26 | export const debugMode = () => Boolean( AGWP.debugMode ); 27 | 28 | export const Log = ( what ) => { 29 | if ( debugMode ) { 30 | console.log( what ); // eslint-disable-line 31 | } 32 | }; 33 | export const LogStart = ( title ) => { 34 | if ( debugMode ) { 35 | console.group( title ); // eslint-disable-line 36 | } 37 | }; 38 | export const LogEnd = ( title ) => { 39 | if ( debugMode ) { 40 | console.groupEnd( title ); // eslint-disable-line 41 | } 42 | }; 43 | 44 | export function generateUEID() { 45 | let first = ( Math.random() * 46656 ) || 0; 46 | let second = ( Math.random() * 46656 ) || 0; 47 | first = ( '000' + first.toString( 36 ) ).slice( -3 ); 48 | second = ( '000' + second.toString( 36 ) ).slice( -3 ); 49 | return first + second; 50 | } 51 | 52 | export function hasProTemplates( templates ) { 53 | return templates.some( ( template ) => template.is_pro === true ); 54 | } 55 | 56 | export function increaseInstallCount( settings, dispatch ) { 57 | const installCount = parseInt( settings.install_count ) || 0; 58 | 59 | dispatch( { 60 | settings: { 61 | ...settings, 62 | install_count: installCount + 1, 63 | }, 64 | } ); 65 | 66 | requestSettingUpdate( 'install_count', installCount + 1 ); 67 | } 68 | 69 | export function isNewTheme( date ) { 70 | const start = moment.unix( date ); 71 | const end = moment.now(); 72 | return Math.ceil( moment.duration( start.diff( end ) ).asDays() ); 73 | } 74 | 75 | export function getTime( date ) { 76 | const start = moment.unix( date ); 77 | const end = moment.now(); 78 | return Math.ceil( moment.duration( start.diff( end ) ).asMinutes() ); 79 | } 80 | -------------------------------------------------------------------------------- /codeception.dist.yml: -------------------------------------------------------------------------------- 1 | paths: 2 | tests: tests 3 | output: tests/_output 4 | data: tests/_data 5 | support: tests/_support 6 | envs: tests/_envs 7 | actor_suffix: Tester 8 | extensions: 9 | enabled: 10 | - Codeception\Extension\RunFailed 11 | commands: 12 | - Codeception\Command\GenerateWPUnit 13 | - Codeception\Command\GenerateWPRestApi 14 | - Codeception\Command\GenerateWPRestController 15 | - Codeception\Command\GenerateWPRestPostTypeController 16 | - Codeception\Command\GenerateWPAjax 17 | - Codeception\Command\GenerateWPCanonical 18 | - Codeception\Command\GenerateWPXMLRPC 19 | - Codeception\Command\DbSnapshot 20 | - tad\Codeception\Command\SearchReplace 21 | params: 22 | - .env 23 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "analogwp/analogwp-templates", 3 | "description": "Style Kits for Elementor adds a number of intuitive styling controls in the Elementor editor that allow you to apply styles globally or per page.", 4 | "type": "wordpress-plugin", 5 | "license": "GPL-2.0", 6 | "authors": [ 7 | { 8 | "name": "AnalogWP", 9 | "email": "hello@analogwp.com" 10 | } 11 | ], 12 | "minimum-stability": "dev", 13 | "prefer-stable": true, 14 | "config": { 15 | "sort-packages": true, 16 | "allow-plugins": { 17 | "civicrm/composer-downloads-plugin": true, 18 | "ergebnis/composer-normalize": true 19 | } 20 | }, 21 | "require": { 22 | "enshrined/svg-sanitize": "^0.15.4" 23 | }, 24 | "require-dev": { 25 | "civicrm/composer-downloads-plugin": "*", 26 | "ergebnis/composer-normalize": "*", 27 | "flow/jsonpath": "*", 28 | "sniccowp/php-scoper-wordpress-excludes": "*" 29 | }, 30 | "extra": { 31 | "downloads": { 32 | "php-scoper": { 33 | "path": "vendor/bin/php-scoper", 34 | "type": "phar", 35 | "url": "https://github.com/humbug/php-scoper/releases/download/0.17.2/php-scoper.phar" 36 | } 37 | } 38 | }, 39 | "scripts": { 40 | "post-install-cmd": [ 41 | "@prefix-dependencies" 42 | ], 43 | "post-update-cmd": [ 44 | "@prefix-dependencies" 45 | ], 46 | "prefix-dependencies": [ 47 | "php-scoper add-prefix --output-dir=./third-party --force --quiet", 48 | "echo '{ \"autoload\": { \"classmap\": [\"\"] } }' > ./third-party/composer.json", 49 | "@composer dump-autoload --working-dir ./third-party --no-dev --classmap-authoritative" 50 | ] 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /freemius/assets/css/admin/affiliation.css: -------------------------------------------------------------------------------- 1 | #fs_affiliation_content_wrapper #messages{margin-top:25px}#fs_affiliation_content_wrapper h3{font-size:24px;margin-left:0;padding:0}#fs_affiliation_content_wrapper ul li{box-sizing:border-box;list-style-type:none}#fs_affiliation_content_wrapper ul li:before{content:"✓";font-weight:700;margin-right:10px}#fs_affiliation_content_wrapper label,#fs_affiliation_content_wrapper li,#fs_affiliation_content_wrapper p:not(.description){font-size:16px!important;line-height:26px!important}#fs_affiliation_content_wrapper .button{font-size:16px;height:40px;line-height:35px;margin-bottom:7px;margin-top:20px}#fs_affiliation_content_wrapper .button#cancel_button{margin-right:5px}#fs_affiliation_content_wrapper form .input-container{margin-bottom:15px}#fs_affiliation_content_wrapper form .input-container .input-label{display:block;font-weight:700;width:100%}#fs_affiliation_content_wrapper form .input-container.input-container-text input,#fs_affiliation_content_wrapper form .input-container.input-container-text label,#fs_affiliation_content_wrapper form .input-container.input-container-text textarea{display:block}#fs_affiliation_content_wrapper form .input-container #add_domain,#fs_affiliation_content_wrapper form .input-container .remove-domain{display:inline-block;margin-top:3px;text-decoration:none}#fs_affiliation_content_wrapper form .input-container #add_domain:focus,#fs_affiliation_content_wrapper form .input-container .remove-domain:focus{box-shadow:none}#fs_affiliation_content_wrapper form .input-container #add_domain.disabled,#fs_affiliation_content_wrapper form .input-container .remove-domain.disabled{color:#aaa;cursor:default}#fs_affiliation_content_wrapper form #extra_domains_container .description{margin-top:0;position:relative;top:-4px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container{margin-bottom:15px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container .domain{display:inline-block;margin-right:5px}#fs_affiliation_content_wrapper form #extra_domains_container .extra-domain-input-container .domain:last-of-type{margin-bottom:0} -------------------------------------------------------------------------------- /freemius/assets/css/admin/checkout.css: -------------------------------------------------------------------------------- 1 | .fs-ajax-loader{height:20px;margin:auto;position:relative;width:170px}.fs-ajax-loader .fs-ajax-loader-bar{animation-direction:normal;animation-duration:1.5s;animation-iteration-count:infinite;animation-name:bounce_ajaxLoader;background-color:#fff;height:20px;position:absolute;top:0;transform:scale(.3);width:20px}.fs-ajax-loader .fs-ajax-loader-bar-1{animation-delay:.6s;left:0}.fs-ajax-loader .fs-ajax-loader-bar-2{animation-delay:.75s;left:19px}.fs-ajax-loader .fs-ajax-loader-bar-3{animation-delay:.9s;left:38px}.fs-ajax-loader .fs-ajax-loader-bar-4{animation-delay:1.05s;left:57px}.fs-ajax-loader .fs-ajax-loader-bar-5{animation-delay:1.2s;left:76px}.fs-ajax-loader .fs-ajax-loader-bar-6{animation-delay:1.35s;left:95px}.fs-ajax-loader .fs-ajax-loader-bar-7{animation-delay:1.5s;left:114px}.fs-ajax-loader .fs-ajax-loader-bar-8{animation-delay:1.65s;left:133px}@keyframes bounce_ajaxLoader{0%{background-color:#0074a3;transform:scale(1)}to{background-color:#fff;transform:scale(.3)}}@media screen and (max-width:782px){#wpbody-content{padding-bottom:0!important}}.fs-checkout-process-redirect{padding:40px;text-align:center} -------------------------------------------------------------------------------- /freemius/assets/css/admin/clone-resolution.css: -------------------------------------------------------------------------------- 1 | .fs-notice[data-id^=clone_resolution_options_notice]{color:inherit!important;padding:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-notice-body{margin-bottom:0;padding:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-notice-header{padding:5px 10px}.fs-notice[data-id^=clone_resolution_options_notice] ol{margin-bottom:0;margin-top:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-options-container{display:flex;flex-direction:row;padding:0 10px 10px}@media(max-width:750px){.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-options-container{flex-direction:column}}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option{border:1px solid #ccc;flex:auto;margin:5px;padding:10px 10px 15px}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option:first-child{margin-left:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option:last-child{margin-right:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-resolution-option strong{font-size:1.2em;line-height:1.5em;padding:2px}.fs-notice[data-id^=clone_resolution_options_notice] a{text-decoration:none}.fs-notice[data-id^=clone_resolution_options_notice] .button{margin-right:10px}.rtl .fs-notice[data-id^=clone_resolution_options_notice] .button{margin-left:10px;margin-right:0}.fs-notice[data-id^=clone_resolution_options_notice] .fs-clone-documentation-container{padding:0 10px 15px}.fs-notice[data-id=temporary_duplicate_notice] #fs_clone_resolution_error_message{background:#fee;border:1px solid #d3135a;color:#d3135a;padding:10px}.fs-notice[data-id=temporary_duplicate_notice] ol{margin-top:0}.fs-notice[data-id=temporary_duplicate_notice] a{position:relative}.fs-notice[data-id=temporary_duplicate_notice] a:focus{box-shadow:none}.fs-notice[data-id=temporary_duplicate_notice] a.disabled{color:gray}.fs-notice[data-id=temporary_duplicate_notice] a .fs-ajax-spinner{bottom:0;left:8px;margin-left:100%;position:absolute;right:0;top:-1px} -------------------------------------------------------------------------------- /freemius/assets/css/admin/debug.css: -------------------------------------------------------------------------------- 1 | label.fs-tag,span.fs-tag{background:#ffba00;border-radius:3px;color:#fff;display:inline-block;font-size:11px;line-height:11px;padding:5px;vertical-align:baseline}label.fs-tag.fs-warn,span.fs-tag.fs-warn{background:#ffba00}label.fs-tag.fs-info,span.fs-tag.fs-info{background:#00a0d2}label.fs-tag.fs-success,span.fs-tag.fs-success{background:#46b450}label.fs-tag.fs-error,span.fs-tag.fs-error{background:#dc3232}.fs-switch-label{font-size:20px;line-height:31px;margin:0 5px}#fs_log_book table{font-family:Consolas,Monaco,monospace;font-size:12px}#fs_log_book table th{color:#ccc}#fs_log_book table tr{background:#232525}#fs_log_book table tr.alternate{background:#2b2b2b}#fs_log_book table tr td.fs-col--logger{color:#5a7435}#fs_log_book table tr td.fs-col--type{color:#ffc861}#fs_log_book table tr td.fs-col--function{color:#a7b7b1;font-weight:700}#fs_log_book table tr td.fs-col--message,#fs_log_book table tr td.fs-col--message a{color:#9a73ac!important}#fs_log_book table tr td.fs-col--file{color:#d07922}#fs_log_book table tr td.fs-col--timestamp{color:#6596be} -------------------------------------------------------------------------------- /freemius/assets/css/admin/gdpr-optin-notice.css: -------------------------------------------------------------------------------- 1 | .fs-notice[data-id^=gdpr_optin_actions] .underlined{text-decoration:underline}.fs-notice[data-id^=gdpr_optin_actions] ul .action-description,.fs-notice[data-id^=gdpr_optin_actions] ul .button{vertical-align:middle}.fs-notice[data-id^=gdpr_optin_actions] ul .action-description{display:inline-block;margin-left:3px} -------------------------------------------------------------------------------- /freemius/assets/css/admin/index.php: -------------------------------------------------------------------------------- 1 | ").attr({method:t,action:r}).css({display:"none"}),a=function(r,e){if(n.isArray(e))for(var t=0;t").attr({type:"hidden",name:String(r),value:String(e)}))};for(var i in e)e.hasOwnProperty(i)&&a(i,e[i]);return o.appendTo("body")}})}(jQuery); -------------------------------------------------------------------------------- /freemius/assets/js/nojquery.ba-postmessage.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery postMessage - v0.5 - 9/11/2009 3 | * http://benalman.com/projects/jquery-postmessage-plugin/ 4 | * 5 | * Copyright (c) 2009 "Cowboy" Ben Alman 6 | * Dual licensed under the MIT and GPL licenses. 7 | * http://benalman.com/about/license/ 8 | * 9 | * Non-jQuery fork by Jeff Lee 10 | * 11 | * This fork consists of the following changes: 12 | * 1. Basic code cleanup and restructuring, for legibility. 13 | * 2. The `postMessage` and `receiveMessage` functions can be bound arbitrarily, 14 | * in terms of both function names and object scope. Scope is specified by 15 | * the the "this" context of NoJQueryPostMessageMixin(); 16 | * 3. I've removed the check for Opera 9.64, which used `$.browser`. There were 17 | * at least three different GitHub users requesting the removal of this 18 | * "Opera sniff" on the original project's Issues page, so I figured this 19 | * would be a relatively safe change. 20 | * 4. `postMessage` no longer uses `$.param` to serialize messages that are not 21 | * strings. I actually prefer this structure anyway. `receiveMessage` does 22 | * not implement a corresponding deserialization step, and as such it seems 23 | * cleaner and more symmetric to leave both data serialization and 24 | * deserialization to the client. 25 | * 5. The use of `$.isFunction` is replaced by a functionally-identical check. 26 | * 6. The `$:nomunge` YUI option is no longer necessary. 27 | */ 28 | function NoJQueryPostMessageMixin(n,e){var t,i,o,s,a,r=1;return window.postMessage?(window.addEventListener?(t=function(n){window.addEventListener("message",n,!1)},i=function(n){window.removeEventListener("message",n,!1)}):(t=function(n){window.attachEvent("onmessage",n)},i=function(n){window.detachEvent("onmessage",n)}),this[n]=function(n,e,t){e&&t.postMessage(n,e.replace(/([^:]+:\/\/[^\/]+).*/,"$1"))},this[e]=function(n,e,s){if(o&&(i(o),o=null),!n)return!1;o=t((function(t){switch(Object.prototype.toString.call(e)){case"[object String]":if(e!==t.origin)return!1;break;case"[object Function]":if(e(t.origin))return!1}n(t)}))}):(this[n]=function(n,e,t){e&&(t.location=e.replace(/#.*$/,"")+"#"+ +new Date+r+++"&"+n)},this[e]=function(n,e,t){s&&(clearInterval(s),s=null),n&&(t="number"==typeof e?e:"number"==typeof t?t:100,s=setInterval((function(){var e=document.location.hash,t=/^#?\d+&/;e!==a&&t.test(e)&&(a=e,n({data:e.replace(t,"")}))}),t))}),this} -------------------------------------------------------------------------------- /freemius/assets/js/postmessage.js: -------------------------------------------------------------------------------- 1 | !function(e,t){var s,n,o,i,r,a,c,p,u=this;u.FS=u.FS||{},u.FS.PostMessage=(n=new NoJQueryPostMessageMixin("postMessage","receiveMessage"),o={},i=decodeURIComponent(document.location.hash.replace(/^#/,"")),r=i.substring(0,i.indexOf("/","https://"===i.substring(0,8)?8:7)),a=""!==i,c=e(window),p=e("html"),{init:function(e,t){s=e,n.receiveMessage((function(e){var t=JSON.parse(e.data);if(o[t.type])for(var s=0;s0&&c.on("scroll",(function(){for(var e=0;e 11 | * @license MIT 12 | */ 13 | 14 | /*! 15 | * Font Awesome Free 6.0.0 by @fontawesome - https://fontawesome.com 16 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 17 | * Copyright 2022 Fonticons, Inc. 18 | */ 19 | 20 | /** @license React v0.20.2 21 | * scheduler.production.min.js 22 | * 23 | * Copyright (c) Facebook, Inc. and its affiliates. 24 | * 25 | * This source code is licensed under the MIT license found in the 26 | * LICENSE file in the root directory of this source tree. 27 | */ 28 | 29 | /** @license React v17.0.2 30 | * react-dom.production.min.js 31 | * 32 | * Copyright (c) Facebook, Inc. and its affiliates. 33 | * 34 | * This source code is licensed under the MIT license found in the 35 | * LICENSE file in the root directory of this source tree. 36 | */ 37 | 38 | /** @license React v17.0.2 39 | * react.production.min.js 40 | * 41 | * Copyright (c) Facebook, Inc. and its affiliates. 42 | * 43 | * This source code is licensed under the MIT license found in the 44 | * LICENSE file in the root directory of this source tree. 45 | */ 46 | -------------------------------------------------------------------------------- /freemius/includes/class-fs-user-lock.php: -------------------------------------------------------------------------------- 1 | _lock = new FS_Lock( "locked_{$current_user_id}" ); 53 | } 54 | 55 | /** 56 | * Try to acquire lock. If the lock is already set or is being acquired by another locker, don't do anything. 57 | * 58 | * @author Vova Feldman (@svovaf) 59 | * @since 2.1.0 60 | * 61 | * @param int $expiration 62 | * 63 | * @return bool TRUE if successfully acquired lock. 64 | */ 65 | function try_lock( $expiration = 0 ) { 66 | return $this->_lock->try_lock( $expiration ); 67 | } 68 | 69 | /** 70 | * Acquire lock regardless if it's already acquired by another locker or not. 71 | * 72 | * @author Vova Feldman (@svovaf) 73 | * @since 2.1.0 74 | * 75 | * @param int $expiration 76 | */ 77 | function lock( $expiration = 0 ) { 78 | $this->_lock->lock( $expiration ); 79 | } 80 | 81 | /** 82 | * Unlock the lock. 83 | * 84 | * @author Vova Feldman (@svovaf) 85 | * @since 2.1.0 86 | */ 87 | function unlock() { 88 | $this->_lock->unlock(); 89 | } 90 | } -------------------------------------------------------------------------------- /freemius/includes/customizer/index.php: -------------------------------------------------------------------------------- 1 | title( 'Freemius' ); // @phpstan-ignore-line 27 | } 28 | 29 | public static function requests_count() { 30 | if ( class_exists( 'Freemius_Api_WordPress' ) ) { 31 | $logger = Freemius_Api_WordPress::GetLogger(); 32 | } else { 33 | $logger = array(); 34 | } 35 | 36 | return number_format( count( $logger ) ); 37 | } 38 | 39 | public static function total_time() { 40 | if ( class_exists( 'Freemius_Api_WordPress' ) ) { 41 | $logger = Freemius_Api_WordPress::GetLogger(); 42 | } else { 43 | $logger = array(); 44 | } 45 | 46 | $total_time = .0; 47 | foreach ( $logger as $l ) { 48 | $total_time += $l['total']; 49 | } 50 | 51 | return number_format( 100 * $total_time, 2 ) . ' ' . fs_text_x_inline( 'ms', 'milliseconds' ); 52 | } 53 | 54 | public function render() { 55 | ?> 56 |
    57 | 58 |
    59 | 60 |
    61 | 62 |
    63 | 64 |
    65 | status ); 47 | } 48 | 49 | /** 50 | * @author Leo Fajardo 51 | * 52 | * @return bool 53 | */ 54 | function is_pending() { 55 | return ( 'pending' === $this->status ); 56 | } 57 | 58 | /** 59 | * @author Leo Fajardo 60 | * 61 | * @return bool 62 | */ 63 | function is_suspended() { 64 | return ( 'suspended' === $this->status ); 65 | } 66 | 67 | /** 68 | * @author Leo Fajardo 69 | * 70 | * @return bool 71 | */ 72 | function is_rejected() { 73 | return ( 'rejected' === $this->status ); 74 | } 75 | 76 | /** 77 | * @author Leo Fajardo 78 | * 79 | * @return bool 80 | */ 81 | function is_blocked() { 82 | return ( 'blocked' === $this->status ); 83 | } 84 | } -------------------------------------------------------------------------------- /freemius/includes/entities/class-fs-billing.php: -------------------------------------------------------------------------------- 1 | release_mode ); 63 | } 64 | } -------------------------------------------------------------------------------- /freemius/includes/entities/class-fs-scope-entity.php: -------------------------------------------------------------------------------- 1 | is_beta ); 61 | } 62 | } 63 | 64 | function get_name() { 65 | return trim( ucfirst( trim( is_string( $this->first ) ? $this->first : '' ) ) . ' ' . ucfirst( trim( is_string( $this->last ) ? $this->last : '' ) ) ); 66 | } 67 | 68 | function is_verified() { 69 | return ( isset( $this->is_verified ) && true === $this->is_verified ); 70 | } 71 | 72 | /** 73 | * @author Leo Fajardo (@leorw) 74 | * @since 2.4.2 75 | * 76 | * @return bool 77 | */ 78 | function is_beta() { 79 | // Return `false` since this is just for backward compatibility. 80 | return false; 81 | } 82 | 83 | static function get_type() { 84 | return 'user'; 85 | } 86 | } -------------------------------------------------------------------------------- /freemius/includes/entities/index.php: -------------------------------------------------------------------------------- 1 | 44 | */ 45 | public function get_query_params( Freemius $fs ) { 46 | $context_params = array( 47 | 'plugin_id' => $fs->get_id(), 48 | 'plugin_public_key' => $fs->get_public_key(), 49 | 'plugin_version' => $fs->get_plugin_version(), 50 | ); 51 | 52 | // Get site context secure params. 53 | if ( $fs->is_registered() ) { 54 | $context_params = array_merge( $context_params, FS_Security::instance()->get_context_params( 55 | $fs->get_site(), 56 | time(), 57 | 'contact' 58 | ) ); 59 | } 60 | 61 | return array_merge( $_GET, array_merge( $context_params, array( 62 | 'plugin_version' => $fs->get_plugin_version(), 63 | 'wp_login_url' => wp_login_url(), 64 | 'site_url' => Freemius::get_unfiltered_site_url(), 65 | // 'wp_admin_css' => get_bloginfo('wpurl') . "/wp-admin/load-styles.php?c=1&load=buttons,wp-admin,dashicons", 66 | ) ) ); 67 | } 68 | 69 | /** 70 | * Retrieves the standalone link to the Freemius Contact Form. 71 | * 72 | * @param Freemius $fs 73 | * 74 | * @return string 75 | */ 76 | public function get_standalone_link( Freemius $fs ) { 77 | $query_params = $this->get_query_params( $fs ); 78 | 79 | $query_params['is_standalone'] = 'true'; 80 | $query_params['parent_url'] = admin_url( add_query_arg( null, null ) ); 81 | 82 | return WP_FS__ADDRESS . '/contact/?' . http_build_query( $query_params ); 83 | } 84 | } -------------------------------------------------------------------------------- /freemius/includes/managers/index.php: -------------------------------------------------------------------------------- 1 | _result = $result; 23 | 24 | $code = 0; 25 | $message = 'Unknown error, please check GetResult().'; 26 | $type = ''; 27 | 28 | if ( isset( $result['error'] ) && is_array( $result['error'] ) ) { 29 | if ( isset( $result['error']['code'] ) ) { 30 | $code = $result['error']['code']; 31 | } 32 | if ( isset( $result['error']['message'] ) ) { 33 | $message = $result['error']['message']; 34 | } 35 | if ( isset( $result['error']['type'] ) ) { 36 | $type = $result['error']['type']; 37 | } 38 | } 39 | 40 | $this->_type = $type; 41 | $this->_code = $code; 42 | 43 | parent::__construct( $message, is_numeric( $code ) ? $code : 0 ); 44 | } 45 | 46 | /** 47 | * Return the associated result object returned by the API server. 48 | * 49 | * @return array The result from the API server 50 | */ 51 | public function getResult() { 52 | return $this->_result; 53 | } 54 | 55 | public function getStringCode() { 56 | return $this->_code; 57 | } 58 | 59 | public function getType() { 60 | return $this->_type; 61 | } 62 | 63 | /** 64 | * To make debugging easier. 65 | * 66 | * @return string The string representation of the error 67 | */ 68 | public function __toString() { 69 | $str = $this->getType() . ': '; 70 | 71 | if ( $this->code != 0 ) { 72 | $str .= $this->getStringCode() . ': '; 73 | } 74 | 75 | return $str . $this->getMessage(); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /freemius/includes/sdk/Exceptions/InvalidArgumentException.php: -------------------------------------------------------------------------------- 1 | $data ) { 35 | if ( 0 === strpos( $file_real_path, fs_normalize_path( dirname( realpath( WP_PLUGIN_DIR . '/' . $relative_path ) ) . '/' ) ) ) { 36 | if ( '.' !== dirname( trailingslashit( $relative_path ) ) ) { 37 | return $relative_path; 38 | } 39 | } 40 | } 41 | 42 | return null; 43 | } 44 | -------------------------------------------------------------------------------- /freemius/includes/supplements/fs-essential-functions-2.2.1.php: -------------------------------------------------------------------------------- 1 | $install ) { 21 | if ( true === $install->is_disconnected ) { 22 | $permission_manager->update_site_tracking( 23 | false, 24 | ( 0 == $blog_id ) ? null : $blog_id, 25 | // Update only if permissions are not yet set. 26 | true 27 | ); 28 | } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /freemius/includes/supplements/index.php: -------------------------------------------------------------------------------- 1 | 35 |
    36 | 37 | 38 | 39 | 40 | 41 | 54 |
    -------------------------------------------------------------------------------- /freemius/templates/account/partials/deactivate-license-button.php: -------------------------------------------------------------------------------- 1 | 30 |
    31 | 32 | 33 | 34 | 35 | 36 |
    -------------------------------------------------------------------------------- /freemius/templates/account/partials/index.php: -------------------------------------------------------------------------------- 1 | get_slug(); 25 | 26 | ?> 27 |
    28 |
    29 |

    30 | 31 |
    32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | > 45 | 46 | 47 | 48 | 51 | 52 | 53 | 54 |
    id ?>created ) ) ?>formatted_gross() ?>is_migrated() ) : ?>
    55 |
    56 |
    57 |
    58 | 21 | -------------------------------------------------------------------------------- /freemius/templates/ajax-loader.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /freemius/templates/api-connectivity-message-js.php: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /freemius/templates/checkout.php: -------------------------------------------------------------------------------- 1 | is_premium() ) { 23 | fs_require_template( 'checkout/frame.php', $VARS ); 24 | } else { 25 | fs_require_template( 'checkout/redirect.php', $VARS ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /freemius/templates/connect/index.php: -------------------------------------------------------------------------------- 1 | 29 |
  • 31 | 32 | 33 |
    34 |
    35 |
    36 | 37 | 38 |
    39 | class="fs-tooltip-trigger"> 40 | 41 |

    42 |
    43 |
  • -------------------------------------------------------------------------------- /freemius/templates/debug/index.php: -------------------------------------------------------------------------------- 1 | 15 |

    16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | 39 | > 42 | 43 | 44 | 45 | 46 | 57 | 62 | 63 | 64 | 65 | 66 |
    #
    .get_id() ?> 47 | %s', 50 | esc_html( substr( $log['msg'], 0, 32 ) ) . ( 32 < strlen( $log['msg'] ) ? '...' : '' ) 51 | ); 52 | ?> 53 |
    54 | 55 |
    56 |
    get_file() ) . ':' . $log['line']; 60 | } 61 | ?>
    -------------------------------------------------------------------------------- /freemius/templates/email.php: -------------------------------------------------------------------------------- 1 | 18 | 19 | $section ) { 21 | ?> 22 | 23 | 24 | 25 | 26 | $row ) { 28 | $col_count = count( $row ); 29 | ?> 30 | 31 | 33 | 34 | 36 | 37 | 38 | 41 | 42 | 45 | 46 | 49 |
    :
    -------------------------------------------------------------------------------- /freemius/templates/forms/deactivation/contact.php: -------------------------------------------------------------------------------- 1 | get_slug(); 18 | 19 | echo fs_text_inline( 'Sorry for the inconvenience and we are here to help if you give us a chance.', 'contact-support-before-deactivation', $slug ) 20 | . sprintf(" %s", 21 | $fs->contact_url( 'technical_support' ), 22 | fs_text_inline( 'Contact Support', 'contact-support', $slug ) 23 | ); 24 | -------------------------------------------------------------------------------- /freemius/templates/forms/deactivation/index.php: -------------------------------------------------------------------------------- 1 | get_slug(); 18 | 19 | $skip_url = fs_nonce_url( $fs->_get_admin_page_url( '', array( 'fs_action' => $fs->get_unique_affix() . '_skip_activation' ) ), $fs->get_unique_affix() . '_skip_activation' ); 20 | $skip_text = strtolower( fs_text_x_inline( 'Skip', 'verb', 'skip', $slug ) ); 21 | $use_plugin_anonymously_text = fs_text_inline( 'Click here to use the plugin anonymously', 'click-here-to-use-plugin-anonymously', $slug ); 22 | 23 | echo sprintf( fs_text_inline( "You might have missed it, but you don't have to share any data and can just %s the opt-in.", 'dont-have-to-share-any-data', $slug ), "{$skip_text}" ) 24 | . " {$use_plugin_anonymously_text}"; -------------------------------------------------------------------------------- /freemius/templates/forms/index.php: -------------------------------------------------------------------------------- 1 | _get_license(); 19 | 20 | if ( ! is_object( $license ) ) { 21 | $purchase_url = $fs->pricing_url(); 22 | } else { 23 | $subscription = $fs->_get_subscription( $license->id ); 24 | 25 | $purchase_url = $fs->checkout_url( 26 | is_object( $subscription ) ? 27 | ( 1 == $subscription->billing_cycle ? WP_FS__PERIOD_MONTHLY : WP_FS__PERIOD_ANNUALLY ) : 28 | WP_FS__PERIOD_LIFETIME, 29 | false, 30 | array( 'licenses' => $license->quota ) 31 | ); 32 | } 33 | 34 | $plugin_data = $fs->get_plugin_data(); 35 | ?> 36 | -------------------------------------------------------------------------------- /freemius/templates/index.php: -------------------------------------------------------------------------------- 1 | 12 | -------------------------------------------------------------------------------- /freemius/templates/js/open-license-activation.php: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /freemius/templates/js/style-premium-theme.php: -------------------------------------------------------------------------------- 1 | get_slug(); 21 | 22 | ?> 23 | -------------------------------------------------------------------------------- /freemius/templates/partials/index.php: -------------------------------------------------------------------------------- 1 | 20 |
    21 | 22 |
    -------------------------------------------------------------------------------- /freemius/templates/plugin-info/description.php: -------------------------------------------------------------------------------- 1 | info->selling_point_0 ) || 21 | ! empty( $plugin->info->selling_point_1 ) || 22 | ! empty( $plugin->info->selling_point_2 ) 23 | ) : ?> 24 |
    25 |
      26 | 27 | info->{'selling_point_' . $i} ) ) : ?> 28 |
    • 29 | 30 |

      info->{'selling_point_' . $i} ) ?>

    • 31 | 32 | 33 |
    34 |
    35 | 36 |
    37 | info->description, array( 39 | 'a' => array( 'href' => array(), 'title' => array(), 'target' => array() ), 40 | 'b' => array(), 41 | 'i' => array(), 42 | 'p' => array(), 43 | 'blockquote' => array(), 44 | 'h2' => array(), 45 | 'h3' => array(), 46 | 'ul' => array(), 47 | 'ol' => array(), 48 | 'li' => array() 49 | ) ); 50 | ?> 51 |
    52 | info->screenshots ) ) : ?> 53 | info->screenshots ?> 54 |
    55 |

    slug ) ?>

    56 |
      57 | $url ) : ?> 59 |
    • 60 | 66 | 69 |
    • 70 | 71 |
    72 |
    73 | -------------------------------------------------------------------------------- /freemius/templates/plugin-info/index.php: -------------------------------------------------------------------------------- 1 | 22 |
      23 | $url ) : ?> 25 |
    1. 26 | 27 |
    2. 28 | 29 |
    30 | -------------------------------------------------------------------------------- /freemius/templates/secure-https-header.php: -------------------------------------------------------------------------------- 1 | 15 |
    16 | 17 | get_text_inline( 'Secure HTTPS %s page, running from an external domain', 'secure-x-page-header' ), 29 | $VARS['page'] 30 | ) ) . 31 | ' - ' . 32 | sprintf( 33 | '%s', 34 | 'https://www.mcafeesecure.com/verify?host=' . WP_FS__ROOT_DOMAIN_PRODUCTION, 35 | 'Freemius Inc. [US]' 36 | ); 37 | } 38 | ?> 39 |
    -------------------------------------------------------------------------------- /freemius/templates/sticky-admin-notice-js.php: -------------------------------------------------------------------------------- 1 | 16 | 41 | -------------------------------------------------------------------------------- /freemius/templates/tabs-capture-js.php: -------------------------------------------------------------------------------- 1 | get_slug(); 19 | ?> 20 | -------------------------------------------------------------------------------- /inc/Consumer.php: -------------------------------------------------------------------------------- 1 | parent_base; 39 | 40 | if ( $is_analog_screen ) { 41 | $text = sprintf( 42 | /* translators: 1: Style Kits for Elementor, 2: Link to plugin review */ 43 | __( 'Enjoyed %1$s? Please leave us a %2$s rating. We really appreciate your support!', 'ang' ), 44 | '' . __( 'Style Kits for Elementor', 'ang' ) . '', 45 | '★★★★★' 46 | ); 47 | } 48 | 49 | return $text; 50 | } 51 | 52 | /** 53 | * Plugin row meta. 54 | * 55 | * Adds row meta links to the plugin list table. 56 | * 57 | * @param array $plugin_meta An array of the plugin's metadata, including the version, author, author URI, and plugin URI. 58 | * @param string $plugin_file Path to the plugin file, relative to the plugins directory. 59 | * 60 | * @return array An array of modified plugin row meta links. 61 | */ 62 | public function plugin_row_meta( $plugin_meta, $plugin_file ) { 63 | if ( ANG_PLUGIN_BASE === $plugin_file ) { 64 | $row_meta = array( 65 | 'ang_docs' => '' . __( 'Documentation', 'ang' ) . '', 66 | 'ang_support' => '' . __( 'Get Support', 'ang' ) . '', 67 | ); 68 | 69 | $plugin_meta = array_merge( $plugin_meta, $row_meta ); 70 | } 71 | 72 | return $plugin_meta; 73 | } 74 | } 75 | 76 | new Admin(); 77 | -------------------------------------------------------------------------------- /inc/class-analog-importer.php: -------------------------------------------------------------------------------- 1 | get_template_content( $args['template_id'], $args['license'], $args['method'], $args['site_id'] ); 47 | } 48 | 49 | if ( is_wp_error( $data ) ) { 50 | return $data; 51 | } 52 | 53 | Plugin::elementor()->editor->set_edit_mode( true ); 54 | 55 | // Remove Typography options if opted in. 56 | if ( isset( $args['options']['remove_typography'] ) && true === $args['options']['remove_typography'] ) { 57 | require_once ANG_PLUGIN_DIR . 'inc/class-formatter.php'; 58 | $data['content'] = Formatter::remove_typography_data_recursive( $data['content'] ); 59 | } 60 | 61 | $data['content'] = $this->replace_elements_ids( $data['content'] ); 62 | $data['content'] = $this->process_export_import_content( $data['content'], 'on_import' ); 63 | 64 | $post_id = $args['editor_post_id']; 65 | $document = Plugin::elementor()->documents->get( $post_id ); 66 | if ( $document ) { 67 | $data['content'] = $document->get_elements_raw_data( $data['content'], true ); 68 | } 69 | 70 | /** 71 | * During json encode/decode between preview/demo, isInner is usually converted into string. 72 | * This helper function converts it back to Boolean so Elementor doesn't changes this control 73 | * into an "Inner Section". 74 | * 75 | * @since 1.3.8 76 | */ 77 | $data['content'] = Utils::convert_string_to_boolean( $data['content'] ); 78 | 79 | return $data; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /inc/class-cron.php: -------------------------------------------------------------------------------- 1 | WEEK_IN_SECONDS, 41 | 'display' => __( 'Once Weekly', 'ang' ), 42 | ); 43 | 44 | return $schedules; 45 | } 46 | 47 | /** 48 | * Schedules our events 49 | * 50 | * @since 1.1 51 | * @return void 52 | */ 53 | public function schedule_events() { 54 | $this->weekly_events(); 55 | } 56 | 57 | /** 58 | * Schedule weekly events 59 | * 60 | * @access private 61 | * @since 1.1 62 | * @return void 63 | */ 64 | private function weekly_events() { 65 | if ( ! wp_next_scheduled( 'analog/tracker/send_event' ) ) { 66 | wp_schedule_event( time(), 'weekly', 'analog/tracker/send_event' ); 67 | } 68 | } 69 | } 70 | 71 | 72 | new Cron(); 73 | -------------------------------------------------------------------------------- /inc/class-formatter.php: -------------------------------------------------------------------------------- 1 | $value ) { 86 | if ( is_array( $haystack ) ) { 87 | $haystack[ $k ] = self::remove_typography_data_recursive( $value ); 88 | } 89 | } 90 | } 91 | return $haystack; 92 | } 93 | } 94 | 95 | new Formatter(); 96 | -------------------------------------------------------------------------------- /inc/class-options.php: -------------------------------------------------------------------------------- 1 | get(); 59 | $options[ $key ] = $value; 60 | update_option( self::OPTION_KEY, $options ); 61 | } 62 | 63 | /** 64 | * Delete a single option. 65 | * 66 | * @param string $key Option key. 67 | * @return void 68 | */ 69 | public function delete( $key ) { 70 | $options = $this->get(); 71 | if ( ! isset( $options[ $key ] ) ) { 72 | return; 73 | } 74 | 75 | unset( $options[ $key ] ); 76 | update_option( self::OPTION_KEY, $options ); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /inc/cli/commands.php: -------------------------------------------------------------------------------- 1 | convert_all_sk_to_kits(); 19 | 20 | WP_CLI::success( 'All Style Kits have been migrated. 🎉' ); 21 | } 22 | 23 | function style_kits_list() { 24 | $posts = \get_posts( 25 | array( 26 | 'post_type' => 'ang_tokens', 27 | 'posts_per_page' => -1, 28 | ) 29 | ); 30 | 31 | WP_CLI\Utils\format_items( 'table', $posts, array( 'ID', 'post_title' ) ); 32 | } 33 | 34 | function kits_list() { 35 | $posts = \get_posts( 36 | array( 37 | 'post_type' => Source_Local::CPT, 38 | 'post_status' => array( 'publish', 'draft' ), 39 | 'posts_per_page' => -1, 40 | 'orderby' => 'title', 41 | 'order' => 'DESC', 42 | 'meta_query' => array( // @codingStandardsIgnoreLine 43 | array( 44 | 'key' => \Elementor\Core\Base\Document::TYPE_META_KEY, 45 | 'value' => 'kit', 46 | ), 47 | ), 48 | ) 49 | ); 50 | 51 | WP_CLI\Utils\format_items( 'table', $posts, array( 'ID', 'post_title' ) ); 52 | } 53 | 54 | function refresh_library() { 55 | delete_transient( 'analogwp_template_info' ); 56 | 57 | WP_CLI::success( 'Refresh Style Kit remote library.' ); 58 | } 59 | -------------------------------------------------------------------------------- /inc/elementor/Google_Fonts.php: -------------------------------------------------------------------------------- 1 | 20 ) ); 37 | 38 | if ( ! is_wp_error( $request ) ) { 39 | $body = wp_remote_retrieve_body( $request ); 40 | if ( ! empty( $body ) ) { 41 | set_transient( self::TRANSIENT, $body, DAY_IN_SECONDS ); 42 | } 43 | } 44 | } 45 | } 46 | 47 | /** 48 | * Iterate through our Google fonts library and add it to Elementor. 49 | * 50 | * @param array $additional_fonts Google fonts list. 51 | * 52 | * @since 1.8.0 53 | * @return array|mixed 54 | */ 55 | public function add_fonts_to_elementor( $additional_fonts ) { 56 | $fonts = get_transient( self::TRANSIENT ); 57 | 58 | if ( $fonts ) { 59 | $fonts = json_decode( $fonts, true ); 60 | if ( is_array( $fonts ) && count( $fonts ) ) { 61 | $formatted_fonts = array(); 62 | 63 | foreach ( $fonts as $font ) { 64 | $formatted_fonts[ $font ] = 'googlefonts'; 65 | } 66 | 67 | $additional_fonts = array_merge( $additional_fonts, $formatted_fonts ); 68 | } 69 | } 70 | 71 | return $additional_fonts; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /inc/elementor/Reset_Default_Style_Trait.php: -------------------------------------------------------------------------------- 1 | update_control( $control_id, array( 'default' => $default ) ); 34 | } 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /inc/elementor/class-finder-shortcuts.php: -------------------------------------------------------------------------------- 1 | array( 47 | 'title' => __( 'Templates Library', 'ang' ), 48 | 'url' => admin_url( 'admin.php?page=analogwp_templates' ), 49 | 'icon' => 'library-download', 50 | 'keywords' => array( 'analog', 'library', 'settings' ), 51 | ), 52 | 'settings' => array( 53 | 'title' => __( 'Settings', 'ang' ), 54 | 'url' => admin_url( 'admin.php?page=ang-settings' ), 55 | 'icon' => 'settings', 56 | 'keywords' => array( 'analog', 'settings' ), 57 | ), 58 | 'style-kits' => array( 59 | 'title' => __( 'Theme Style Kits', 'ang' ), 60 | 'url' => admin_url( 'admin.php?page=style-kits' ), 61 | 'icon' => 'settings', 62 | 'keywords' => array( 'analog', 'style', 'kits' ), 63 | ), 64 | ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /inc/elementor/class-post-type.php: -------------------------------------------------------------------------------- 1 | __( 'Style Kits', 'ang' ), 33 | 'singular_name' => __( 'Style Kit', 'ang' ), 34 | 'menu_name' => _x( 'Style Kits', 'admin menu', 'ang' ), 35 | 'name_admin_bar' => _x( 'Style Kit', 'add new on admin bar', 'ang' ), 36 | 'add_new' => _x( 'Add New', 'book', 'ang' ), 37 | 'add_new_item' => __( 'Add New Style Kit', 'ang' ), 38 | 'new_item' => __( 'New Style Kit', 'ang' ), 39 | 'edit_item' => __( 'Edit Style Kit', 'ang' ), 40 | 'view_item' => __( 'View Style Kit', 'ang' ), 41 | 'all_items' => __( 'Style Kits', 'ang' ), 42 | 'search_items' => __( 'Search Style Kits', 'ang' ), 43 | 'parent_item_colon' => __( 'Parent Style Kits:', 'ang' ), 44 | 'not_found' => __( 'No Style Kit found.', 'ang' ), 45 | 'not_found_in_trash' => __( 'No Style Kit found in Trash.', 'ang' ), 46 | ); 47 | } 48 | 49 | /** 50 | * Register post type. 51 | * 52 | * @return void 53 | */ 54 | public function register() { 55 | $args = array( 56 | 'labels' => $this->labels(), 57 | 'hierarchical' => false, 58 | 'show_ui' => apply_filters( 'analog_tokens_visibility', true ), 59 | 'show_in_menu' => false, 60 | 'show_in_nav_menus' => false, 61 | 'show_in_admin_bar' => false, 62 | 'show_admin_column' => false, 63 | 'rewrite' => false, 64 | 'public' => false, 65 | 'supports' => array( 66 | 'title', 67 | 'author', 68 | 'thumbnail', 69 | 'custom-fields', 70 | ), 71 | 'capabilities' => array( 72 | 'create_posts' => 'do_not_allow', 73 | ), 74 | 'map_meta_cap' => true, 75 | ); 76 | 77 | $args = apply_filters( 'analog/elementor/cpt/tokens/args', $args, $this->labels() ); 78 | 79 | register_post_type( self::CPT, $args ); 80 | } 81 | } 82 | 83 | new Post_Type(); 84 | -------------------------------------------------------------------------------- /inc/elementor/globals/class-controller.php: -------------------------------------------------------------------------------- 1 | register_endpoint( new Colors( $this ) ); 15 | $this->register_endpoint( new Typography( $this ) ); 16 | } 17 | 18 | public function get_collection_params() { 19 | // Does not have 'get_items' args (OPTIONS). 20 | // Maybe TODO: try `$this->get_index_endpoint()->get_collection_params()`. 21 | return []; 22 | } 23 | 24 | public function get_permission_callback( $request ) { 25 | // Allow internal get global values. (e.g render global.css for a visitor) 26 | if ( 'GET' === $request->get_method() && Plugin::elementor()->data_manager_v2->is_internal() ) { 27 | return true; 28 | } 29 | 30 | return current_user_can( 'edit_posts' ); 31 | } 32 | 33 | protected function register_index_endpoint() { 34 | $this->register_endpoint( new Endpoint\Index\AllChildren( $this ) ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /inc/elementor/js/ang-cpt-tools.js: -------------------------------------------------------------------------------- 1 | jQuery( document ).ready( function( $ ) { 2 | const ANGTools = function() { 3 | /** 4 | * Hold reusable elements. 5 | * 6 | * @type {Object} 7 | */ 8 | const cache = {}; 9 | 10 | function init() { 11 | cacheElements(); 12 | 13 | initStyleKitImport(); 14 | } 15 | 16 | function cacheElements() { 17 | cache.$body = $( 'body' ); 18 | cache.$importButton = $( '#analog-import-template-trigger' ); 19 | cache.$importArea = $( '#analog-import-template-area' ); 20 | } 21 | 22 | function initStyleKitImport() { 23 | if ( ! cache.$body.hasClass( 'post-type-ang_tokens' ) ) { 24 | return; 25 | } 26 | 27 | cache.$formAnchor = $( 'h1.wp-heading-inline' ); 28 | cache.$formAnchor.after( cache.$importArea ).after( cache.$importButton ); 29 | 30 | cache.$importButton.on( 'click', () => cache.$importArea.toggle() ); 31 | 32 | cache.$importArea.find( 'input[type=submit]' ).attr( 'disabled', true ); 33 | 34 | cache.$importArea.find( 'input[type=file]' ).on( 'change', function() { 35 | cache.$importArea.find( 'input[type=submit]' ).removeAttr( 'disabled' ); 36 | } ); 37 | } 38 | 39 | init(); 40 | }; 41 | 42 | new ANGTools(); 43 | } ); 44 | -------------------------------------------------------------------------------- /inc/elementor/js/ang-typography.js: -------------------------------------------------------------------------------- 1 | /* global elementor, ANG_Action, $e, analog */ 2 | jQuery( document ).ready( function() { 3 | function handleFonts( font ) { 4 | elementor.helpers.enqueueFont( font ); 5 | } 6 | 7 | const pageSettings = elementor.settings.page.model.attributes; 8 | _.map( pageSettings, function( value, key ) { 9 | if ( key.startsWith( 'ang_' ) && key.endsWith( '_font_family' ) ) { 10 | elementor.settings.page.addChangeCallback( key, handleFonts ); 11 | } 12 | } ); 13 | 14 | elementor.on( 'preview:loaded', () => { 15 | const settings = elementor.settings.page.model.attributes; 16 | _.map( settings, function( value, key ) { 17 | if ( key.startsWith( 'ang_' ) && key.endsWith( '_font_family' ) ) { 18 | if ( value ) { 19 | elementor.helpers.enqueueFont( value ); 20 | } 21 | } 22 | } ); 23 | } ); 24 | 25 | function addPageStyleSettings( groups ) { 26 | const actions = [ 27 | { 28 | name: 'page_styles', 29 | title: ANG_Action.translate.pageStyles, 30 | callback: function() { 31 | analog.redirectToSection(); 32 | }, 33 | }, 34 | { 35 | name: 'theme_style', 36 | title: elementor.translate( 'Theme Style' ), 37 | callback: analog.openThemeStyles, 38 | }, 39 | { 40 | name: 'global_colors', 41 | title: elementor.translate( 'Edit Style Kit Colors' ), 42 | callback: analog.openGlobalColors, 43 | }, 44 | { 45 | name: 'global_fonts', 46 | title: elementor.translate( 'Edit Style Kit Fonts' ), 47 | callback: analog.openGlobalFonts, 48 | }, 49 | ]; 50 | 51 | const PageStyles = { 52 | name: 'ang_styles', 53 | actions: actions, 54 | }; 55 | 56 | groups.splice( 3, 0, PageStyles ); 57 | groups.join(); 58 | 59 | return groups; 60 | } 61 | 62 | if ( ANG_Action.skPanelsAllowed && elementor.config.initial_document.panel.support_kit ) { 63 | elementor.hooks.addFilter( 'elements/widget/contextMenuGroups', addPageStyleSettings ); 64 | elementor.hooks.addFilter( 'elements/section/contextMenuGroups', addPageStyleSettings ); 65 | elementor.hooks.addFilter( 'elements/column/contextMenuGroups', addPageStyleSettings ); 66 | } 67 | } ); 68 | -------------------------------------------------------------------------------- /inc/elementor/kit/tabs/Theme_Style_Kits.php: -------------------------------------------------------------------------------- 1 | get_id(), $this->get_title() ); 29 | } 30 | 31 | /** 32 | * Tab ID. 33 | * 34 | * @return string 35 | */ 36 | public function get_id() { 37 | return 'theme-style-kits'; 38 | } 39 | 40 | /** 41 | * Tab title. 42 | * 43 | * @return string|void 44 | */ 45 | public function get_title() { 46 | return __( 'Style Kits', 'ang' ); 47 | } 48 | 49 | /** 50 | * Tab Group. 51 | * 52 | * @return string 53 | */ 54 | public function get_group() { 55 | return 'theme-style'; 56 | } 57 | 58 | /** 59 | * Tab icon. 60 | * 61 | * @return string 62 | */ 63 | public function get_icon() { 64 | return 'eicon-global-settings'; 65 | } 66 | 67 | /** 68 | * Tab help URL. 69 | * 70 | * @return string 71 | */ 72 | public function get_help_url() { 73 | return 'https://analogwp.com/docs/'; 74 | } 75 | 76 | /** 77 | * Tab controls. 78 | * 79 | * Tab controls are hooked mostly on `elementor/element/kit/section_buttons/after_section_end`. 80 | */ 81 | protected function register_tab_controls() {} 82 | } 83 | 84 | new Theme_Style_Kits( Kit::class ); 85 | 86 | /** 87 | * Fires on tabs registering. 88 | */ 89 | add_action( 90 | 'elementor/kit/register_tabs', 91 | function( $kit ) { 92 | $kit->register_tab( 'theme-style-kits', Theme_Style_Kits::class ); 93 | } 94 | ); 95 | -------------------------------------------------------------------------------- /inc/elementor/kit/views/trash-kit-confirmation.php: -------------------------------------------------------------------------------- 1 | 'ang_trash_kit', 13 | 'kit_id' => $post_id, 14 | 'ang_trash_kit_nonce' => wp_create_nonce( 'ang_trash_kit' ), 15 | '_wp_http_referrer' => '/wp-admin/admin.php?page=style-kits', 16 | 'force_delete_kit' => '1', 17 | ), 18 | get_admin_url() . 'admin-ajax.php', 19 | ); 20 | ?> 21 |

    22 | 23 |

    24 | 25 |

    26 | 27 |

    28 | 29 |
    30 | 31 | 32 | 33 | 34 | 35 | 41 | 42 | 43 | 76 | -------------------------------------------------------------------------------- /inc/elementor/tags/class-dark-background.php: -------------------------------------------------------------------------------- 1 | editor->is_edit_mode() ) { 39 | $post_id = Plugin::elementor()->editor->get_post_id(); 40 | } else { 41 | $post_id = get_the_ID(); 42 | } 43 | 44 | return $post_id; 45 | } 46 | 47 | /** 48 | * Get Elementor document type. 49 | * 50 | * @return mixed 51 | */ 52 | public function get_document_type() { 53 | $document = Plugin::elementor()->documents->get_doc_or_auto_save( $this->get_post_id() ); 54 | if ( $document ) { 55 | $config = $document->get_config(); 56 | 57 | return $config['type']; 58 | } 59 | 60 | return false; 61 | } 62 | 63 | /** 64 | * Get a specific Elementor page setting. 65 | * 66 | * @param string $id Setting ID. 67 | * 68 | * @return mixed 69 | */ 70 | public function get_page_setting( $id ) { 71 | $page_settings_manager = Manager::get_settings_managers( 'page' ); 72 | $page_settings_model = $page_settings_manager->get_model( $this->get_post_id() ); 73 | 74 | return $page_settings_model->get_settings( $id ); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /inc/settings-helpers.php: -------------------------------------------------------------------------------- 1 | get( $key ) ); 91 | 92 | Utils::set_elementor_active_kit( $kit_id ); 93 | } 94 | add_action( 'ang_update_option', __NAMESPACE__ . '\ang_update_elementor_kit' ); 95 | -------------------------------------------------------------------------------- /inc/settings/class-settings-experiments.php: -------------------------------------------------------------------------------- 1 | id = 'experiments'; 23 | $this->label = __( 'Experiments', 'ang' ); 24 | parent::__construct(); 25 | 26 | } 27 | 28 | /** 29 | * Get settings array. 30 | * 31 | * @return array 32 | */ 33 | public function get_settings() { 34 | 35 | $options = array( 36 | 'default' => __( 'Default', 'ang' ), 37 | 'active' => __( 'Active', 'ang' ), 38 | 'inactive' => __( 'Inactive', 'ang' ), 39 | ); 40 | 41 | $settings = apply_filters( 42 | 'ang_experiments_settings', 43 | array( 44 | array( 45 | 'title' => __( 'Style Kits Experiments', 'ang' ), 46 | 'desc' => sprintf( 47 | /* translators: %s: Style Kits Experiments Documentation link */ 48 | __( 'Below you can activate experimental features for Style Kits and Style Kits Pro. We suggest you to turn on backups while using these experiments. %s about how this works.', 'ang' ), 49 | '' . __( 'Learn more', 'ang' ) . '' 50 | ), 51 | 'type' => 'title', 52 | 'id' => 'ang_experiments', 53 | ), 54 | array( 55 | 'title' => __( 'Container-based Library', 'ang' ), 56 | 'desc' => __( 'Get access to the container-based library of Patterns. You need to have the Containers Feature activated in Elementor, to test the new library.', 'ang' ), 57 | 'id' => 'container_library_experiment', 58 | 'default' => 'default', 59 | 'type' => 'select', 60 | 'options' => $options, 61 | ), 62 | array( 63 | 'type' => 'sectionend', 64 | 'id' => 'ang_beta', 65 | ), 66 | ) 67 | ); 68 | 69 | return apply_filters( 'ang_get_settings_' . $this->id, $settings ); 70 | } 71 | 72 | /** 73 | * Output the settings. 74 | */ 75 | public function output() { 76 | $settings = $this->get_settings(); 77 | 78 | Admin_Settings::output_fields( $settings ); 79 | } 80 | 81 | /** 82 | * Save settings. 83 | */ 84 | public function save() { 85 | $settings = $this->get_settings(); 86 | 87 | Admin_Settings::save_fields( $settings ); 88 | } 89 | } 90 | 91 | return new Experiments(); 92 | -------------------------------------------------------------------------------- /inc/settings/class-settings-extensions.php: -------------------------------------------------------------------------------- 1 | id = 'extensions'; 25 | $this->label = __( 'Extensions', 'ang' ); 26 | 27 | parent::__construct(); 28 | } 29 | 30 | /** 31 | * Get sections. 32 | * 33 | * @return array 34 | */ 35 | public function get_sections() { 36 | return apply_filters( 'ang_get_sections_' . $this->id, array() ); 37 | } 38 | 39 | /** 40 | * Get settings array. 41 | * 42 | * @param string $current_section Current section id. 43 | * @return array 44 | */ 45 | public function get_settings( $current_section = '' ) { 46 | global $current_section; 47 | $sections = $this->get_sections(); 48 | 49 | if ( ! empty( $sections ) && empty( $current_section ) ) { 50 | $current_section = array_keys( $sections )[0]; 51 | } 52 | 53 | $settings = array(); 54 | if ( '' === $current_section ) { 55 | $settings = apply_filters( 56 | 'ang_general_extension_settings', 57 | array() 58 | ); 59 | } 60 | 61 | return apply_filters( 'ang_get_settings_extensions', $settings, $current_section ); 62 | } 63 | 64 | /** 65 | * Output the settings. 66 | */ 67 | public function output() { 68 | global $current_section; 69 | 70 | $settings = $this->get_settings( $current_section ); 71 | 72 | Admin_Settings::output_fields( $settings ); 73 | } 74 | 75 | /** 76 | * Save settings. 77 | */ 78 | public function save() { 79 | global $current_section; 80 | 81 | $settings = $this->get_settings( $current_section ); 82 | 83 | Admin_Settings::save_fields( $settings ); 84 | if ( $current_section ) { 85 | do_action( 'ang_update_options_' . $this->id . '_' . $current_section ); 86 | } 87 | } 88 | } 89 | 90 | return new Extensions(); 91 | -------------------------------------------------------------------------------- /inc/settings/class-settings-gopro.php: -------------------------------------------------------------------------------- 1 | id = 'gopro'; 27 | $this->label = __( 'Style Kits Pro', 'ang' ); 28 | parent::__construct(); 29 | 30 | add_action( 'ang_settings_' . $this->id, array( $this, 'get_pro' ) ); 31 | } 32 | 33 | /** 34 | * Get settings array. 35 | * 36 | * @return array 37 | */ 38 | public function get_settings() { 39 | $settings = apply_filters( 40 | 'ang_gopro_settings', 41 | array() 42 | ); 43 | 44 | return apply_filters( 'ang_get_settings_' . $this->id, $settings ); 45 | } 46 | 47 | /** 48 | * Get Pro Tab Data. 49 | */ 50 | public function get_pro() { 51 | include dirname( __FILE__ ) . '/views/html-admin-settings-gopro.php'; 52 | } 53 | 54 | /** 55 | * Output the settings. 56 | */ 57 | public function output() { 58 | $settings = $this->get_settings(); 59 | 60 | Admin_Settings::output_fields( $settings ); 61 | } 62 | 63 | /** 64 | * Save settings. 65 | */ 66 | public function save() { 67 | $settings = $this->get_settings(); 68 | 69 | Admin_Settings::save_fields( $settings ); 70 | } 71 | } 72 | 73 | return new GoPro(); 74 | -------------------------------------------------------------------------------- /inc/settings/views/html-admin-settings-gopro.php: -------------------------------------------------------------------------------- 1 | 12 | 13 |
    14 |

    15 |

    Excited with the free version of Style Kits? Try out Style Kits PRO and optimise your Elementor design workflow with more features:

    16 |
      17 |
    • 18 |
    • 19 |
    • 20 |
    • 21 |
    • 22 |
    • 23 |
    • 24 |
    25 |

    26 | 27 |
    28 | 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "analogwp-templates", 3 | "version": "2.3.4", 4 | "description": "Handfully crafted Elementor templates packs.", 5 | "main": "/client/index.js", 6 | "private": true, 7 | "scripts": { 8 | "install-scripts": "composer install && npm install", 9 | "build-app": "wp-scripts build --webpack-src-dir=client --output-path=assets/js/app", 10 | "dev-app": "wp-scripts start --webpack-src-dir=client --output-path=assets/js/app", 11 | "makePot": "wp i18n make-pot . ./languages/ang.pot", 12 | "convertPot2json": "npx po2json ./languages/ang.pot ./languages/ang-analogwp-app.json -f jed1.x", 13 | "build": "gulp build", 14 | "gh:release": "gulp github-build" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/analogwp/analogwp-templates.git" 19 | }, 20 | "author": "AnalogWP", 21 | "license": "GPL", 22 | "bugs": { 23 | "url": "https://github.com/analogwp/analogwp-templates/issues" 24 | }, 25 | "homepage": "https://github.com/analogwp/analogwp-templates#readme", 26 | "dependencies": { 27 | "classnames": "^2.2.6", 28 | "react-masonry-css": "^1.0.14", 29 | "react-select": "^5.8.2", 30 | "react-waypoint": "^10.3.0", 31 | "regenerator-runtime": "^0.14.1", 32 | "styled-components": "^4.1.3" 33 | }, 34 | "devDependencies": { 35 | "@babel/plugin-proposal-class-properties": "^7.5.5", 36 | "@babel/preset-env": "^7.6.3", 37 | "@babel/preset-react": "^7.6.3", 38 | "@wordpress/scripts": "^30.4.0", 39 | "babel-core": "^6.26.3", 40 | "babel-eslint": "^10.0.3", 41 | "babel-loader": "^8.0.6", 42 | "del": "^5.1.0", 43 | "gulp": "^5.0.0", 44 | "gulp-babel": "8.0.0", 45 | "gulp-checktextdomain": "^2.3.0", 46 | "gulp-copy": "^4.0.1", 47 | "gulp-rename": "^1.4.0", 48 | "gulp-rsync": "^0.0.8", 49 | "gulp-run-command": "^0.0.10", 50 | "gulp-uglify": "^3.0.2", 51 | "gulp-zip": "^5.0.1" 52 | }, 53 | "files": [ 54 | "assets", 55 | "inc", 56 | "languages", 57 | "third-party", 58 | "analogwp-templates.php", 59 | "uninstall.php", 60 | "readme.txt" 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /phpcs.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | A custom set of code standard rules to check for AnalogWP Templates. 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | tests/* 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | . 38 | 39 | 40 | /node_modules/* 41 | /build/* 42 | /languages/* 43 | 44 | -------------------------------------------------------------------------------- /scoper.inc.php: -------------------------------------------------------------------------------- 1 | 'Analog\\Dependencies', 13 | 'finders' => array( 14 | // Enshrined/SVG-Sanitize. 15 | Finder::create() 16 | ->files() 17 | ->ignoreVCS( true ) 18 | ->ignoreDotFiles( true ) 19 | ->name( '*.php' ) 20 | ->exclude( 21 | array( 22 | 'tests', 23 | ) 24 | ) 25 | ->in( 'vendor/enshrined/svg-sanitize' ) 26 | ->append( [ 'vendor/enshrined/svg-sanitize/composer.json' ] ), 27 | Finder::create()->append([ 28 | 'composer.json', 29 | ]), 30 | ), 31 | 'patchers' => array( 32 | static function ( string $filePath, string $prefix, string $contents ): string { 33 | // Change the contents here. 34 | 35 | return $contents; 36 | }, 37 | ), 38 | 39 | 'exclude-classes' => $wp_classes, 40 | 'exclude-functions' => $wp_functions, 41 | 'exclude-constants' => $wp_constants, 42 | ]; 43 | -------------------------------------------------------------------------------- /tests/_data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/analogwp/analogwp-templates/56387ea3bc5e273b8de268bc454e20e95299953e/tests/_data/.gitkeep -------------------------------------------------------------------------------- /tests/_output/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /tests/_support/AcceptanceTester.php: -------------------------------------------------------------------------------- 1 | loginAsAdmin(); 8 | } 9 | 10 | private function shouldSaveSettings(AcceptanceTester $I) { 11 | // Ensure settings can be saved. 12 | $I->amOnAdminPage( 'admin.php?page=ang-settings' ); 13 | 14 | $I->amGoingTo( 'save page settings without any changes' ); 15 | $I->click( 'Save changes' ); 16 | $I->see( 'Your settings have been saved.' ); 17 | 18 | // Ensure tab click is working fine. 19 | $I->click( 'Misc', '.nav-tab-wrapper' ); 20 | $I->see( 'Save changes' ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/acceptance/StyleKitExportImportCest.php: -------------------------------------------------------------------------------- 1 | loginAsAdmin(); 8 | } 9 | 10 | public function exportStyleKit( AcceptanceTester $I ) { 11 | $I->amOnAdminPage( 'edit.php?post_type=ang_tokens' ); 12 | $I->moveMouseOver( '.column-title.has-row-actions' ); 13 | $I->see( 'Export Style Kit' ); 14 | $I->click( 'Export Style Kit' ); 15 | 16 | $I->wait(3); 17 | 18 | $link = $I->grabAttributeFrom( '.export-template a', 'href' ); 19 | $url = parse_url( $link ); 20 | parse_str( $url['query'], $params ); 21 | $kit_id = $params['kit_id']; 22 | 23 | $name = 'analog-' . $kit_id . '-' . date( 'Y-m-d' ) . '.json'; 24 | $I->seeFileFound( $name, $_ENV['DOWNLOAD_LOCATION'] ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/api.suite.yml: -------------------------------------------------------------------------------- 1 | actor: ApiTester 2 | modules: 3 | enabled: 4 | - REST: 5 | url: '%WP_URL%/wp-json/agwp/v1' 6 | depends: PhpBrowser 7 | part: Json 8 | - \Helper\Api 9 | -------------------------------------------------------------------------------- /tests/api/CheckEndpointsCest.php: -------------------------------------------------------------------------------- 1 | sendGET( 'https://analogwp.com/wp-json/analogwp/v1/info' ); 8 | $I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK); 9 | $I->seeResponseIsJson(); 10 | $I->seeResponseMatchesJsonType([ 11 | 'timestamp' => 'integer', 12 | 'library' => 'array' 13 | ]); 14 | 15 | // Test Blocks. 16 | $I->seeResponseMatchesJsonType( 17 | [ 18 | 'id' => 'integer:>0', 19 | 'siteID' => 'integer', 20 | 'title' => 'string', 21 | 'thumbnail' => 'string:url', 22 | 'published' => 'integer', 23 | 'tags' => 'array', 24 | 'popularityIndex' => 'integer', 25 | 'is_pro' => 'boolean', 26 | 'requiredVersion' => 'string|null' 27 | ], 28 | '$.library.blocks[0]' 29 | ); 30 | 31 | // Test StyleKits. 32 | $I->seeResponseMatchesJsonType( 33 | [ 34 | 'id' => 'integer:>0', 35 | 'title' => 'string', 36 | 'slug' => 'string', 37 | 'image' => 'string:url', 38 | 'site_id' => 'integer', 39 | 'is_pro' => 'boolean', 40 | ], 41 | '$.library.stylekits[0]' 42 | ); 43 | 44 | // Test Templates. 45 | $I->seeResponseMatchesJsonType( 46 | [ 47 | 'id' => 'string', 48 | 'site_id' => 'string', 49 | 'title' => 'string', 50 | 'thumbnail' => 'string:url', 51 | 'published' => 'integer', 52 | 'url' => 'string:url', 53 | 'type' => 'string', 54 | 'tags' => 'array', 55 | 'page_template' => 'string', 56 | 'popularityIndex' => 'integer', 57 | 'is_pro' => 'boolean', 58 | 'version' => 'string|null', 59 | ], 60 | '$.library.templates[0]' 61 | ); 62 | 63 | // Test template_kits. 64 | $I->seeResponseMatchesJsonType( 65 | [ 66 | 'title' => 'string', 67 | 'site_id' => 'integer', 68 | 'thumbnail' => 'string:url', 69 | ], 70 | '$.library.template_kits[0]' 71 | ); 72 | } 73 | 74 | public function shouldBeUnauthorized( ApiTester $I ) { 75 | $I->sendGET( '/templates' ); 76 | $I->seeResponseCodeIs( 401 ); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /tests/functional.suite.yml: -------------------------------------------------------------------------------- 1 | # Codeception Test Suite Configuration 2 | # 3 | # Suite for functional tests 4 | # Emulate web requests and make WordPress process them 5 | 6 | actor: FunctionalTester 7 | modules: 8 | enabled: 9 | - WPDb 10 | - WPBrowser 11 | # - WPFilesystem 12 | - Asserts 13 | - \Helper\Functional 14 | config: 15 | WPDb: 16 | dsn: 'mysql:host=%DB_HOST%;dbname=%DB_NAME%' 17 | user: '%DB_USER%' 18 | password: '%DB_PASSWORD%' 19 | dump: 'tests/_data/dump.sql' 20 | populate: true 21 | cleanup: true 22 | waitlock: 0 23 | url: '%WP_URL%' 24 | urlReplacement: true 25 | tablePrefix: '%TABLE_PREFIX%' 26 | WPBrowser: 27 | url: '%WP_URL%' 28 | adminUsername: '%ADMIN_USERNAME%' 29 | adminPassword: '%ADMIN_PASSWORD%' 30 | adminPath: '%WP_ADMIN_PATH%' 31 | WPFilesystem: 32 | wpRootFolder: '%WP_ROOT_FOLDER%' 33 | plugins: '/wp-content/plugins' 34 | mu-plugins: '/wp-content/mu-plugins' 35 | themes: '/wp-content/themes' 36 | uploads: '/wp-content/uploads' -------------------------------------------------------------------------------- /tests/unit.suite.yml: -------------------------------------------------------------------------------- 1 | # Codeception Test Suite Configuration 2 | # 3 | # Suite for unit or integration tests. 4 | 5 | actor: UnitTester 6 | modules: 7 | enabled: 8 | - Asserts 9 | - \Helper\Unit -------------------------------------------------------------------------------- /tests/wpunit.suite.yml: -------------------------------------------------------------------------------- 1 | # Codeception Test Suite Configuration 2 | # 3 | # Suite for unit or integration tests that require WordPress functions and classes. 4 | 5 | actor: WpunitTester 6 | modules: 7 | enabled: 8 | - WPLoader 9 | - \Helper\Wpunit 10 | config: 11 | WPLoader: 12 | wpRootFolder: "%WP_ROOT_FOLDER%" 13 | dbName: "%TEST_DB_NAME%" 14 | dbHost: "%TEST_DB_HOST%" 15 | dbUser: "%TEST_DB_USER%" 16 | dbPassword: "%TEST_DB_PASSWORD%" 17 | tablePrefix: "%TEST_TABLE_PREFIX%" 18 | domain: "%WP_DOMAIN%" 19 | adminEmail: "%ADMIN_EMAIL%" 20 | title: "Test" 21 | plugins: ['analogwp-templates/analogwp-templates.php'] 22 | activatePlugins: ['analogwp-templates/analogwp-templates.php'] -------------------------------------------------------------------------------- /third-party/composer.json: -------------------------------------------------------------------------------- 1 | { "autoload": { "classmap": [""] } } 2 | -------------------------------------------------------------------------------- /third-party/vendor/autoload.php: -------------------------------------------------------------------------------- 1 | $vendorDir . '/enshrined/svg-sanitize/src/ElementReference/Resolver.php', 10 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\ElementReference\\Subject' => $vendorDir . '/enshrined/svg-sanitize/src/ElementReference/Subject.php', 11 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\ElementReference\\Usage' => $vendorDir . '/enshrined/svg-sanitize/src/ElementReference/Usage.php', 12 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\Exceptions\\NestingException' => $vendorDir . '/enshrined/svg-sanitize/src/Exceptions/NestingException.php', 13 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\Helper' => $vendorDir . '/enshrined/svg-sanitize/src/Helper.php', 14 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\Sanitizer' => $vendorDir . '/enshrined/svg-sanitize/src/Sanitizer.php', 15 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\AllowedAttributes' => $vendorDir . '/enshrined/svg-sanitize/src/data/AllowedAttributes.php', 16 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\AllowedTags' => $vendorDir . '/enshrined/svg-sanitize/src/data/AllowedTags.php', 17 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\AttributeInterface' => $vendorDir . '/enshrined/svg-sanitize/src/data/AttributeInterface.php', 18 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\TagInterface' => $vendorDir . '/enshrined/svg-sanitize/src/data/TagInterface.php', 19 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\XPath' => $vendorDir . '/enshrined/svg-sanitize/src/data/XPath.php', 20 | 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 21 | ); 22 | -------------------------------------------------------------------------------- /third-party/vendor/composer/autoload_namespaces.php: -------------------------------------------------------------------------------- 1 | setClassMapAuthoritative(true); 33 | $loader->register(true); 34 | 35 | return $loader; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /third-party/vendor/composer/autoload_static.php: -------------------------------------------------------------------------------- 1 | __DIR__ . '/..' . '/enshrined/svg-sanitize/src/ElementReference/Resolver.php', 11 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\ElementReference\\Subject' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/ElementReference/Subject.php', 12 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\ElementReference\\Usage' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/ElementReference/Usage.php', 13 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\Exceptions\\NestingException' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/Exceptions/NestingException.php', 14 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\Helper' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/Helper.php', 15 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\Sanitizer' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/Sanitizer.php', 16 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\AllowedAttributes' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/data/AllowedAttributes.php', 17 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\AllowedTags' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/data/AllowedTags.php', 18 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\AttributeInterface' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/data/AttributeInterface.php', 19 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\TagInterface' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/data/TagInterface.php', 20 | 'Analog\\Dependencies\\enshrined\\svgSanitize\\data\\XPath' => __DIR__ . '/..' . '/enshrined/svg-sanitize/src/data/XPath.php', 21 | 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 22 | ); 23 | 24 | public static function getInitializer(ClassLoader $loader) 25 | { 26 | return \Closure::bind(function () use ($loader) { 27 | $loader->classMap = ComposerStaticInitf898fd6c5f659794d92b538c45d56a06::$classMap; 28 | 29 | }, null, ClassLoader::class); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /third-party/vendor/enshrined/svg-sanitize/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "enshrined\/svg-sanitize", 3 | "description": "An SVG sanitizer for PHP", 4 | "license": "GPL-2.0-or-later", 5 | "authors": [ 6 | { 7 | "name": "Daryll Doyle", 8 | "email": "daryll@enshrined.co.uk" 9 | } 10 | ], 11 | "scripts": { 12 | "test": "phpunit --no-coverage", 13 | "test:coverage": "phpunit" 14 | }, 15 | "autoload": { 16 | "psr-4": { 17 | "Analog\\Dependencies\\enshrined\\svgSanitize\\": "src" 18 | } 19 | }, 20 | "autoload-dev": { 21 | "psr-4": { 22 | "Analog\\Dependencies\\enshrined\\svgSanitize\\Tests\\": "tests" 23 | } 24 | }, 25 | "require": { 26 | "ext-dom": "*", 27 | "ext-libxml": "*", 28 | "php": "^7.0 || ^8.0" 29 | }, 30 | "require-dev": { 31 | "phpunit\/phpunit": "^6.5 || ^8.5" 32 | } 33 | } -------------------------------------------------------------------------------- /third-party/vendor/enshrined/svg-sanitize/src/ElementReference/Usage.php: -------------------------------------------------------------------------------- 1 | subject = $subject; 22 | $this->count = (int) $count; 23 | } 24 | /** 25 | * @param int $by 26 | */ 27 | public function increment($by = 1) 28 | { 29 | $this->count += (int) $by; 30 | } 31 | /** 32 | * @return Subject 33 | */ 34 | public function getSubject() 35 | { 36 | return $this->subject; 37 | } 38 | /** 39 | * @return int 40 | */ 41 | public function getCount() 42 | { 43 | return $this->count; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /third-party/vendor/enshrined/svg-sanitize/src/Exceptions/NestingException.php: -------------------------------------------------------------------------------- 1 | element = $element; 23 | parent::__construct($message, $code, $previous); 24 | } 25 | /** 26 | * Get the element that caused the exception. 27 | * 28 | * @return \DOMElement 29 | */ 30 | public function getElement() 31 | { 32 | return $this->element; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /third-party/vendor/enshrined/svg-sanitize/src/Helper.php: -------------------------------------------------------------------------------- 1 | hasAttribute('href')) { 14 | return $element->getAttribute('href'); 15 | } 16 | if ($element->hasAttributeNS('http://www.w3.org/1999/xlink', 'href')) { 17 | return $element->getAttributeNS('http://www.w3.org/1999/xlink', 'href'); 18 | } 19 | return null; 20 | } 21 | /** 22 | * @param string $href 23 | * @return string|null 24 | */ 25 | public static function extractIdReferenceFromHref($href) 26 | { 27 | if (!\is_string($href) || \strpos($href, '#') !== 0) { 28 | return null; 29 | } 30 | return \substr($href, 1); 31 | } 32 | /** 33 | * @param \DOMElement $needle 34 | * @param \DOMElement $haystack 35 | * @return bool 36 | */ 37 | public static function isElementContainedIn(\DOMElement $needle, \DOMElement $haystack) 38 | { 39 | if ($needle === $haystack) { 40 | return \true; 41 | } 42 | foreach ($haystack->childNodes as $childNode) { 43 | if (!$childNode instanceof \DOMElement) { 44 | continue; 45 | } 46 | if (self::isElementContainedIn($needle, $childNode)) { 47 | return \true; 48 | } 49 | } 50 | return \false; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /third-party/vendor/enshrined/svg-sanitize/src/data/AttributeInterface.php: -------------------------------------------------------------------------------- 1 | handleDefaultNamespace(); 16 | } 17 | /** 18 | * @param string $nodeName 19 | * @return string 20 | */ 21 | public function createNodeName($nodeName) 22 | { 23 | if (empty($this->defaultNamespaceURI)) { 24 | return $nodeName; 25 | } 26 | return self::DEFAULT_NAMESPACE_PREFIX . ':' . $nodeName; 27 | } 28 | protected function handleDefaultNamespace() 29 | { 30 | $rootElements = $this->getRootElements(); 31 | if (\count($rootElements) !== 1) { 32 | throw new \LogicException(\sprintf('Got %d svg elements, expected exactly one', \count($rootElements)), 1570870568); 33 | } 34 | $this->defaultNamespaceURI = (string) $rootElements[0]->namespaceURI; 35 | if ($this->defaultNamespaceURI !== '') { 36 | $this->registerNamespace(self::DEFAULT_NAMESPACE_PREFIX, $this->defaultNamespaceURI); 37 | } 38 | } 39 | /** 40 | * @return \DOMElement[] 41 | */ 42 | protected function getRootElements() 43 | { 44 | $rootElements = []; 45 | $elements = $this->document->getElementsByTagName('svg'); 46 | /** @var \DOMElement $element */ 47 | foreach ($elements as $element) { 48 | if ($element->parentNode !== $this->document) { 49 | continue; 50 | } 51 | $rootElements[] = $element; 52 | } 53 | return $rootElements; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /third-party/vendor/scoper-autoload.php: -------------------------------------------------------------------------------- 1 | files_manager->clear_cache(); 31 | } 32 | --------------------------------------------------------------------------------