├── .devcontainer ├── devcontainer.json └── docker-compose.yml ├── .dockerignore ├── .github ├── .stale ├── CODEOWNERS ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md ├── actions │ ├── prepare-source │ │ └── action.yml │ └── run-wp-tests │ │ └── action.yml ├── codecov.yml ├── codeql-config.yml ├── dependabot.yml └── workflows │ ├── build-docker-image.yml │ ├── changelog-summary-prod.yml │ ├── changelog-summary-staging.yml │ ├── ci.yml │ ├── codeql-analysis.yml │ ├── core-tests.yml │ ├── coverage-develop.yml │ ├── dependency-review.yml │ ├── deploy.yml │ ├── e2e.yml │ ├── lint.yml │ ├── parsely.yml │ ├── search-dev-tools.yml │ └── stale.yml ├── .gitignore ├── .gitmodules ├── .husky ├── .gitignore └── pre-commit ├── .lintstagedrc ├── .sonarcloud.properties ├── 000-debug ├── 0-load.php ├── debug-mode.php ├── logger.php └── not-proxied-flag.php ├── 000-pre-vip-config └── requires.php ├── 000-vip-init.php ├── 001-core.php ├── 001-core ├── constants.php ├── options-api.php └── privacy.php ├── 001-cron.php ├── LICENSE ├── README-PUBLIC.md ├── README.md ├── SECURITY.md ├── __tests__ └── e2e │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── bin │ └── setup-env.sh │ ├── lib │ ├── asana-pharse.d.ts │ ├── components │ │ └── wp-admin-sidebar-component.ts │ ├── data-helper.ts │ ├── global-setup.ts │ ├── pages │ │ ├── lost-password-page.ts │ │ ├── media-upload-page.ts │ │ ├── page-list-page.ts │ │ ├── post-list-page.ts │ │ ├── published-page-page.ts │ │ ├── published-post-page.ts │ │ ├── search-page.ts │ │ ├── settings-writing-page.ts │ │ ├── wp-admin-page.ts │ │ ├── wp-classic-editor-page.ts │ │ ├── wp-editor-page.ts │ │ └── wp-login-page.ts │ ├── playwright-helpers.ts │ └── wp-api-helper.ts │ ├── package-lock.json │ ├── package.json │ ├── playwright.config.ts │ ├── specs │ ├── generic.spec.ts │ ├── media__add.spec.ts │ ├── page__edit.spec.ts │ ├── page__publish.spec.ts │ ├── page_classic__publish.spec.ts │ ├── post__edit.spec.ts │ ├── post__publish.spec.ts │ ├── post_classic__publish.spec.ts │ ├── searchdevtools.spec.ts │ └── security.spec.ts │ ├── test_media │ ├── image_01.jpg │ └── image_02.jpg │ └── tsconfig.json ├── a8c-files.php ├── admin-notice.php ├── admin-notice ├── README.md ├── admin-notice.php ├── class-admin-notice-controller.php ├── class-admin-notice.php ├── conditions │ ├── class-capability-condition.php │ ├── class-date-condition.php │ ├── class-expression-condition.php │ ├── class-wp-version-condition.php │ └── interface-condition.php └── js │ └── script.js ├── advanced-post-cache.php ├── akismet.php ├── akismet ├── .htaccess ├── LICENSE.txt ├── _inc │ ├── akismet-admin.css │ ├── akismet-admin.js │ ├── akismet-frontend.js │ ├── akismet.css │ ├── akismet.js │ ├── fonts │ │ └── inter.css │ ├── img │ │ ├── akismet-refresh-logo.svg │ │ ├── akismet-refresh-logo@2x.png │ │ ├── arrow-left.svg │ │ ├── icon-external.svg │ │ ├── logo-a-2x.png │ │ └── logo-full-2x.png │ └── rtl │ │ ├── akismet-admin-rtl.css │ │ └── akismet-rtl.css ├── akismet.php ├── changelog.txt ├── class.akismet-admin.php ├── class.akismet-cli.php ├── class.akismet-rest-api.php ├── class.akismet-widget.php ├── class.akismet.php ├── index.php ├── readme.txt ├── views │ ├── activate.php │ ├── config.php │ ├── connect-jp.php │ ├── enter.php │ ├── get.php │ ├── logo.php │ ├── notice.php │ ├── predefined.php │ ├── setup.php │ ├── start.php │ ├── stats.php │ └── title.php └── wrapper.php ├── alloptions-limit.php ├── back-compat.php ├── bin ├── download-wp-tests.sh ├── manage-wp-parsely-subtree.sh ├── php-lint.sh ├── test.sh └── upgrade-plugin.sh ├── blogpublic-notice.php ├── cache ├── README.md ├── class-vary-cache.php └── examples │ ├── segmentation-beta │ └── beta.php │ └── segmentation-maintenance-mode-bypass │ └── vip-config.php ├── ci └── changelog-summary.php ├── codebase-manager.php ├── codebase-manager ├── codebase-manager.php └── plugins │ ├── plugin.php │ └── plugins-manager.php ├── composer.json ├── composer.json.tpl ├── composer.lock ├── config ├── class-site-details-index.php └── class-sync.php ├── cron-control ├── .github │ ├── CODEOWNERS │ ├── checkstyle-problem-matcher.json │ ├── dependabot.yml │ └── workflows │ │ ├── ci-grunt.yaml │ │ ├── ci-php.yaml │ │ └── phpcs.yaml ├── .gitignore ├── .nvmrc ├── Gruntfile.js ├── LICENSE ├── README.md ├── __tests__ │ ├── bin │ │ ├── install-wp-tests.sh │ │ └── test.sh │ ├── bootstrap.php │ ├── unit-tests │ │ ├── test-cli-orchestrate-sites.php │ │ ├── test-event.php │ │ ├── test-events-store.php │ │ ├── test-events.php │ │ ├── test-internal-events.php │ │ ├── test-rest-api.php │ │ └── test-wp-adapter.php │ └── utils.php ├── composer.json ├── composer.lock ├── cron-control.php ├── includes │ ├── class-event.php │ ├── class-events-store.php │ ├── class-events.php │ ├── class-internal-events.php │ ├── class-lock.php │ ├── class-main.php │ ├── class-rest-api.php │ ├── class-singleton.php │ ├── constants.php │ ├── functions.php │ ├── utils.php │ ├── wp-adapter.php │ ├── wp-cli.php │ └── wp-cli │ │ ├── class-events.php │ │ ├── class-lock.php │ │ ├── class-main.php │ │ ├── class-orchestrate-runner.php │ │ ├── class-orchestrate-sites.php │ │ ├── class-orchestrate.php │ │ └── class-rest-api.php ├── languages │ └── cron-control.pot ├── package-lock.json ├── package.json ├── phpcs.xml ├── phpunit-multisite.xml ├── phpunit.xml └── readme.txt ├── cron ├── action-scheduler-dynamic-queue.php ├── cron-control │ ├── .github │ │ ├── CODEOWNERS │ │ ├── checkstyle-problem-matcher.json │ │ ├── dependabot.yml │ │ └── workflows │ │ │ ├── ci-grunt.yaml │ │ │ ├── ci-php.yaml │ │ │ └── phpcs.yaml │ ├── .gitignore │ ├── .nvmrc │ ├── Gruntfile.js │ ├── LICENSE │ ├── README.md │ ├── __tests__ │ │ ├── bin │ │ │ ├── install-wp-tests.sh │ │ │ └── test.sh │ │ ├── bootstrap.php │ │ ├── unit-tests │ │ │ ├── test-cli-orchestrate-sites.php │ │ │ ├── test-event.php │ │ │ ├── test-events-store.php │ │ │ ├── test-events.php │ │ │ ├── test-internal-events.php │ │ │ ├── test-rest-api.php │ │ │ └── test-wp-adapter.php │ │ └── utils.php │ ├── composer.json │ ├── composer.lock │ ├── cron-control.php │ ├── includes │ │ ├── class-event.php │ │ ├── class-events-store.php │ │ ├── class-events.php │ │ ├── class-internal-events.php │ │ ├── class-lock.php │ │ ├── class-main.php │ │ ├── class-rest-api.php │ │ ├── class-singleton.php │ │ ├── constants.php │ │ ├── functions.php │ │ ├── utils.php │ │ ├── wp-adapter.php │ │ ├── wp-cli.php │ │ └── wp-cli │ │ │ ├── class-events.php │ │ │ ├── class-lock.php │ │ │ ├── class-main.php │ │ │ ├── class-orchestrate-runner.php │ │ │ ├── class-orchestrate-sites.php │ │ │ ├── class-orchestrate.php │ │ │ └── class-rest-api.php │ ├── languages │ │ └── cron-control.pot │ ├── package-lock.json │ ├── package.json │ ├── phpcs.xml │ ├── phpunit-multisite.xml │ ├── phpunit.xml │ └── readme.txt └── cron.php ├── drop-ins ├── db.php ├── object-cache.php ├── object-cache │ └── object-cache-stable.php └── wp-memcached │ ├── .gitignore │ ├── bin │ └── test.sh │ ├── composer.json │ ├── composer.lock │ ├── includes │ ├── adapter-interface.php │ ├── memcache-adapter.php │ ├── memcached-adapter.php │ ├── stats.php │ └── wp-object-cache.php │ ├── object-cache.php │ ├── phpcs.xml.dist │ ├── phpunit.xml.dist │ ├── psalm.xml.dist │ ├── readme.md │ ├── stubs │ ├── memcache-stubs.php │ ├── memcached-stubs.php │ └── wordpress-stubs.php │ └── tests │ ├── bootstrap.php │ └── test-wp-object-cache.php ├── errors ├── alloptions-limit.html ├── network-not-found.html ├── site-maintenance.html ├── site-not-found.html └── site-shutdown.html ├── files ├── acl │ ├── acl.php │ ├── endpoint-check-file-acl.php │ ├── pre-wp-utils.php │ ├── restrict-all-files.php │ └── restrict-unpublished-files.php ├── class-api-cache.php ├── class-api-client.php ├── class-curl-streamer.php ├── class-image-sizes.php ├── class-image.php ├── class-meta-updater.php ├── class-path-utils.php ├── class-vip-filesystem-local-stream-wrapper.php ├── class-vip-filesystem.php ├── class-wp-filesystem-vip-uploads.php ├── class-wp-filesystem-vip.php └── init-filesystem.php ├── healthcheck ├── class-healthcheck.php └── healthcheck.php ├── http-concat.php ├── integrations ├── block-data-api.php ├── enterprise-search.php ├── enums.php ├── integration-utils.php ├── integration-vip-config.php ├── integration.php ├── integrations.php ├── jetpack.php ├── parsely.php ├── remote-data-blocks.php ├── security-boost.php └── vip-governance.php ├── jetpack.php ├── lib ├── class-apc-cache-interceptor.php ├── class-vip-encloseme-cleanup.php ├── class-vip-request-block.php ├── db-multiple-datasets-config.php ├── environment │ └── class-environment.php ├── feature │ ├── README.md │ ├── class-feature-cli.php │ └── class-feature.php ├── helpers │ ├── environment.php │ ├── php-compat.php │ ├── wp-cli-db.php │ └── wp-cli-db │ │ ├── README.md │ │ ├── class-config.php │ │ ├── class-db-server.php │ │ ├── class-vip-db-command.php │ │ └── class-wp-cli-db.php ├── proxy │ ├── class-iputils.php │ └── ip-forward.php ├── sms.php ├── sunrise │ └── sunrise.php ├── utils │ ├── class-alerts.php │ └── class-context.php └── wpcom-error-handler │ └── wpcom-error-handler.php ├── logstash ├── class-logger.php └── logstash.php ├── misc.php ├── package-lock.json ├── package.json ├── performance.php ├── performance ├── bulk-edit.php ├── class-mime-types-caching.php ├── do-pings.php ├── lastpostmodified.php ├── media.php ├── plugins.php └── vip-tweaks.php ├── phpcs.xml.dist ├── phpunit-multisite.xml ├── phpunit.xml ├── plugin-fixes.php ├── prometheus-collectors ├── class-apcu-collector.php ├── class-cache-collector.php ├── class-error-stats-collector.php ├── class-login-stats-collector.php ├── class-multisite-stats-collector.php ├── class-opcache-collector.php ├── class-potential-multi-dataset-queries-collector.php └── class-user-stats-collector.php ├── prometheus.php ├── prometheus ├── README.md ├── composer.json ├── composer.lock ├── endpoint.php ├── inc │ ├── class-collectorinterface.php │ ├── class-plugin.php │ └── class-safeadapter.php ├── index.php └── vendor │ ├── autoload.php │ ├── composer │ ├── ClassLoader.php │ ├── InstalledVersions.php │ ├── LICENSE │ ├── autoload_classmap.php │ ├── autoload_namespaces.php │ ├── autoload_psr4.php │ ├── autoload_real.php │ ├── autoload_static.php │ ├── installed.json │ ├── installed.php │ └── platform_check.php │ └── promphp │ └── prometheus_client_php │ ├── LICENSE │ ├── README.APCng.md │ ├── README.md │ ├── composer.json │ ├── phpstan.neon.dist │ └── src │ └── Prometheus │ ├── Collector.php │ ├── CollectorRegistry.php │ ├── Counter.php │ ├── Exception │ ├── MetricNotFoundException.php │ ├── MetricsRegistrationException.php │ └── StorageException.php │ ├── Gauge.php │ ├── Histogram.php │ ├── Math.php │ ├── MetricFamilySamples.php │ ├── RegistryInterface.php │ ├── RenderTextFormat.php │ ├── RendererInterface.php │ ├── Sample.php │ ├── Storage │ ├── APC.php │ ├── APCng.php │ ├── Adapter.php │ ├── InMemory.php │ └── Redis.php │ └── Summary.php ├── qm-plugins ├── qm-alloptions │ ├── class-qm-collector-alloptions.php │ ├── class-qm-data-alloptions.php │ ├── class-qm-output-html-alloptions.php │ ├── qm-alloptions.php │ ├── readme.md │ └── screenshot-1.png ├── qm-apcu-cache │ ├── class-qm-collector-apcu-cache.php │ ├── class-qm-output-html-apcu-cache.php │ └── qm-apcu-cache.php ├── qm-cron │ ├── class-qm-collector-cron.php │ ├── class-qm-data-cron.php │ ├── class-qm-output-html-cron.php │ └── qm-cron.php ├── qm-db-connections │ ├── class-qm-collector-db-connections.php │ ├── class-qm-data-db-connections.php │ ├── class-qm-output-html-db-connections.php │ └── qm-db-connections.php ├── qm-limited-header-php-errors │ └── output │ │ └── headers │ │ └── php-errors.php ├── qm-object-cache │ ├── class-qm-data-object-cache.php │ ├── collectors │ │ ├── class-qm-collector-object-cache-group-stats.php │ │ ├── class-qm-collector-object-cache-ops.php │ │ ├── class-qm-collector-object-cache-slow-ops.php │ │ └── class-qm-collector-object-cache.php │ ├── css │ │ └── style.css │ ├── html │ │ ├── class-qm-output-html-object-cache-group-stats.php │ │ ├── class-qm-output-html-object-cache-ops.php │ │ ├── class-qm-output-html-object-cache-slow-ops.php │ │ └── class-qm-output-html-object-cache.php │ ├── qm-object-cache.php │ └── readme.md └── qm-vip │ ├── class-qm-collector-vip.php │ ├── class-qm-data-vip.php │ ├── class-qm-output-html-vip.php │ └── qm-vip.php ├── query-monitor.php ├── query-monitor ├── LICENSE ├── SECURITY.md ├── assets │ ├── icons │ │ ├── admin-generic.svg │ │ ├── arrow-down.svg │ │ ├── edit.svg │ │ ├── external.svg │ │ ├── filter.svg │ │ ├── image-rotate-left.svg │ │ ├── image-rotate-right.svg │ │ ├── info.svg │ │ ├── no-alt.svg │ │ ├── warning.svg │ │ └── yes-alt.svg │ ├── query-monitor.css │ └── query-monitor.js ├── classes │ ├── Activation.php │ ├── Backtrace.php │ ├── CLI.php │ ├── Collector.php │ ├── Collector_Assets.php │ ├── Collectors.php │ ├── Component.php │ ├── DB.php │ ├── Data.php │ ├── DataCollector.php │ ├── Dispatcher.php │ ├── Dispatchers.php │ ├── Hook.php │ ├── Output.php │ ├── PHP.php │ ├── Plugin.php │ ├── QM.php │ ├── QueryMonitor.php │ ├── Timer.php │ ├── Util.php │ ├── debug_bar.php │ └── debug_bar_panel.php ├── collectors │ ├── admin.php │ ├── assets_scripts.php │ ├── assets_styles.php │ ├── block_editor.php │ ├── cache.php │ ├── caps.php │ ├── conditionals.php │ ├── db_callers.php │ ├── db_components.php │ ├── db_dupes.php │ ├── db_queries.php │ ├── debug_bar.php │ ├── doing_it_wrong.php │ ├── environment.php │ ├── hooks.php │ ├── http.php │ ├── languages.php │ ├── logger.php │ ├── multisite.php │ ├── overview.php │ ├── php_errors.php │ ├── raw_request.php │ ├── redirects.php │ ├── request.php │ ├── theme.php │ ├── timing.php │ └── transients.php ├── composer.json ├── data │ ├── admin.php │ ├── assets.php │ ├── block_editor.php │ ├── cache.php │ ├── caps.php │ ├── conditionals.php │ ├── db_callers.php │ ├── db_components.php │ ├── db_dupes.php │ ├── db_queries.php │ ├── doing_it_wrong.php │ ├── environment.php │ ├── fallback.php │ ├── hooks.php │ ├── http.php │ ├── languages.php │ ├── logger.php │ ├── multisite.php │ ├── overview.php │ ├── php_errors.php │ ├── raw_request.php │ ├── redirect.php │ ├── request.php │ ├── theme.php │ ├── timing.php │ └── transients.php ├── dispatchers │ ├── AJAX.php │ ├── Html.php │ ├── REST.php │ ├── REST_Envelope.php │ ├── Redirect.php │ └── WP_Die.php ├── output │ ├── Headers.php │ ├── Html.php │ ├── Raw.php │ ├── headers │ │ ├── overview.php │ │ ├── php_errors.php │ │ └── redirects.php │ ├── html │ │ ├── admin.php │ │ ├── assets.php │ │ ├── assets_scripts.php │ │ ├── assets_styles.php │ │ ├── block_editor.php │ │ ├── caps.php │ │ ├── conditionals.php │ │ ├── db_callers.php │ │ ├── db_components.php │ │ ├── db_dupes.php │ │ ├── db_queries.php │ │ ├── debug_bar.php │ │ ├── doing_it_wrong.php │ │ ├── environment.php │ │ ├── headers.php │ │ ├── hooks.php │ │ ├── http.php │ │ ├── languages.php │ │ ├── logger.php │ │ ├── multisite.php │ │ ├── overview.php │ │ ├── php_errors.php │ │ ├── request.php │ │ ├── theme.php │ │ ├── timing.php │ │ └── transients.php │ └── raw │ │ ├── cache.php │ │ ├── conditionals.php │ │ ├── db_queries.php │ │ ├── http.php │ │ ├── logger.php │ │ └── transients.php ├── query-monitor.php ├── readme.txt ├── vendor │ ├── autoload.php │ └── composer │ │ ├── ClassLoader.php │ │ ├── LICENSE │ │ ├── autoload_real.php │ │ ├── autoload_static.php │ │ └── platform_check.php └── wp-content │ └── db.php ├── renovate.json ├── rest-api └── vip-endpoints.php ├── rewrite-rules-inspector.php ├── schema.php ├── search ├── es-wp-query │ ├── .gitignore │ ├── .travis.yml │ ├── README.md │ ├── adapters │ │ └── vip-search.php │ ├── bin │ │ ├── install-es.sh │ │ └── install-wp-tests.sh │ ├── class-es-wp-date-query.php │ ├── class-es-wp-meta-query.php │ ├── class-es-wp-query-shoehorn.php │ ├── class-es-wp-query-wrapper.php │ ├── class-es-wp-tax-query.php │ ├── es-wp-query.php │ ├── functions.php │ ├── multisite.xml │ ├── phpcs.xml.dist │ ├── phpunit.xml.dist │ └── tests │ │ ├── .DS_Store │ │ ├── bootstrap.php │ │ └── query │ │ ├── author.php │ │ ├── date.php │ │ ├── dateQuery.php │ │ ├── loggedIn.php │ │ ├── metaQuery.php │ │ ├── post.php │ │ ├── query.php │ │ ├── results.php │ │ ├── shoehorn.php │ │ └── taxQuery.php ├── includes │ ├── classes │ │ ├── class-cache.php │ │ ├── class-concurrency-limiter.php │ │ ├── class-dashboard.php │ │ ├── class-fieldcountgaugejob.php │ │ ├── class-health.php │ │ ├── class-healthjob.php │ │ ├── class-prometheus-collector.php │ │ ├── class-queue.php │ │ ├── class-queuewaittimejob.php │ │ ├── class-search.php │ │ ├── class-settingshealthjob.php │ │ ├── class-syncmanager-helper.php │ │ ├── class-versioning.php │ │ ├── class-versioningcleanupjob.php │ │ ├── commands │ │ │ ├── class-corecommand.php │ │ │ ├── class-documentcommand.php │ │ │ ├── class-healthcommand.php │ │ │ ├── class-queuecommand.php │ │ │ └── class-versioncommand.php │ │ ├── concurrency-limiter │ │ │ ├── backendinterface.php │ │ │ ├── class-apcu-backend.php │ │ │ └── class-object-cache-backend.php │ │ └── queue │ │ │ ├── class-cron.php │ │ │ └── class-schema.php │ └── functions │ │ ├── ep-get-query-log.php │ │ └── utils.php ├── search-dev-tools │ ├── .babelrc.json │ ├── .eslintrc.json │ ├── .gitignore │ ├── README.md │ ├── build │ │ ├── bundle.css │ │ └── bundle.js │ ├── package-lock.json │ ├── package.json │ ├── postcss.config.js │ ├── search-dev-tools.php │ ├── src │ │ ├── assets │ │ │ ├── close.svg │ │ │ ├── favicon.ico │ │ │ ├── icon.png │ │ │ ├── lg.svg │ │ │ ├── minus.svg │ │ │ ├── plus.svg │ │ │ └── wpvip.svg │ │ ├── components │ │ │ ├── app.js │ │ │ ├── collapsible-list │ │ │ │ ├── index.js │ │ │ │ └── style.scss │ │ │ ├── information-pane │ │ │ │ ├── index.js │ │ │ │ └── style.scss │ │ │ ├── overlay │ │ │ │ ├── index.js │ │ │ │ └── style.scss │ │ │ ├── query │ │ │ │ ├── index.js │ │ │ │ └── style.scss │ │ │ └── style.scss │ │ ├── context.js │ │ ├── index.js │ │ ├── manifest.json │ │ ├── style │ │ │ ├── mixins.scss │ │ │ ├── prism.scss │ │ │ ├── style.scss │ │ │ └── vars.scss │ │ ├── template.html │ │ ├── utils.js │ │ └── webpack-public-path.js │ └── webpack.config.js └── search.php ├── security.php ├── security ├── class-lockout.php ├── class-private-sites.php ├── js │ └── password.js ├── login-error.php ├── machine-user.php └── password.php ├── shared-plugins └── two-factor │ ├── LICENSE.md │ ├── assets │ ├── banner-1544x500.png │ ├── banner-772x250.png │ ├── icon-128x128.png │ ├── icon-256x256.png │ ├── icon.svg │ ├── screenshot-1.png │ ├── screenshot-2.png │ └── screenshot-3.png │ ├── class-two-factor-compat.php │ ├── class-two-factor-core.php │ ├── includes │ ├── Google │ │ └── u2f-api.js │ ├── Yubico │ │ └── U2F.php │ ├── function.login-footer.php │ ├── function.login-header.php │ └── qrcode-generator │ │ └── qrcode.js │ ├── providers │ ├── class-two-factor-backup-codes.php │ ├── class-two-factor-dummy.php │ ├── class-two-factor-email.php │ ├── class-two-factor-fido-u2f-admin-list-table.php │ ├── class-two-factor-fido-u2f-admin.php │ ├── class-two-factor-fido-u2f.php │ ├── class-two-factor-provider.php │ ├── class-two-factor-totp.php │ ├── css │ │ └── fido-u2f-admin.css │ └── js │ │ ├── fido-u2f-admin-inline-edit.js │ │ ├── fido-u2f-admin.js │ │ └── fido-u2f-login.js │ ├── readme.txt │ ├── two-factor.php │ └── user-edit.css ├── stats.php ├── telemetry ├── README.md ├── class-telemetry-client.php ├── class-telemetry-event-queue.php ├── class-telemetry-event.php ├── class-telemetry-system.php ├── class-telemetry.php ├── pendo │ ├── class-pendo-javascript-library.php │ ├── class-pendo-track-client.php │ ├── class-pendo-track-event-dto.php │ ├── class-pendo-track-event.php │ ├── class-pendo.php │ ├── js │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── pendo-agent.js │ │ └── pendo-agent.mjs │ └── pendo-utils.php └── tracks │ ├── class-tracks-client.php │ ├── class-tracks-event-dto.php │ ├── class-tracks-event.php │ ├── class-tracks.php │ └── tracks-utils.php ├── tests ├── 001-core │ └── test-constants.php ├── admin-notice │ ├── conditions │ │ ├── test-class-capability-condition.php │ │ ├── test-class-date-condition.php │ │ └── test-class-wp-version-condition.php │ ├── test-admin-notice.php │ ├── test-class-admin-notice-controller.php │ └── test-class-admin-notice.php ├── bootstrap.php ├── cache │ ├── mock-header.php │ └── test-vary-cache.php ├── class-speedup-isolated-wp-tests.php ├── class-vip-test-listener.php ├── config │ ├── test-site-details-index.php │ └── test-sync.php ├── files │ ├── acl │ │ ├── mock-header.php │ │ ├── test-acl.php │ │ ├── test-pre-wp-utils.php │ │ ├── test-restrict-all-files.php │ │ └── test-restrict-unpublished-files.php │ ├── test-api-client.php │ ├── test-curl-streamer.php │ ├── test-fix-block-img-tag-sizes.php │ ├── test-image-sizes.php │ ├── test-image.php │ ├── test-path-utils.php │ ├── test-vip-filesystem-api-cache.php │ ├── test-vip-filesystem-local-stream-wrapper.php │ ├── test-vip-filesystem.php │ ├── test-wp-filesystem-vip-uploads.php │ └── test-wp-filesystem-vip.php ├── fixtures │ ├── client-mu-plugins │ │ ├── empty │ │ │ └── .nodelete │ │ └── valid │ │ │ ├── 0-first-plugin.php │ │ │ ├── index.php │ │ │ ├── not-php.txt │ │ │ ├── with-headers.php │ │ │ └── z-last-plugin.php │ ├── files │ │ ├── stream.txt │ │ ├── upload.jpg │ │ └── upload.some-unmatched-extension │ ├── image.jpg │ ├── jetpack │ │ └── class-jetpack-sync-immediately.php │ ├── pdf.pdf │ └── plugin-fixes │ │ └── mock-ninja-forms-class.php ├── integrations │ ├── fake-integration.php │ ├── test-enterprise-search.php │ ├── test-integration-utils.php │ ├── test-integration-vip-config.php │ ├── test-integration.php │ ├── test-integrations.php │ ├── test-parsely.php │ ├── test-remote-data-blocks.php │ ├── test-vip-block-data-api.php │ ├── test-vip-governance.php │ └── test-vip-security-boost.php ├── lib │ ├── environment │ │ └── test-class-environment.php │ ├── feature │ │ ├── test-class-feature-ms.php │ │ └── test-class-feature.php │ ├── helpers │ │ ├── test-environment.php │ │ └── test-wp-cli-db.php │ ├── mock-wpdb.php │ ├── proxy │ │ ├── class-ip-forward-test-base.php │ │ ├── test-fix-remote-address-from-ip-trail-with-verification-key.php │ │ ├── test-fix-remote-address-with-verification-key.php │ │ ├── test-get-ip-addresses-from-ip-trail.php │ │ ├── test-get-proxy-verification-key.php │ │ ├── test-ip-forward.php │ │ └── test-is-valid-proxy-verification-key.php │ ├── test-db-multiple-datasets-config.php │ ├── test-vip-request-block.php │ └── utils │ │ ├── class-testable-alerts.php │ │ ├── context.php │ │ └── test-alerts.php ├── logstash │ ├── class-testable-logger.php │ └── test-logger.php ├── mock-constants.php ├── mock-header.php ├── parsely │ └── test-mu-parsely-integration.php ├── performance │ ├── test-class-mime-types-caching.php │ └── test-do-pings.php ├── prometheus-collectors │ ├── test-class-potential-multi-dataset-queries-collector.php │ └── test-class-user-stats-collector.php ├── prometheus │ ├── class-plugin-helper.php │ └── test-prometheus.php ├── proxy-helpers.php ├── search │ ├── data │ │ └── test_fixtures.yml │ ├── includes │ │ └── classes │ │ │ ├── mock-header.php │ │ │ ├── queue │ │ │ └── test-class-cron.php │ │ │ ├── test-class-cache.php │ │ │ ├── test-class-health.php │ │ │ ├── test-class-healthjob.php │ │ │ ├── test-class-queue.php │ │ │ ├── test-class-search.php │ │ │ ├── test-class-settingshealthjob.php │ │ │ ├── test-class-versioning.php │ │ │ ├── test-class-versioningcleanupjob.php │ │ │ ├── test-concurrency-limiter.php │ │ │ └── test-syncmanager-helper.php │ └── test-search-dev-tools.php ├── security │ ├── test-class-private-sites.php │ ├── test-lockout.php │ ├── test-login-error.php │ ├── test-machine-user.php │ └── test-password.php ├── telemetry │ ├── pendo │ │ ├── test-class-pendo-client.php │ │ ├── test-class-pendo-javascript-library.php │ │ ├── test-class-pendo-track-event.php │ │ ├── test-class-pendo.php │ │ └── test-pendo-utils.php │ ├── test-class-telemetry-event-queue.php │ ├── test-class-telemetry.php │ └── tracks │ │ ├── test-class-tracks-client.php │ │ ├── test-class-tracks-event-dto.php │ │ ├── test-class-tracks-event.php │ │ ├── test-class-tracks.php │ │ └── test-tracks-utils.php ├── test-a8c-files-utils.php ├── test-cache-purge-term.php ├── test-cache-ttl-manager-rest.php ├── test-check-for-404-and-remove-cache-headers.php ├── test-client-mu-plugins.php ├── test-core-filters.php ├── test-core.php ├── test-divi-compatibility.php ├── test-jetpack.php ├── test-lib-proxy-ip-utils.php ├── test-performance-lastpostmodified.php ├── test-plugin-fixes.php ├── test-schema.php ├── test-security.php ├── test-stats.php ├── test-vip-cache-manager.php ├── test-vip-integrations.php ├── test-vip-jetpack.php ├── test-vip-mail.php ├── test-vip-plugins.php ├── test-vip-rest-api.php ├── test-wp-cli-ssl.php ├── trait-assertfiledirectory.php ├── trait-assertnumerictype.php ├── trait-expectexception.php ├── trait-expectphpexception.php ├── utils │ ├── parsely-utils.php │ └── utils.php ├── vip-dashboard │ └── test-vip-dashboard.php ├── vip-feed-cache │ ├── test-vip-feed-cache.php │ └── test.rss ├── vip-helpers │ ├── test-class-user-cleanup.php │ ├── test-jetpack-ip-manager.php │ ├── test-vip-roles.php │ ├── test-wpcom-vip-load-plugin.php │ ├── test-wpcom-vip-set-image-quality-for-url.php │ ├── test-wpcomvip-restrictions.php │ └── vip-utils │ │ ├── include-vip-utils-include-plugin.php │ │ ├── test-vip-utils-include-plugin.php │ │ ├── test-vip-utils-is-vip-convenience-domain.php │ │ ├── test-vip-utils-remote-requests.php │ │ ├── test-vip-utils-resized-attachments.php │ │ ├── test-vip-utils-vip-is-jetpack-request.php │ │ ├── test-vip-utils-vip-powered-wpcom-url.php │ │ ├── test-vip-utils-wpcom-vip-file-get-contents.php │ │ ├── test-vip-utils-wpcom-vip-is-feedservice-ua.php │ │ └── test-wpcom-vip-should-load-plugins.php ├── vip-jetpack │ └── connection-pilot │ │ └── test-class-jetpack-connection-pilot.php ├── vip-parsely │ └── Telemetry │ │ └── Tracks │ │ └── test-class-tracks.php ├── vip-support │ ├── test-role.php │ └── test-user.php └── wpcom-vip-two-factor │ └── sms-provider.php ├── two-factor.php ├── vip-cache-manager.php ├── vip-cache-manager ├── api.php ├── js │ └── admin-bar.js ├── ttl-manager.php └── vip-cache-manager.php ├── vip-dashboard.php ├── vip-dashboard ├── assets │ ├── css │ │ └── style.css │ ├── img │ │ └── wpcom-vip-logo.svg │ └── js │ │ └── vip-dashboard.js ├── components │ ├── header.php │ ├── widget-contact.php │ └── widget-welcome.php └── vip-dashboard.php ├── vip-feed-cache.php ├── vip-feed-cache ├── class-vip-go-feed-cache.php └── class-vip-go-feed-transient.php ├── vip-helpers ├── class-jetpack-ip-manager.php ├── class-user-cleanup.php ├── class-vip-backup-user-role-cli.php ├── class-wpcomvip-restrictions.php ├── images │ ├── vip-powered-dark-long.png │ ├── vip-powered-dark-normal.png │ ├── vip-powered-dark-small.png │ ├── vip-powered-light-long.png │ ├── vip-powered-light-normal.png │ └── vip-powered-light-small.png ├── sandbox.php ├── vip-caching.php ├── vip-clean-term-cache.php ├── vip-deprecated.php ├── vip-elasticsearch.php ├── vip-media.php ├── vip-migrations.php ├── vip-mods.php ├── vip-newrelic.php ├── vip-non-production.php ├── vip-notoptions-mitigation.php ├── vip-permastructs.php ├── vip-roles.php ├── vip-stats.php ├── vip-syndication-cache.php ├── vip-utils.php └── vip-wp-cli.php ├── vip-integrations.php ├── vip-integrations └── .gitkeep ├── vip-jetpack ├── connection-pilot │ ├── class-jetpack-connection-attendant.php │ ├── class-jetpack-connection-cli.php │ ├── class-jetpack-connection-controls.php │ └── class-jetpack-connection-pilot.php ├── css │ ├── admin-settings.css │ └── mandatory-settings.css ├── jetpack-mandatory.php ├── jetpack-sso-dummy.php └── vip-jetpack.php ├── vip-light-term-count.php ├── vip-mail.php ├── vip-parsely ├── Telemetry │ ├── Events │ │ ├── track-delete-widget.php │ │ ├── track-option-updated.php │ │ ├── track-settings-page-loaded.php │ │ └── track-widget-updated.php │ ├── Tracks │ │ ├── class-tracks-event.php │ │ └── class-tracks.php │ ├── class-telemetry-system.php │ └── class-telemetry.php └── vip-parsely.php ├── vip-plugins.php ├── vip-plugins ├── css │ └── plugins-ui.css ├── js │ └── plugins-ui.js └── vip-plugins.php ├── vip-rest-api.php ├── vip-support.php ├── vip-support ├── LICENSE ├── class-vip-support-cli.php ├── class-vip-support-role.php ├── class-vip-support-user.php ├── readme.txt └── vip-support.php ├── vip-woocommerce.php ├── vip-woocommerce ├── logging.php └── vip-woocommerce.php ├── vip-wp-cli-to-cron └── limit-wp-cli-command.php ├── wordpress-importer.php ├── wordpress-importer ├── class-wp-import.php ├── compat.php ├── parsers.php ├── parsers │ ├── class-wxr-parser-regex.php │ ├── class-wxr-parser-simplexml.php │ ├── class-wxr-parser-xml.php │ └── class-wxr-parser.php ├── readme.txt └── wordpress-importer.php ├── wp-cli.php ├── wp-cli ├── README.md ├── alloptions.php ├── class-async-scheduler-command.php ├── class-option-autoload.php ├── class-vip-subsites-cli-command.php ├── class-vip-user-cli-command.php ├── media-regenerate.php ├── vip-cache.php ├── vip-data-cleanup.php ├── vip-filesystem.php ├── vip-fixers.php ├── vip-go-convert-to-utf8mb4.php ├── vip-migrations.php └── vip-two-factor.php ├── wp-parsely.php ├── wpcom-vip-two-factor ├── is-jetpack-sso.php ├── set-providers.php └── sms-provider.php └── z-client-mu-plugins.php /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WPVIP MU Plugins", 3 | "dockerComposeFile": "docker-compose.yml", 4 | "service": "wordpress", 5 | "workspaceFolder": "/var/www/html/wp-content/mu-plugins", 6 | "forwardPorts": [80], 7 | "portsAttributes": { 8 | "80": { 9 | "label": "Application", 10 | "onAutoForward": "notify" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.devcontainer/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | wordpress: 3 | image: ghcr.io/automattic/vip-codespaces/wpvip-base:latest 4 | environment: 5 | WORDPRESS_DB_HOST: database 6 | WORDPRESS_DB_USER: wordpress 7 | WORDPRESS_DB_PASSWORD: wordpress 8 | WORDPRESS_DB_NAME: wordpress 9 | WORDPRESS_DEBUG: true 10 | volumes: 11 | - ../:/var/www/html/wp-content/mu-plugins 12 | depends_on: 13 | - database 14 | - memcached 15 | ports: 16 | - 80:80 17 | database: 18 | image: mysql:8.4 19 | command: mysqld --sql-mode=ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION --max_allowed_packet=67M --mysql-native-password=ON 20 | environment: 21 | MYSQL_ROOT_PASSWORD: password 22 | MYSQL_DATABASE: wordpress 23 | MYSQL_USER: wordpress 24 | MYSQL_PASSWORD: wordpress 25 | memcached: 26 | image: memcached:1.6-alpine 27 | command: memcached -m 64 28 | -------------------------------------------------------------------------------- /.github/.stale: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 180 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 60 5 | # Label to use when marking an issue as stale 6 | staleLabel: [Status] Stale 7 | # Comment to post when marking an issue as stale. Set to `false` to disable 8 | markComment: > 9 | This issue has been automatically marked as stale because it has not had 10 | recent activity in the past 90 days. It will be closed in 14 days if no 11 | further activity occurs. Thank you for your contribution. 12 | 13 | Please feel free to re-open and address the feedback and we'll take another look. 14 | # Comment to post when closing a stale issue. Set to `false` to disable 15 | closeComment: true 16 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners 2 | * @Automattic/vip-platform-cantina 3 | 4 | # Leave owners empty for these two 5 | package.json 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## For Automatticians! 2 | 3 | :wave: Just a quick reminder that this is a public repo. Please don't include any internal links or sensitive data (like PII, private code, client names, site URLs, etc. If you're not sure if something is safe to share, please just ask! 4 | 5 | If you're not an Automattician, welcome! We look forward to your contribution! :heart: 6 | 7 | Please remove this section before submitting the issue. 8 | 9 | --- 10 | 11 | ## Expected/Desired Behavior 12 | 13 | Fill with either one: 14 | 15 | 1. Expected behavior for bugs 16 | 1. Desired behavior for improvements/enhancements 17 | 18 | ## Actual Behavior 19 | 20 | How the application currently works. 21 | 22 | ## Steps to Reproduce the Problem 23 | 24 | 1. Step 1 25 | 1. Step 2 26 | 1. Step 3 27 | 28 | ## (Optional) Additional notes 29 | 30 | Any other relevant information to help with debugging/implementation. 31 | -------------------------------------------------------------------------------- /.github/actions/prepare-source/action.yml: -------------------------------------------------------------------------------- 1 | name: Prepare source code for testing 2 | description: Checks out and installs all dependencies 3 | runs: 4 | using: composite 5 | steps: 6 | - name: Check out mu-plugins-ext 7 | uses: actions/checkout@v4.2.2 8 | with: 9 | repository: 'Automattic/vip-go-mu-plugins-ext' 10 | path: 'vip-go-mu-plugins-ext' 11 | 12 | - name: Copy plugins into the source tree 13 | shell: bash 14 | run: 'rsync -r --delete --exclude-from="vip-go-mu-plugins-ext/.dockerignore" vip-go-mu-plugins-ext/* ./' 15 | 16 | - name: Clean up 17 | shell: bash 18 | run: rm -rf vip-go-mu-plugins-ext 19 | 20 | -------------------------------------------------------------------------------- /.github/codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | notify: 3 | after_n_builds: 2 4 | wait_for_ci: true 5 | 6 | coverage: 7 | status: 8 | project: 9 | default: 10 | informational: true 11 | 12 | # Too noisy 13 | github_checks: 14 | annotations: false 15 | -------------------------------------------------------------------------------- /.github/codeql-config.yml: -------------------------------------------------------------------------------- 1 | name: CodeQL Config 2 | 3 | paths: 4 | - search/search-dev-tools/src/ 5 | - .github/ 6 | 7 | paths-ignore: 8 | - node_modules 9 | 10 | queries: 11 | - uses: security-and-quality 12 | -------------------------------------------------------------------------------- /.github/workflows/build-docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Build Docker image 2 | 3 | on: 4 | push: 5 | branches: 6 | - staging 7 | workflow_dispatch: 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | build: 14 | name: Build Docker image 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Request to build Docker image 18 | uses: actions/github-script@v7.0.1 19 | with: 20 | github-token: ${{ secrets.WPCOM_VIP_BOT_TOKEN }} 21 | script: | 22 | github.rest.repos.createDispatchEvent({ 23 | owner: 'automattic', 24 | repo: 'vip-container-images', 25 | event_type: 'build-mu-plugins', 26 | client_payload: {} 27 | }) 28 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: CodeQL Analysis 2 | 3 | on: 4 | push: 5 | branches: 6 | - develop 7 | pull_request: 8 | branches: 9 | - develop 10 | paths: 11 | - "search/search-dev-tools/src/**.js" 12 | - ".github/**.yml" 13 | schedule: 14 | - cron: '24 2 * * 6' 15 | 16 | permissions: 17 | actions: read 18 | contents: read 19 | security-events: write 20 | 21 | jobs: 22 | analyze: 23 | name: Static Code Analysis with CodeQL 24 | runs-on: ubuntu-latest 25 | strategy: 26 | fail-fast: false 27 | matrix: 28 | language: 29 | - javascript 30 | - actions 31 | steps: 32 | - name: Checkout repository 33 | uses: actions/checkout@v4.2.2 34 | 35 | - name: Initialize CodeQL 36 | uses: github/codeql-action/init@v3.28.18 37 | with: 38 | languages: ${{ matrix.language }} 39 | config-file: ./.github/codeql-config.yml 40 | 41 | - name: Perform CodeQL Analysis 42 | uses: github/codeql-action/analyze@v3.28.18 43 | with: 44 | category: "/language:${{matrix.language}}" 45 | -------------------------------------------------------------------------------- /.github/workflows/dependency-review.yml: -------------------------------------------------------------------------------- 1 | name: Dependency Review 2 | 3 | on: 4 | pull_request: 5 | 6 | permissions: 7 | contents: read 8 | 9 | jobs: 10 | dependency-review: 11 | runs-on: ubuntu-latest 12 | name: Review Dependencies 13 | steps: 14 | - name: Harden Runner 15 | uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 16 | with: 17 | egress-policy: block 18 | allowed-endpoints: > 19 | api.deps.dev:443 20 | api.github.com:443 21 | api.securityscorecards.dev:443 22 | github.com:443 23 | 24 | - name: Check out the source code 25 | uses: actions/checkout@v4.2.2 26 | 27 | - name: Review dependencies 28 | uses: actions/dependency-review-action@v4.7.1 29 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: Stale monitor 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 * * *' 6 | 7 | jobs: 8 | stale: 9 | name: Stale 10 | runs-on: ubuntu-latest 11 | permissions: 12 | issues: write 13 | pull-requests: write 14 | steps: 15 | - uses: Automattic/vip-actions/stale@1137b91acf0f5ea4e0db044bcf14ceabed9b068f # trunk 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | 4 | # Secrets directory 5 | .secrets 6 | 7 | # Secret files 8 | jetpack-private.php 9 | 10 | # dev-env related files 11 | /dev-env-plugin.php 12 | 13 | # Local PHPDoc configuration file 14 | # overrides phpdoc.dist.xml 15 | phpdoc.xml 16 | phpdoc 17 | 18 | # Composer 19 | /vendor/ 20 | /output/ 21 | 22 | # npm 23 | node_modules 24 | 25 | # Jetpack dev files 26 | jetpack-*/tools 27 | jetpack-*/bin 28 | 29 | # e2e outputs 30 | /test-results/ 31 | cypress/results/ 32 | e2eStorageState.json 33 | /unique-index-name.php -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "advanced-post-cache"] 2 | path = advanced-post-cache 3 | url = https://github.com/Automattic/advanced-post-cache.git 4 | [submodule "rewrite-rules-inspector"] 5 | path = rewrite-rules-inspector 6 | url = https://github.com/Automattic/rewrite-rules-inspector 7 | [submodule "http-concat"] 8 | path = http-concat 9 | url = https://github.com/Automattic/nginx-http-concat.git 10 | [submodule "lightweight-term-count-update"] 11 | path = lightweight-term-count-update 12 | url = https://github.com/Automattic/lightweight-term-count-update 13 | [submodule "gutenberg-ramp"] 14 | path = gutenberg-ramp 15 | url = https://github.com/Automattic/gutenberg-ramp.git 16 | [submodule "search/elasticpress"] 17 | path = search/elasticpress 18 | url = https://github.com/Automattic/ElasticPress.git 19 | [submodule "jetpack"] 20 | path = jetpack 21 | url = https://github.com/Automattic/jetpack-production.git 22 | [submodule "wp-parsely"] 23 | path = wp-parsely 24 | url = https://github.com/Parsely/wp-parsely.git 25 | [submodule "drop-ins/hyperdb"] 26 | path = drop-ins/hyperdb 27 | url = https://github.com/automattic/hyperdb 28 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | npx lint-staged 4 | -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.php": [ 3 | "phplint", 4 | "vendor/bin/phpcs" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.sonarcloud.properties: -------------------------------------------------------------------------------- 1 | sonar.sources=. 2 | sonar.exclusions=advanced-post-cache/**,akismet/**,bin/**,ci/**,cron-control/**,debug-bar-cron/**,debug-bar/**,drop-ins/**,http-concat/**,jetpack*/**,lightweight-term-count-update/**,query-monitor/**,rewrite-rules-inspector/**,search/elasticpress/**,search/debug-bar-elasticpress/**,search/es-wp-query/**,shared-plugins/**,telemetry/pendo/js/*.js,wordpress-importer/**,wp-parsely*/**,tests/**,__tests__/** 3 | sonar.tests=tests,__tests__ 4 | sonar.cpd.exclusions=errors/** 5 | -------------------------------------------------------------------------------- /000-debug/0-load.php: -------------------------------------------------------------------------------- 1 | Although we strive to create the most secure products possible, we are not perfect. If you happen to find a security vulnerability in one of our services, we would appreciate letting us know and allowing us to respond before disclosing the issue publicly. We take security seriously, and we will try to review and reply to every legitimate security report personally within 24 hours. 4 | 5 | ([Source](https://automattic.com/security/)) 6 | 7 | ## Reporting a Vulnerability 8 | 9 | For responsible disclosure of security issues and to be eligible for our bug bounty program, please submit security issuess via the HackerOne portal: https://hackerone.com/automattic 10 | -------------------------------------------------------------------------------- /__tests__/e2e/.eslintrc.js: -------------------------------------------------------------------------------- 1 | require( '@automattic/eslint-plugin-wpvip/init' ); 2 | 3 | module.exports = { 4 | parserOptions: { 5 | ecmaVersion: 2021, 6 | project: [__dirname + "/tsconfig.json"], 7 | }, 8 | extends: [ 9 | 'plugin:@automattic/wpvip/recommended', 10 | 'plugin:playwright/playwright-test', 11 | 'plugin:deprecation/recommended', 12 | ], 13 | ignorePatterns: [ 'bin/**/*', '*.js' ], 14 | rules: { 15 | '@typescript-eslint/no-non-null-assertion': 'off', 16 | }, 17 | root: true, 18 | }; 19 | -------------------------------------------------------------------------------- /__tests__/e2e/.gitignore: -------------------------------------------------------------------------------- 1 | /e2eStorageState.json 2 | /node_modules/ 3 | /test-results/ 4 | -------------------------------------------------------------------------------- /__tests__/e2e/lib/asana-pharse.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'asana-phrase' { 2 | class Factory { 3 | constructor(generators: unknown[]); 4 | randomPhrase(): string[]; 5 | } 6 | 7 | export function default32BitFactory(): Factory; 8 | export { Factory /*, WordGenerator, Dictionary, NumberRange, dictionaries */ }; 9 | } 10 | -------------------------------------------------------------------------------- /__tests__/e2e/lib/data-helper.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * External dependencies 3 | */ 4 | import phrase from 'asana-phrase'; 5 | 6 | /** 7 | * Given either a string or array of strings, returns a single string with each word in TitleCase. 8 | * 9 | * @param {string[]|string} words Either string or array of strings to be converted to TitleCase. 10 | * @return {string} String with each distinct word converted to TitleCase. 11 | */ 12 | export function toTitleCase( words: string[] | string ): string { 13 | if ( typeof words === 'string' ) { 14 | words = words.trim().split( ' ' ); 15 | } 16 | 17 | const result = words.map( ( word ) => { 18 | return word.charAt( 0 ).toUpperCase() + word.slice( 1 ); 19 | } ); 20 | 21 | return result.join( ' ' ); 22 | } 23 | 24 | /** 25 | * Generates a random phrase in proper case (Sample Sentence Text). 26 | * 27 | * @return {string} Generated text. 28 | */ 29 | export function getRandomPhrase(): string { 30 | const generated: string[] = phrase.default32BitFactory().randomPhrase(); 31 | return toTitleCase( generated ); 32 | } 33 | -------------------------------------------------------------------------------- /__tests__/e2e/lib/pages/page-list-page.ts: -------------------------------------------------------------------------------- 1 | import type { Page } from '@playwright/test'; 2 | 3 | const selectors = { 4 | pageLink: ( pageID: string ) => `#post-${ pageID } a.row-title`, 5 | }; 6 | 7 | export class PageListPage { 8 | private readonly page: Page; 9 | 10 | /** 11 | * Constructs an instance of the component. 12 | * 13 | * @param { Page } page The underlying page 14 | */ 15 | constructor( page: Page ) { 16 | this.page = page; 17 | } 18 | 19 | /** 20 | * Navigate to Page List page 21 | */ 22 | public visit(): Promise { 23 | return this.page.goto( '/wp-admin/edit.php?post_type=page' ); 24 | } 25 | 26 | /** 27 | * Edit Page by ID 28 | * 29 | * @param { string } pageID ID of the page to be edited 30 | */ 31 | public editPageByID( pageID: string ): Promise { 32 | return this.page.click( selectors.pageLink( pageID ) ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /__tests__/e2e/lib/pages/post-list-page.ts: -------------------------------------------------------------------------------- 1 | import type { Page } from '@playwright/test'; 2 | 3 | const selectors = { 4 | postLink: ( postID: string ) => `#post-${ postID } a.row-title`, 5 | }; 6 | 7 | export class PostListPage { 8 | private readonly page: Page; 9 | 10 | /** 11 | * Constructs an instance of the component. 12 | * 13 | * @param { Page } page The underlying page 14 | */ 15 | constructor( page: Page ) { 16 | this.page = page; 17 | } 18 | 19 | /** 20 | * Navigate to Post List page 21 | */ 22 | public visit(): Promise { 23 | return this.page.goto( '/wp-admin/edit.php' ); 24 | } 25 | 26 | /** 27 | * Edit Post by ID 28 | * 29 | * @param {string} postID ID of the post to be edited 30 | */ 31 | public editPostByID( postID: string ): Promise { 32 | return this.page.click( selectors.postLink( postID ) ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /__tests__/e2e/lib/pages/wp-admin-page.ts: -------------------------------------------------------------------------------- 1 | import type { Locator, Page } from '@playwright/test'; 2 | 3 | const selectors = { 4 | adminBar: '#wpadminbar', 5 | }; 6 | 7 | export class WPAdminPage { 8 | private readonly page: Page; 9 | public readonly adminBar: Locator; 10 | 11 | /** 12 | * Constructs an instance of the component. 13 | * 14 | * @param { Page } page The underlying page 15 | */ 16 | constructor( page: Page ) { 17 | this.page = page; 18 | this.adminBar = page.locator( selectors.adminBar ); 19 | } 20 | 21 | /** 22 | * Navigate to WP Admin 23 | */ 24 | public visit(): Promise { 25 | return this.page.goto( '/wp-admin' ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /__tests__/e2e/lib/playwright-helpers.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * External dependencies 3 | */ 4 | import type { Locator, Page } from '@playwright/test'; 5 | 6 | /** 7 | * Returns the list of classes for the given element as a string list. 8 | * 9 | * @param {Locator} locator Element locator 10 | * @return {string[]} Class list 11 | */ 12 | export async function getClassList( locator: Locator ): Promise { 13 | const classList = await locator.evaluate( ( node ) => node.classList ); 14 | return Array.from( Object.values( classList ) ); 15 | } 16 | 17 | /** 18 | * More robust version of `page.goto()`. 19 | * 20 | * @param {Page} page Page object 21 | * @param {string} url URL to navigate to 22 | */ 23 | export function goToPage( page: Page, url: string ): Promise { 24 | return Promise.all( [ 25 | page.goto( url, { waitUntil: 'load' } ), 26 | page.waitForURL( url, { waitUntil: 'load' } ), 27 | ] ); 28 | } 29 | -------------------------------------------------------------------------------- /__tests__/e2e/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vip-go-mu-plugins-e2e", 3 | "private": true, 4 | "version": "1.0.0", 5 | "description": "E2E Tests for mu-plugins", 6 | "scripts": { 7 | "lint": "eslint .", 8 | "pretest": "./bin/setup-env.sh", 9 | "test": "playwright test -c playwright.config.ts", 10 | "posttest": "vip dev-env destroy --slug=e2e-test-site" 11 | }, 12 | "author": "Automattic", 13 | "devDependencies": { 14 | "@automattic/eslint-plugin-wpvip": "^0.13.0", 15 | "@babel/plugin-syntax-decorators": "^7.22.10", 16 | "@playwright/test": "^1.39.0", 17 | "@types/node": "^22.0.0", 18 | "asana-phrase": "^0.0.8", 19 | "eslint": "^8.51.0", 20 | "eslint-plugin-deprecation": "^3.0.0", 21 | "eslint-plugin-playwright": "^2.0.1", 22 | "typescript": "^5.2.2" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /__tests__/e2e/playwright.config.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * External dependencies 3 | */ 4 | import { PlaywrightTestConfig } from '@playwright/test'; 5 | 6 | const config: PlaywrightTestConfig = { 7 | retries: 1, 8 | globalSetup: require.resolve( './lib/global-setup' ), 9 | timeout: 120000, 10 | reporter: process.env.CI ? [ [ 'github' ] ] : 'line', 11 | reportSlowTests: null, 12 | workers: process.env.CI ? 1 : undefined, 13 | use: { 14 | headless: process.env.DEBUG_TESTS !== 'true', 15 | viewport: { width: 1280, height: 1000 }, 16 | ignoreHTTPSErrors: true, 17 | video: 'retain-on-failure', 18 | trace: 'retain-on-failure', 19 | storageState: 'e2eStorageState.json', 20 | baseURL: process.env.E2E_BASE_URL ? process.env.E2E_BASE_URL : 'http://e2e-test-site.vipdev.lndo.site', 21 | }, 22 | }; 23 | 24 | export default config; 25 | -------------------------------------------------------------------------------- /__tests__/e2e/test_media/image_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/vip-go-mu-plugins/15ba43b107f3e065cd7a26fafca7bf449f0754c6/__tests__/e2e/test_media/image_01.jpg -------------------------------------------------------------------------------- /__tests__/e2e/test_media/image_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/vip-go-mu-plugins/15ba43b107f3e065cd7a26fafca7bf449f0754c6/__tests__/e2e/test_media/image_02.jpg -------------------------------------------------------------------------------- /__tests__/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "NodeNext", 5 | "moduleResolution": "NodeNext", 6 | "rootDirs": ["lib", "specs"], 7 | "strict": true, 8 | "esModuleInterop": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "noEmit": true, 11 | "baseUrl": ".", 12 | "noImplicitAny": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /admin-notice.php: -------------------------------------------------------------------------------- 1 | add( 18 | new Admin_Notice( 19 | 'WordPress 5.9 is scheduled to be released on Tuesday, January 25th', 20 | [ 21 | new Date_Condition( '2022-01-01', '2022-02-01' ), 22 | new WP_Version_Condition( '5.8', '5.9' ), 23 | ], 24 | 'wp-5.9' 25 | ) 26 | ); 27 | } 28 | ); 29 | ``` -------------------------------------------------------------------------------- /admin-notice/conditions/class-capability-condition.php: -------------------------------------------------------------------------------- 1 | capabilities = $capabilities ? $capabilities : []; 11 | } 12 | 13 | public function evaluate() { 14 | foreach ( $this->capabilities as $capability ) { 15 | if ( ! current_user_can( $capability ) ) { 16 | return false; 17 | } 18 | } 19 | 20 | return true; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /admin-notice/conditions/class-date-condition.php: -------------------------------------------------------------------------------- 1 | start_date = new \DateTime( $start_date, new \DateTimeZone( 'UTC' ) ); 13 | $this->end_date = new \DateTime( $end_date, new \DateTimeZone( 'UTC' ) ); 14 | $this->decision_date = new \DateTime( $decision_date, new \DateTimeZone( 'UTC' ) ); 15 | } 16 | 17 | public function evaluate() { 18 | return $this->start_date < $this->decision_date && $this->end_date > $this->decision_date; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /admin-notice/conditions/class-expression-condition.php: -------------------------------------------------------------------------------- 1 | condition = $condition; 16 | } 17 | 18 | public function evaluate() { 19 | return (bool) $this->condition; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /admin-notice/conditions/class-wp-version-condition.php: -------------------------------------------------------------------------------- 1 | minimum_version = $minimum_version; 19 | $this->maximum_version = $maximum_version; 20 | } 21 | 22 | public function evaluate() { 23 | $current_version = $GLOBALS['wp_version']; 24 | 25 | if ( $this->minimum_version && version_compare( $current_version, $this->minimum_version, '<' ) ) { 26 | return false; 27 | } 28 | 29 | if ( $this->maximum_version && version_compare( $current_version, $this->maximum_version, '>=' ) ) { 30 | return false; 31 | } 32 | 33 | return true; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /admin-notice/conditions/interface-condition.php: -------------------------------------------------------------------------------- 1 | notice.addEventListener( 'click', vipNoticeClickHandler ) ); 29 | } 30 | 31 | window.onload = (function (oldLoad) { 32 | return function () { 33 | oldLoad && oldLoad(); 34 | registerDismissHooks(); 35 | } 36 | })(window.onload) 37 | -------------------------------------------------------------------------------- /advanced-post-cache.php: -------------------------------------------------------------------------------- 1 | 5 | Order Deny,Allow 6 | Deny from all 7 | 8 | 9 | # Apache 2.4 10 | 11 | Require all denied 12 | 13 | 14 | # Akismet CSS and JS 15 | 16 | 17 | Allow from all 18 | 19 | 20 | 21 | Require all granted 22 | 23 | 24 | 25 | # Akismet images 26 | 27 | 28 | Allow from all 29 | 30 | 31 | 32 | Require all granted 33 | 34 | 35 | -------------------------------------------------------------------------------- /akismet/_inc/akismet-admin.js: -------------------------------------------------------------------------------- 1 | document.addEventListener( 'DOMContentLoaded', function() { 2 | // Prevent aggressive iframe caching in Firefox 3 | var statsIframe = document.getElementById( 'stats-iframe' ); 4 | if ( statsIframe ) { 5 | statsIframe.contentWindow.location.href = statsIframe.src; 6 | } 7 | } ); -------------------------------------------------------------------------------- /akismet/_inc/img/akismet-refresh-logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/vip-go-mu-plugins/15ba43b107f3e065cd7a26fafca7bf449f0754c6/akismet/_inc/img/akismet-refresh-logo@2x.png -------------------------------------------------------------------------------- /akismet/_inc/img/arrow-left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /akismet/_inc/img/icon-external.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /akismet/_inc/img/logo-a-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/vip-go-mu-plugins/15ba43b107f3e065cd7a26fafca7bf449f0754c6/akismet/_inc/img/logo-a-2x.png -------------------------------------------------------------------------------- /akismet/_inc/img/logo-full-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/vip-go-mu-plugins/15ba43b107f3e065cd7a26fafca7bf449f0754c6/akismet/_inc/img/logo-full-2x.png -------------------------------------------------------------------------------- /akismet/index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 |
7 | 8 |
-------------------------------------------------------------------------------- /akismet/views/enter.php: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 | 6 | 7 |

8 |
9 | 10 | 11 |
12 |
13 |
14 |
15 | -------------------------------------------------------------------------------- /akismet/views/get.php: -------------------------------------------------------------------------------- 1 | 0 ) { 9 | $submit_classes_attr = implode( ' ', $classes ); 10 | } 11 | ?> 12 | 13 |
14 | 15 | 16 | 17 | 18 |
19 | -------------------------------------------------------------------------------- /akismet/views/logo.php: -------------------------------------------------------------------------------- 1 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | -------------------------------------------------------------------------------- /akismet/views/predefined.php: -------------------------------------------------------------------------------- 1 |
2 |

3 |

4 | wp-config.php' ); 8 | 9 | ?> 10 |

11 |
-------------------------------------------------------------------------------- /akismet/views/setup.php: -------------------------------------------------------------------------------- 1 |
2 |

3 | __( 'Set up your Akismet account' , 'akismet' ), 'classes' => array( 'akismet-button', 'akismet-is-primary' ) ) ); ?> 4 |
5 | -------------------------------------------------------------------------------- /akismet/views/start.php: -------------------------------------------------------------------------------- 1 | 7 |
8 |
9 |
10 | 11 |
12 |
13 |
14 | 15 |
16 | status, array( 'active', 'active-dunning', 'no-sub', 'missing', 'cancelled', 'suspended' ) ) ) { 21 | Akismet::view( 'connect-jp', compact( 'akismet_user' ) ); 22 | } else { 23 | Akismet::view( 'activate' ); 24 | } 25 | 26 | ?> 27 |
28 |
29 |
-------------------------------------------------------------------------------- /akismet/views/stats.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | true ) ); ?> 5 | 8 |
9 |
10 | 11 | 12 |
-------------------------------------------------------------------------------- /akismet/views/title.php: -------------------------------------------------------------------------------- 1 |
2 |

3 |
-------------------------------------------------------------------------------- /back-compat.php: -------------------------------------------------------------------------------- 1 | " 7 | echo 8 | echo "Example: manage-wp-parsely-subtree.sh 2.4 2.4.1" 9 | echo 10 | echo "If subtree already exists:" 11 | echo " This command will update the wp-parsely-2.4 folder to the tag 2.4.1" 12 | echo "If the subtree does not already exist:" 13 | echo " This command will create a new folder wp-parsely-2.4 using the tag 2.4.1" 14 | exit 1 15 | fi 16 | 17 | tree_version=$1 18 | parsely_tag=$2 19 | 20 | tree_dir="wp-parsely-${tree_version}" 21 | if [ -e "$tree_dir" ]; then 22 | echo "Removing existing wp-parsely folder $tree_dir with tag $parsely_tag" 23 | 24 | rm -rf $tree_dir 25 | fi 26 | 27 | echo "Creating new wp-parsely folder $tree_dir using tag: $parsely_tag" 28 | 29 | wget "https://downloads.wordpress.org/plugin/wp-parsely.$parsely_tag.zip" 30 | unzip "wp-parsely.$parsely_tag.zip" 31 | mv wp-parsely $tree_dir 32 | rm "wp-parsely.$parsely_tag.zip" 33 | -------------------------------------------------------------------------------- /bin/php-lint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | npx phplint '**/*.php' '!vendor/**' '!node_modules/**' '!jetpack*/**' '!wp-parsely*/**' '!drop-ins/wp-memcached/stubs/**' > /dev/null 4 | -------------------------------------------------------------------------------- /bin/upgrade-plugin.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit # exit on error 4 | 5 | if [ $# -lt 1 ]; then 6 | echo "usage: $0 " 7 | exit 1 8 | fi 9 | 10 | PLUGIN_SLUG=$1 11 | 12 | update_wporg_plugin() { 13 | URL=https://downloads.wordpress.org/plugin/${PLUGIN_SLUG}.zip 14 | 15 | echo "Removing current dir: ${PLUGIN_SLUG}" 16 | rm -rf ${PLUGIN_SLUG} 17 | 18 | echo "Downloading latest release: ${URL}" 19 | wget $URL 20 | 21 | echo "Unzipping" 22 | unzip ${PLUGIN_SLUG}.zip 23 | rm ${PLUGIN_SLUG}.zip 24 | 25 | echo 26 | echo "- Don't forget to update $PLUGIN_SLUG.php with the version number." 27 | } 28 | 29 | case $PLUGIN_SLUG in 30 | akismet | debug-bar | query-monitor) 31 | update_wporg_plugin 32 | ;; 33 | 34 | *) 35 | echo "Unknown plugin; skipping" 36 | ;; 37 | esac 38 | -------------------------------------------------------------------------------- /cache/examples/segmentation-maintenance-mode-bypass/vip-config.php: -------------------------------------------------------------------------------- 1 | init(); 16 | } ); 17 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require-dev": { 3 | "phpunit/phpunit": "9.6.19", 4 | "automattic/vipwpcs": "3.0.1", 5 | "phpcompatibility/phpcompatibility-wp": "2.1.7", 6 | "erusev/parsedown": "1.7.4", 7 | "dms/phpunit-arraysubset-asserts": "0.5.0", 8 | "yoast/phpunit-polyfills": "4.0.0", 9 | "johnpbloch/wordpress-core": "6.8.1", 10 | "wp-phpunit/wp-phpunit": "6.8.1", 11 | "wp-cli/wp-cli": "2.12.0" 12 | }, 13 | "config": { 14 | "allow-plugins": { 15 | "dealerdirect/phpcodesniffer-composer-installer": true 16 | }, 17 | "sort-packages": true, 18 | "platform": { 19 | "php": "8.0" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /composer.json.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "name": "automattic/vip-go-mu-plugins", 3 | "description": "The mu-plugins that power the VIP Go Platform", 4 | "require": { 5 | "php": "^7.4 || ^8.0" 6 | }, 7 | "repositories": [ 8 | { 9 | "type": "vcs", 10 | "url": "https://github.com/automattic/vip-go-mu-plugins-built" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /cron-control/.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners 2 | * @Automattic/vip-platform-cantina 3 | -------------------------------------------------------------------------------- /cron-control/.github/checkstyle-problem-matcher.json: -------------------------------------------------------------------------------- 1 | { 2 | "problemMatcher": [ 3 | { 4 | "owner": "phpcs", 5 | "severity": "error", 6 | "pattern": [ 7 | { 8 | "regexp": "^$", 9 | "file": 1 10 | }, 11 | { 12 | "regexp": "+)$", 13 | "line": 1, 14 | "column": 2, 15 | "severity": 3, 16 | "message": 4, 17 | "code": 5, 18 | "loop": true 19 | } 20 | ] 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /cron-control/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - directory: / 4 | open-pull-requests-limit: 15 5 | package-ecosystem: composer 6 | schedule: 7 | interval: daily 8 | 9 | - directory: / 10 | open-pull-requests-limit: 15 11 | package-ecosystem: github-actions 12 | schedule: 13 | interval: daily 14 | 15 | - directory: / 16 | open-pull-requests-limit: 15 17 | package-ecosystem: npm 18 | schedule: 19 | interval: daily 20 | -------------------------------------------------------------------------------- /cron-control/.github/workflows/ci-grunt.yaml: -------------------------------------------------------------------------------- 1 | name: CI (Grunt) 2 | 3 | on: 4 | push: 5 | workflow_dispatch: 6 | 7 | concurrency: 8 | group: ci-grunt-${{ github.ref }} 9 | cancel-in-progress: true 10 | 11 | env: 12 | NODE_VERSION: "18" 13 | 14 | jobs: 15 | build: 16 | if: "!contains(github.event.head_commit.message, '[ci skip]')" 17 | name: Run Grunt tasks 18 | runs-on: ubuntu-latest 19 | steps: 20 | - name: Check out source code 21 | uses: actions/checkout@v3.3.0 22 | 23 | - name: Set up Node.js environment 24 | uses: actions/setup-node@v3.6.0 25 | with: 26 | node-version: ${{ env.NODE_VERSION }} 27 | caching: true 28 | 29 | - name: Install dependencies 30 | run: npm ci --ignore-scripts 31 | 32 | - name: Run postinstall scripts 33 | run: npm rebuild && npm run prepare --if-present 34 | 35 | - name: Run build tasks 36 | run: npm run build 37 | -------------------------------------------------------------------------------- /cron-control/.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | .DS_Store 3 | Thumbs.db 4 | wp-cli.local.yml 5 | node_modules/ 6 | *.sql 7 | *.tar.gz 8 | *.zip 9 | .phpunit.result.cache 10 | -------------------------------------------------------------------------------- /cron-control/.nvmrc: -------------------------------------------------------------------------------- 1 | 18.13 2 | -------------------------------------------------------------------------------- /cron-control/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "automattic/cron-control", 3 | "description": "Execute WordPress cron events in parallel, with custom event storage for high-volume cron.", 4 | "license": "GPL-2.0", 5 | "require": { 6 | "php": ">=7.4.0" 7 | }, 8 | "require-dev": { 9 | "dealerdirect/phpcodesniffer-composer-installer": "1.0.0", 10 | "phpcompatibility/phpcompatibility-wp": "2.1.4", 11 | "phpunit/phpunit": "9.5.28", 12 | "wp-coding-standards/wpcs": "^2.3", 13 | "johnpbloch/wordpress-core": "6.1.1", 14 | "wp-phpunit/wp-phpunit": "6.1.1", 15 | "yoast/phpunit-polyfills": "1.1.0", 16 | "wp-cli/wp-cli": "*" 17 | }, 18 | "config": { 19 | "sort-packages": true, 20 | "allow-plugins": { 21 | "dealerdirect/phpcodesniffer-composer-installer": true 22 | }, 23 | "platform": { 24 | "php": "7.4" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /cron-control/cron-control.php: -------------------------------------------------------------------------------- 1 | class_init(); 33 | } 34 | 35 | return self::$__instances[ $caller ]; 36 | } 37 | 38 | /** 39 | * Singleton constructor 40 | */ 41 | protected function __construct() {} 42 | 43 | /** 44 | * PLUGIN SETUP 45 | */ 46 | 47 | /** 48 | * Register hooks 49 | */ 50 | protected function class_init() {} 51 | } 52 | -------------------------------------------------------------------------------- /cron-control/includes/wp-cli/class-main.php: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | ./__tests__/unit-tests/ 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /cron-control/phpunit.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | ./__tests__/unit-tests/ 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /cron/cron-control/.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners 2 | * @Automattic/vip-platform-cantina 3 | -------------------------------------------------------------------------------- /cron/cron-control/.github/checkstyle-problem-matcher.json: -------------------------------------------------------------------------------- 1 | { 2 | "problemMatcher": [ 3 | { 4 | "owner": "phpcs", 5 | "severity": "error", 6 | "pattern": [ 7 | { 8 | "regexp": "^$", 9 | "file": 1 10 | }, 11 | { 12 | "regexp": "+)$", 13 | "line": 1, 14 | "column": 2, 15 | "severity": 3, 16 | "message": 4, 17 | "code": 5, 18 | "loop": true 19 | } 20 | ] 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /cron/cron-control/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - directory: / 4 | open-pull-requests-limit: 15 5 | package-ecosystem: composer 6 | schedule: 7 | interval: daily 8 | 9 | - directory: / 10 | open-pull-requests-limit: 15 11 | package-ecosystem: github-actions 12 | schedule: 13 | interval: daily 14 | 15 | - directory: / 16 | open-pull-requests-limit: 15 17 | package-ecosystem: npm 18 | schedule: 19 | interval: daily 20 | -------------------------------------------------------------------------------- /cron/cron-control/.github/workflows/ci-grunt.yaml: -------------------------------------------------------------------------------- 1 | name: CI (Grunt) 2 | 3 | on: 4 | push: 5 | workflow_dispatch: 6 | 7 | concurrency: 8 | group: ci-grunt-${{ github.ref }} 9 | cancel-in-progress: true 10 | 11 | env: 12 | NODE_VERSION: "18" 13 | 14 | jobs: 15 | build: 16 | name: Run Grunt tasks 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Check out source code 20 | uses: actions/checkout@v3.3.0 21 | 22 | - name: Set up Node.js environment 23 | uses: actions/setup-node@v3.6.0 24 | with: 25 | node-version: ${{ env.NODE_VERSION }} 26 | cache: npm 27 | 28 | - name: Install dependencies 29 | run: npm ci --ignore-scripts 30 | 31 | - name: Run postinstall scripts 32 | run: npm rebuild && npm run prepare --if-present 33 | 34 | - name: Run build tasks 35 | run: npm run build 36 | -------------------------------------------------------------------------------- /cron/cron-control/.github/workflows/phpcs.yaml: -------------------------------------------------------------------------------- 1 | name: Code Style Check 2 | 3 | on: 4 | push: 5 | workflow_dispatch: 6 | 7 | concurrency: 8 | group: csc-${{ github.ref }} 9 | cancel-in-progress: true 10 | 11 | jobs: 12 | codestyle: 13 | name: Run code style check 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Check out source code 17 | uses: actions/checkout@v3.3.0 18 | 19 | - name: Set up PHP 20 | uses: shivammathur/setup-php@v2 21 | with: 22 | php-version: 8.1 23 | 24 | - name: Install PHP Dependencies 25 | uses: ramsey/composer-install@3.0.0 26 | 27 | - name: Add error matcher 28 | run: echo "::add-matcher::$(pwd)/.github/checkstyle-problem-matcher.json" 29 | 30 | - name: Run style check 31 | run: vendor/bin/phpcs --report=checkstyle 32 | -------------------------------------------------------------------------------- /cron/cron-control/.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | .DS_Store 3 | Thumbs.db 4 | wp-cli.local.yml 5 | node_modules/ 6 | *.sql 7 | *.tar.gz 8 | *.zip 9 | .phpunit.result.cache 10 | -------------------------------------------------------------------------------- /cron/cron-control/.nvmrc: -------------------------------------------------------------------------------- 1 | 18.13 2 | -------------------------------------------------------------------------------- /cron/cron-control/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "automattic/cron-control", 3 | "description": "Execute WordPress cron events in parallel, with custom event storage for high-volume cron.", 4 | "license": "GPL-2.0", 5 | "require": { 6 | "php": ">=7.4.0" 7 | }, 8 | "require-dev": { 9 | "dealerdirect/phpcodesniffer-composer-installer": "1.0.0", 10 | "phpcompatibility/phpcompatibility-wp": "2.1.4", 11 | "phpunit/phpunit": "9.5.28", 12 | "wp-coding-standards/wpcs": "^2.3", 13 | "johnpbloch/wordpress-core": "6.1.1", 14 | "wp-phpunit/wp-phpunit": "6.1.1", 15 | "yoast/phpunit-polyfills": "1.1.0", 16 | "wp-cli/wp-cli": "*" 17 | }, 18 | "config": { 19 | "sort-packages": true, 20 | "allow-plugins": { 21 | "dealerdirect/phpcodesniffer-composer-installer": true 22 | }, 23 | "platform": { 24 | "php": "7.4" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /cron/cron-control/cron-control.php: -------------------------------------------------------------------------------- 1 | class_init(); 33 | } 34 | 35 | return self::$__instances[ $caller ]; 36 | } 37 | 38 | /** 39 | * Singleton constructor 40 | */ 41 | protected function __construct() {} 42 | 43 | /** 44 | * PLUGIN SETUP 45 | */ 46 | 47 | /** 48 | * Register hooks 49 | */ 50 | protected function class_init() {} 51 | } 52 | -------------------------------------------------------------------------------- /cron/cron-control/includes/wp-cli/class-main.php: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | ./__tests__/unit-tests/ 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /cron/cron-control/phpunit.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | ./__tests__/unit-tests/ 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /drop-ins/db.php: -------------------------------------------------------------------------------- 1 | = 7.4" 7 | }, 8 | "require-dev": { 9 | "automattic/vipwpcs": "^2.3", 10 | "dealerdirect/phpcodesniffer-composer-installer": "^0.7.2", 11 | "phpcompatibility/phpcompatibility-wp": "^2.1", 12 | "phpunit/phpunit": "^9.5", 13 | "vimeo/psalm": "^5.0", 14 | "wp-phpunit/wp-phpunit": "^6.1", 15 | "yoast/phpunit-polyfills": "^1.1" 16 | }, 17 | "license": "MIT", 18 | "authors": [ 19 | { 20 | "name": "Volodymyr Kolesnykov", 21 | "email": "volodymyr@wildwolf.name" 22 | } 23 | ], 24 | "config": { 25 | "sort-packages": true, 26 | "platform": { 27 | "php": "7.4" 28 | }, 29 | "allow-plugins": { 30 | "dealerdirect/phpcodesniffer-composer-installer": true 31 | } 32 | }, 33 | "scripts": { 34 | "phpcs": "phpcs", 35 | "phpcs:fix": "phpcbf", 36 | "psalm": "psalm" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /drop-ins/wp-memcached/phpcs.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | Custom ruleset for VIP Go mu-plugins 4 | 5 | . 6 | 7 | /\.git/* 8 | /vendor/* 9 | /stubs/* 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /drop-ins/wp-memcached/phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | ./tests/ 13 | 14 | 15 | 16 | 17 | 18 | ./object-cache.php 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /drop-ins/wp-memcached/psalm.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /drop-ins/wp-memcached/tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | check(); 29 | $hc->render(); 30 | }, PHP_INT_MIN ); 31 | } 32 | -------------------------------------------------------------------------------- /integrations/enums.php: -------------------------------------------------------------------------------- 1 | get_env_config()['version'] ) ) { 16 | $this->version = $this->get_env_config()['version']; 17 | } elseif ( defined( 'VIP_JETPACK_PINNED_VERSION' ) ) { 18 | $this->version = constant( 'VIP_JETPACK_PINNED_VERSION' ); 19 | } else { 20 | $this->version = vip_default_jetpack_version(); 21 | } 22 | } 23 | 24 | public function load(): void { 25 | if ( $this->is_loaded() ) { 26 | return; 27 | } 28 | 29 | // Pass through to the old code for now which will respect all existing constants 30 | if ( ! defined( 'WP_INSTALLING' ) ) { 31 | vip_jetpack_load(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/helpers/environment.php: -------------------------------------------------------------------------------- 1 | early_init(); 16 | -------------------------------------------------------------------------------- /lib/helpers/wp-cli-db/README.md: -------------------------------------------------------------------------------- 1 | # WP-CLI `wp db` Command Helper 2 | 3 | Add necessary configuration details prior to handing off control to the [wp-cli/db-command](https://github.com/wp-cli/db-command/). 4 | 5 | **IMPORTANT:** Everything in this directory runs **before** WordPress loads, so no wp-specific functions may be used (actions, filters, etc.) 6 | -------------------------------------------------------------------------------- /lib/helpers/wp-cli-db/class-vip-db-command.php: -------------------------------------------------------------------------------- 1 | hook ) { 13 | return false; 14 | } 15 | 16 | return $event; 17 | } 18 | add_action( 'schedule_event', __NAMESPACE__ . '\disable_pings' ); 19 | 20 | function pre_disable_pings( $scheduled, $event ) { 21 | if ( null !== $scheduled ) { 22 | return $scheduled; 23 | } 24 | 25 | if ( 'do_pings' === $event->hook ) { 26 | return false; 27 | } 28 | 29 | return $scheduled; 30 | } 31 | // Hooking at 0 to get in before cron control on pre_schedule_event 32 | add_filter( 'pre_schedule_event', __NAMESPACE__ . '\pre_disable_pings', 0, 2 ); 33 | 34 | // Don't allow new _encloseme metas 35 | function block_encloseme_metadata_filter( $should_update, $object_id, $meta_key ) { 36 | if ( '_encloseme' === $meta_key ) { 37 | $should_update = false; 38 | } 39 | 40 | return $should_update; 41 | } 42 | add_filter( 'add_post_metadata', __NAMESPACE__ . '\block_encloseme_metadata_filter', 10, 3 ); 43 | -------------------------------------------------------------------------------- /performance/media.php: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 15 | 16 | ./tests/ 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /prometheus-collectors/class-error-stats-collector.php: -------------------------------------------------------------------------------- 1 | error_counter = $registry->getOrRegisterCounter( 16 | 'error', 17 | 'count', 18 | 'Number of runtime errors', 19 | [ 'site_id', 'error_type' ] 20 | ); 21 | add_action( 'php_error_handler', [ $this, 'php_error_handler' ], 10, 4 ); 22 | } 23 | 24 | public function php_error_handler( $error_type, $message, $file, $line ): void { 25 | $this->error_counter->inc( [ Plugin::get_instance()->get_site_label(), (string) $error_type ] ); 26 | } 27 | 28 | public function collect_metrics(): void { 29 | /* Do nothing */ 30 | } 31 | 32 | public function process_metrics(): void { 33 | /* Do nothing */ 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /prometheus-collectors/class-multisite-stats-collector.php: -------------------------------------------------------------------------------- 1 | network_site_gauge = $registry->getOrRegisterGauge( 17 | 'site', 18 | 'count', 19 | 'Number of network sites', 20 | [ 'status' ] 21 | ); 22 | } 23 | } 24 | 25 | public function collect_metrics(): void { 26 | if ( ! $this->network_site_gauge ) { 27 | return; 28 | } 29 | 30 | $sites_count = wp_count_sites(); 31 | 32 | if ( ! empty( $sites_count ) ) { 33 | foreach ( $sites_count as $status => $count ) { 34 | if ( 'all' !== $status ) { 35 | $this->network_site_gauge->set( $count, [ $status ] ); 36 | } 37 | } 38 | } 39 | } 40 | 41 | public function process_metrics(): void { 42 | /* Do nothing */ 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /prometheus/README.md: -------------------------------------------------------------------------------- 1 | # Prometheus Metrics 2 | 3 | MU-Plugins supports collecting and shipping internal metrics to Prometheus. 4 | 5 | This system is intended for use by WPVIP to monitor the operation of sites and is not suitable for customer use. 6 | 7 | ## Stats Endpoint 8 | 9 | Prometheus metrics are exposed at `/.vip-prom-metrics`. 10 | 11 | ## Collectors 12 | 13 | Stat collection is implemented as Collectors (see the `prometheus-collectors` directory). Each Collector implements `CollectorInterface` and is responsible for collecting the relevant metrics. 14 | 15 | For real-time metrics, like recording specific actions, implement a method in the Collector that is called directly or via WP-hook. 16 | 17 | For "aggregated" metrics collected on an interval (like post counts), implement `collect_metrics()`, which will be run on cron. 18 | 19 | ### Registering Collectors 20 | 21 | Collectors must be registered via the `vip_prometheus_collectors` hook: 22 | 23 | ``` 24 | add_filter( 'vip_prometheus_collectors', function ( $collectors ) { 25 | $collectors['my_collector_name'] = new Collector(); 26 | 27 | return $collectors; 28 | } ); 29 | ``` 30 | -------------------------------------------------------------------------------- /prometheus/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "automattic/prometheus", 3 | "require": { 4 | "promphp/prometheus_client_php": "^2.6" 5 | }, 6 | "autoload": { 7 | "classmap": [ 8 | "inc/" 9 | ] 10 | }, 11 | "config": { 12 | "sort-packages": true, 13 | "platform": { 14 | "php": "7.4" 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /prometheus/inc/class-collectorinterface.php: -------------------------------------------------------------------------------- 1 | $baseDir . '/inc/class-collectorinterface.php', 10 | 'Automattic\\VIP\\Prometheus\\Plugin' => $baseDir . '/inc/class-plugin.php', 11 | 'Automattic\\VIP\\Prometheus\\SafeAdapter' => $baseDir . '/inc/class-safeadapter.php', 12 | 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 13 | ); 14 | -------------------------------------------------------------------------------- /prometheus/vendor/composer/autoload_namespaces.php: -------------------------------------------------------------------------------- 1 | array($vendorDir . '/promphp/prometheus_client_php/src/Prometheus'), 10 | ); 11 | -------------------------------------------------------------------------------- /prometheus/vendor/composer/platform_check.php: -------------------------------------------------------------------------------- 1 | = 70200)) { 8 | $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.0". You are running ' . PHP_VERSION . '.'; 9 | } 10 | 11 | if ($issues) { 12 | if (!headers_sent()) { 13 | header('HTTP/1.1 500 Internal Server Error'); 14 | } 15 | if (!ini_get('display_errors')) { 16 | if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { 17 | fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); 18 | } elseif (!headers_sent()) { 19 | echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; 20 | } 21 | } 22 | trigger_error( 23 | 'Composer detected issues in your platform: ' . implode(' ', $issues), 24 | E_USER_ERROR 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /prometheus/vendor/promphp/prometheus_client_php/phpstan.neon.dist: -------------------------------------------------------------------------------- 1 | parameters: 2 | level: 8 3 | paths: 4 | - src 5 | - tests 6 | reportUnmatchedIgnoredErrors: false 7 | ignoreErrors: 8 | - 9 | # REDIS stuff only runs with it available 10 | '#Constant REDIS_HOST not found\.#' 11 | -------------------------------------------------------------------------------- /prometheus/vendor/promphp/prometheus_client_php/src/Prometheus/Exception/MetricNotFoundException.php: -------------------------------------------------------------------------------- 1 | menu( array( 14 | 'id' => 'qm-apcu-cache', 15 | 'href' => '#qm-apcu-cache', 16 | 'title' => esc_html__( 'APCU Hot-Cache', 'query-monitor' ), 17 | )); 18 | 19 | return $menu; 20 | } 21 | 22 | public function output() { 23 | ?> 24 |
25 |
26 | APCU Hot-Caching is currently disabled'; 30 | } else { 31 | $apc_cache_interceptor->stats(); 32 | } 33 | ?> 34 |
35 |
36 | db_connections; 33 | if ( ! is_array( $db_connections ) || empty( $db_connections ) ) { 34 | return; 35 | } 36 | 37 | $elapsed = 0; 38 | foreach ( $db_connections as $conn ) { 39 | $this->data->db_connections['connections'][] = $conn; 40 | 41 | if ( isset( $conn['elapsed'] ) ) { 42 | $elapsed += $conn['elapsed']; 43 | } 44 | } 45 | $this->data->db_connections['total_connection_time'] = $elapsed; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /qm-plugins/qm-db-connections/class-qm-data-db-connections.php: -------------------------------------------------------------------------------- 1 | get_stats(); 27 | $this->data->operations = $stats['operations'] ?? null; 28 | $this->data->groups = $stats['groups'] ?? null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /qm-plugins/qm-object-cache/collectors/class-qm-collector-object-cache-slow-ops.php: -------------------------------------------------------------------------------- 1 | get_stats(); 27 | $this->data->slow_ops = $stats['slow-ops'] ?? null; 28 | $this->data->slow_ops_groups = $stats['slow-ops-groups'] ?? null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /qm-plugins/qm-object-cache/collectors/class-qm-collector-object-cache.php: -------------------------------------------------------------------------------- 1 | get_stats(); 26 | 27 | $this->data->totals = $stats['totals'] ?? null; 28 | $this->data->operation_counts = $stats['operation_counts'] ?? null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /qm-plugins/qm-object-cache/readme.md: -------------------------------------------------------------------------------- 1 | # Query Monitor: Object Cache 2 | 3 | 4 | ![screenshot](screenshot-1.png) -------------------------------------------------------------------------------- /qm-plugins/qm-vip/class-qm-data-vip.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /query-monitor/assets/icons/arrow-down.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /query-monitor/assets/icons/edit.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /query-monitor/assets/icons/external.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /query-monitor/assets/icons/filter.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /query-monitor/assets/icons/image-rotate-left.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /query-monitor/assets/icons/image-rotate-right.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /query-monitor/assets/icons/info.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /query-monitor/assets/icons/no-alt.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /query-monitor/assets/icons/warning.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /query-monitor/assets/icons/yes-alt.svg: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /query-monitor/classes/Component.php: -------------------------------------------------------------------------------- 1 | data; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /query-monitor/classes/Output.php: -------------------------------------------------------------------------------- 1 | collector = $collector; 27 | } 28 | 29 | /** 30 | * @return mixed 31 | */ 32 | abstract public function get_output(); 33 | 34 | /** 35 | * @return void 36 | */ 37 | public function output() { 38 | // nothing 39 | } 40 | 41 | /** 42 | * @return QM_Collector 43 | */ 44 | public function get_collector() { 45 | return $this->collector; 46 | } 47 | 48 | /** 49 | * @return QM_Timer|null 50 | */ 51 | final public function get_timer() { 52 | return $this->timer; 53 | } 54 | 55 | /** 56 | * @param QM_Timer $timer 57 | * @return void 58 | */ 59 | final public function set_timer( QM_Timer $timer ) { 60 | $this->timer = $timer; 61 | } 62 | 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /query-monitor/collectors/assets_styles.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | public function get_concerned_filters() { 24 | return array( 25 | 'print_styles_array', 26 | 'style_loader_src', 27 | 'style_loader_tag', 28 | ); 29 | } 30 | } 31 | 32 | /** 33 | * @param array $collectors 34 | * @param QueryMonitor $qm 35 | * @return array 36 | */ 37 | function register_qm_collector_assets_styles( array $collectors, QueryMonitor $qm ) { 38 | $collectors['assets_styles'] = new QM_Collector_Assets_Styles(); 39 | return $collectors; 40 | } 41 | 42 | add_filter( 'qm/collectors', 'register_qm_collector_assets_styles', 10, 2 ); 43 | -------------------------------------------------------------------------------- /query-monitor/data/admin.php: -------------------------------------------------------------------------------- 1 | 21 | * @phpstan-var array{}|array{ 22 | * columns_filter: string, 23 | * sortables_filter: string, 24 | * column_action: string, 25 | * class_name?: string, 26 | * } 27 | */ 28 | public $list_table; 29 | 30 | /** 31 | * @var string 32 | */ 33 | public $pagenow; 34 | 35 | /** 36 | * @var string 37 | */ 38 | public $taxnow; 39 | 40 | /** 41 | * @var string 42 | */ 43 | public $typenow; 44 | } 45 | -------------------------------------------------------------------------------- /query-monitor/data/block_editor.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | public $all_dynamic_blocks; 13 | 14 | /** 15 | * @var bool 16 | */ 17 | public $has_block_context; 18 | 19 | /** 20 | * @var bool 21 | */ 22 | public $has_block_timing; 23 | 24 | /** 25 | * @var array|null 26 | */ 27 | public $post_blocks; 28 | 29 | /** 30 | * @var bool 31 | */ 32 | public $post_has_blocks; 33 | 34 | /** 35 | * @var int 36 | */ 37 | public $total_blocks; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /query-monitor/data/cache.php: -------------------------------------------------------------------------------- 1 | 31 | */ 32 | public $stats; 33 | 34 | /** 35 | * @var array 36 | */ 37 | public $object_cache_extensions; 38 | 39 | /** 40 | * @var array 41 | */ 42 | public $opcode_cache_extensions; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /query-monitor/data/caps.php: -------------------------------------------------------------------------------- 1 | > 11 | * @phpstan-var list, 13 | * filtered_trace: list>, 14 | * component: QM_Component, 15 | * result: bool, 16 | * parts: list, 17 | * name: string, 18 | * user: string, 19 | * }> 20 | */ 21 | public $caps; 22 | 23 | /** 24 | * @var array 25 | */ 26 | public $parts; 27 | 28 | /** 29 | * @var array 30 | */ 31 | public $users; 32 | 33 | /** 34 | * @var array 35 | */ 36 | public $components; 37 | } 38 | -------------------------------------------------------------------------------- /query-monitor/data/conditionals.php: -------------------------------------------------------------------------------- 1 | > 11 | * @phpstan-var array{ 12 | * true: list, 13 | * false: list, 14 | * na: list, 15 | * } 16 | */ 17 | public $conds; 18 | } 19 | -------------------------------------------------------------------------------- /query-monitor/data/db_callers.php: -------------------------------------------------------------------------------- 1 | > 11 | * @phpstan-var array, 15 | * }> 16 | */ 17 | public $times = array(); 18 | } 19 | -------------------------------------------------------------------------------- /query-monitor/data/db_components.php: -------------------------------------------------------------------------------- 1 | > 11 | * @phpstan-var array, 14 | * component: string, 15 | * }> 16 | */ 17 | public $times; 18 | } 19 | -------------------------------------------------------------------------------- /query-monitor/data/db_dupes.php: -------------------------------------------------------------------------------- 1 | > 16 | */ 17 | public $dupe_sources; 18 | 19 | /** 20 | * @var array> 21 | */ 22 | public $dupe_callers; 23 | 24 | /** 25 | * @var array> 26 | */ 27 | public $dupe_components; 28 | 29 | /** 30 | * @var array> 31 | */ 32 | public $dupes; 33 | 34 | /** 35 | * @var array 36 | */ 37 | public $dupe_times; 38 | } 39 | -------------------------------------------------------------------------------- /query-monitor/data/db_queries.php: -------------------------------------------------------------------------------- 1 | > 21 | */ 22 | public $errors; 23 | 24 | /** 25 | * @var ?array> 26 | */ 27 | public $expensive; 28 | 29 | /** 30 | * @var array> 31 | */ 32 | public $rows; 33 | 34 | /** 35 | * @var bool 36 | */ 37 | public $has_result; 38 | 39 | /** 40 | * @var bool 41 | */ 42 | public $has_trace; 43 | 44 | /** 45 | * @var bool 46 | */ 47 | public $has_main_query; 48 | 49 | /** 50 | * @var ?array> 51 | * @phpstan-var ?array, 55 | * }> 56 | */ 57 | public $times = array(); 58 | 59 | /** 60 | * @var ?array> 61 | */ 62 | public $dupes; 63 | } 64 | -------------------------------------------------------------------------------- /query-monitor/data/doing_it_wrong.php: -------------------------------------------------------------------------------- 1 | > 11 | * @phpstan-var array>, 14 | * message: string, 15 | * component: QM_Component, 16 | * }> 17 | */ 18 | public $actions; 19 | } 20 | -------------------------------------------------------------------------------- /query-monitor/data/fallback.php: -------------------------------------------------------------------------------- 1 | > 11 | * @phpstan-var list, 16 | * }>, 17 | * parts: list, 18 | * components: array, 19 | * }> 20 | */ 21 | public $hooks; 22 | 23 | /** 24 | * @var array 25 | */ 26 | public $parts; 27 | 28 | /** 29 | * @var array 30 | */ 31 | public $components; 32 | 33 | /** 34 | * @var bool 35 | */ 36 | public $all_hooks; 37 | } 38 | -------------------------------------------------------------------------------- /query-monitor/data/http.php: -------------------------------------------------------------------------------- 1 | > 11 | * @phpstan-var array, 13 | * component: QM_Component, 14 | * filtered_trace: list>, 15 | * info: array|null, 16 | * host: string, 17 | * local: bool, 18 | * ltime: float, 19 | * redirected_to: string|null, 20 | * response: mixed[]|WP_Error, 21 | * type: string, 22 | * url: string, 23 | * }> 24 | */ 25 | public $http; 26 | 27 | /** 28 | * @var float 29 | */ 30 | public $ltime; 31 | 32 | /** 33 | * @var array> 34 | * @phpstan-var array{ 35 | * alert?: list, 36 | * warning?: list, 37 | * } 38 | */ 39 | public $errors; 40 | } 41 | -------------------------------------------------------------------------------- /query-monitor/data/languages.php: -------------------------------------------------------------------------------- 1 | >> 11 | * @phpstan-var array> 19 | */ 20 | public $languages; 21 | 22 | /** 23 | * @var string 24 | */ 25 | public $locale; 26 | 27 | /** 28 | * @var string 29 | */ 30 | public $user_locale; 31 | 32 | /** 33 | * @var string 34 | */ 35 | public $determined_locale; 36 | 37 | /** 38 | * @var string 39 | */ 40 | public $language_attributes; 41 | 42 | /** 43 | * @var string 44 | */ 45 | public $mlp_language; 46 | 47 | /** 48 | * @var string 49 | */ 50 | public $pll_language; 51 | 52 | /** 53 | * @var int 54 | */ 55 | public $total_size; 56 | } 57 | -------------------------------------------------------------------------------- /query-monitor/data/logger.php: -------------------------------------------------------------------------------- 1 | 11 | * @phpstan-var array 12 | */ 13 | public $counts; 14 | 15 | /** 16 | * @var array> 17 | * @phpstan-var list 23 | */ 24 | public $logs; 25 | 26 | /** 27 | * @var array 28 | */ 29 | public $components; 30 | } 31 | -------------------------------------------------------------------------------- /query-monitor/data/multisite.php: -------------------------------------------------------------------------------- 1 | > 11 | * @phpstan-var list 17 | */ 18 | public $switches; 19 | } 20 | -------------------------------------------------------------------------------- /query-monitor/data/overview.php: -------------------------------------------------------------------------------- 1 | 46 | */ 47 | public $current_user; 48 | 49 | /** 50 | * @var ?array 51 | */ 52 | public $switched_user; 53 | 54 | /** 55 | * @var bool 56 | */ 57 | public $display_time_usage_warning; 58 | 59 | /** 60 | * @var bool 61 | */ 62 | public $display_memory_usage_warning; 63 | 64 | /** 65 | * @var bool 66 | */ 67 | public $is_admin; 68 | 69 | } 70 | -------------------------------------------------------------------------------- /query-monitor/data/php_errors.php: -------------------------------------------------------------------------------- 1 | >|null, 17 | * component: QM_Component, 18 | * calls: int, 19 | * } 20 | * @phpstan-type errorObjects array> 21 | */ 22 | class QM_Data_PHP_Errors extends QM_Data { 23 | /** 24 | * @var array 25 | */ 26 | public $components; 27 | 28 | /** 29 | * @var array>> 30 | * @phpstan-var errorObjects 31 | */ 32 | public $errors; 33 | 34 | /** 35 | * @var array>> 36 | * @phpstan-var errorObjects 37 | */ 38 | public $suppressed; 39 | 40 | /** 41 | * @var array>> 42 | * @phpstan-var errorObjects 43 | */ 44 | public $silenced; 45 | } 46 | -------------------------------------------------------------------------------- /query-monitor/data/raw_request.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | public $request; 13 | 14 | /** 15 | * @var array 16 | */ 17 | public $response; 18 | } 19 | -------------------------------------------------------------------------------- /query-monitor/data/redirect.php: -------------------------------------------------------------------------------- 1 | 11 | * @phpstan-var array{ 12 | * title: string, 13 | * data: WP_User|false, 14 | * } 15 | */ 16 | public $user; 17 | 18 | /** 19 | * @var array> 20 | */ 21 | public $multisite; 22 | 23 | /** 24 | * @var array 25 | */ 26 | public $request; 27 | 28 | /** 29 | * @var array 30 | */ 31 | public $qvars; 32 | 33 | /** 34 | * @var array 35 | */ 36 | public $plugin_qvars; 37 | 38 | /** 39 | * @var array 40 | */ 41 | public $queried_object; 42 | 43 | /** 44 | * @var string 45 | */ 46 | public $request_method; 47 | 48 | /** 49 | * @var array 50 | */ 51 | public $matching_rewrites; 52 | } 53 | -------------------------------------------------------------------------------- /query-monitor/data/timing.php: -------------------------------------------------------------------------------- 1 | > 11 | */ 12 | public $warning; 13 | 14 | /** 15 | * @var array> 16 | */ 17 | public $timing; 18 | } 19 | -------------------------------------------------------------------------------- /query-monitor/data/transients.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public $trans = array(); 23 | 24 | /** 25 | * @var bool 26 | */ 27 | public $has_type; 28 | } 29 | -------------------------------------------------------------------------------- /query-monitor/output/Headers.php: -------------------------------------------------------------------------------- 1 | collector->id; 16 | 17 | foreach ( $this->get_output() as $key => $value ) { 18 | if ( ! is_scalar( $value ) ) { 19 | $value = json_encode( $value ); 20 | } 21 | 22 | # Remove illegal characters (Header may not contain NUL bytes) 23 | if ( is_string( $value ) ) { 24 | $value = str_replace( chr( 0 ), '', $value ); 25 | } 26 | 27 | header( sprintf( 'X-QM-%s-%s: %s', $id, $key, $value ) ); 28 | } 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /query-monitor/output/Raw.php: -------------------------------------------------------------------------------- 1 | collector->get_data(); 29 | 30 | return $data->conds['true']; 31 | } 32 | } 33 | 34 | /** 35 | * @param array $output 36 | * @param QM_Collectors $collectors 37 | * @return array 38 | */ 39 | function register_qm_output_raw_conditionals( array $output, QM_Collectors $collectors ) { 40 | $collector = QM_Collectors::get( 'conditionals' ); 41 | if ( $collector ) { 42 | $output['conditionals'] = new QM_Output_Raw_Conditionals( $collector ); 43 | } 44 | return $output; 45 | } 46 | 47 | add_filter( 'qm/outputter/raw', 'register_qm_output_raw_conditionals', 20, 2 ); 48 | -------------------------------------------------------------------------------- /query-monitor/vendor/autoload.php: -------------------------------------------------------------------------------- 1 | = 70400)) { 8 | $issues[] = 'Your Composer dependencies require a PHP version ">= 7.4.0". You are running ' . PHP_VERSION . '.'; 9 | } 10 | 11 | if ($issues) { 12 | if (!headers_sent()) { 13 | header('HTTP/1.1 500 Internal Server Error'); 14 | } 15 | if (!ini_get('display_errors')) { 16 | if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { 17 | fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); 18 | } elseif (!headers_sent()) { 19 | echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; 20 | } 21 | } 22 | trigger_error( 23 | 'Composer detected issues in your platform: ' . implode(' ', $issues), 24 | E_USER_ERROR 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "github>whitesource/merge-confidence:beta", 4 | "config:base", 5 | "schedule:weekly", 6 | ":preserveSemverRanges", 7 | ":separateMultipleMajorReleases", 8 | ":semanticPrefixChore", 9 | ":maintainLockFilesMonthly", 10 | ":dependencyDashboard" 11 | ], 12 | "labels": ["dependencies"], 13 | "postUpdateOptions": ["npmDedupe"], 14 | "rangeStrategy": "update-lockfile", 15 | "rollbackPrs": true, 16 | "composerIgnorePlatformReqs": null, 17 | "reviewers": ["team:Automattic/vip-platform-cantina"], 18 | "packageRules": [ 19 | { 20 | "matchDepTypes": ["devDependencies"], 21 | "matchUpdateTypes": ["minor", "patch"], 22 | "groupName": "all non-major devDependencies", 23 | "groupSlug": "all-minor-patch-devDependencies" 24 | }, 25 | { 26 | "extends": ["packages:eslint"], 27 | "matchDepTypes": ["devDependencies"], 28 | "matchUpdateTypes": ["minor", "patch"], 29 | "groupName": "all non-major eslint", 30 | "groupSlug": "all-minor-patch-eslint" 31 | }, 32 | { 33 | "matchDepTypes": ["action"], 34 | "pinDigests": true 35 | } 36 | ], 37 | "ignorePaths": [ 38 | "akismet/**", 39 | "jetpack*/**", 40 | "wp-parsely-*/**" 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /schema.php: -------------------------------------------------------------------------------- 1 | $q ) { 15 | // Replace meta_key index with one that indexes meta_value as well 16 | if ( preg_match( '|CREATE TABLE ([^ ]*)|', $q, $matches ) && $wpdb->postmeta === $matches[1] ) { 17 | $queries[ $k ] = str_replace( 18 | 'KEY meta_key (meta_key(191))', 19 | sprintf( 'KEY %s', get_postmeta_key_value_index() ), 20 | $q 21 | ); 22 | } 23 | } 24 | 25 | return $queries; 26 | }); 27 | 28 | function get_postmeta_key_value_index() { 29 | // 191 for meta_key is max set by core. 30 | // 100 for meta_value is arbitrary-ish. 31 | return '`vip_meta_key_value` (`meta_key`(191), `meta_value`(100))'; 32 | } 33 | -------------------------------------------------------------------------------- /search/es-wp-query/.gitignore: -------------------------------------------------------------------------------- 1 | /tests/es.php 2 | wpcom-helper.php 3 | .DS_Store 4 | /report/ 5 | .idea 6 | -------------------------------------------------------------------------------- /search/es-wp-query/multisite.xml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | 14 | ./tests/query/ 15 | 16 | 17 | 18 | 19 | ./ 20 | 21 | ./tests/ 22 | ./bin/ 23 | ./adapters/ 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /search/es-wp-query/phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | ./tests/query/ 12 | 13 | 14 | 15 | 16 | ./ 17 | 18 | ./tests/ 19 | ./bin/ 20 | ./adapters/ 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /search/es-wp-query/tests/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/vip-go-mu-plugins/15ba43b107f3e065cd7a26fafca7bf449f0754c6/search/es-wp-query/tests/.DS_Store -------------------------------------------------------------------------------- /search/es-wp-query/tests/query/author.php: -------------------------------------------------------------------------------- 1 | set_permalink_structure( '/%year%/%monthnum%/%day%/%postname%/' ); 13 | } 14 | 15 | function test_author_with_no_posts() { 16 | add_action( 'pre_get_posts', '_es_wp_query_set_es_to_true' ); 17 | $user_id = self::factory()->user->create( array( 'user_login' => 'user-a' ) ); 18 | $this->go_to( '/author/user-a/' ); 19 | $this->assertQueryTrue( 'is_archive', 'is_author' ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /search/includes/classes/class-fieldcountgaugejob.php: -------------------------------------------------------------------------------- 1 | maybe_alert_for_field_count(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /search/includes/classes/class-queuewaittimejob.php: -------------------------------------------------------------------------------- 1 | maybe_alert_for_average_queue_time(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /search/includes/classes/concurrency-limiter/backendinterface.php: -------------------------------------------------------------------------------- 1 | get_query_log(); 7 | foreach ( $queries as $index => $query ) { 8 | unset( $queries[ $index ]['args']['headers']['Authorization'] ); 9 | } 10 | 11 | return $queries; 12 | } 13 | -------------------------------------------------------------------------------- /search/search-dev-tools/.babelrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/env", 5 | { 6 | "bugfixes": true, 7 | "modules": false, 8 | "targets": { 9 | "browsers": [ "> 0.25%", "IE >= 9" ] 10 | }, 11 | "exclude": [ "transform-regenerator" ] 12 | } 13 | ] 14 | ], 15 | "plugins": [ 16 | [ "@babel/plugin-transform-react-jsx", { "pragma": "h", "pragmaFrag": "Fragment" } ], 17 | [ "@babel/plugin-transform-class-properties" ], 18 | [ "@babel/plugin-transform-object-rest-spread", { "loose": true } ], 19 | [ "@babel/plugin-transform-object-assign" ], 20 | [ "@babel/plugin-transform-private-property-in-object" ] 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /search/search-dev-tools/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": [ 4 | "plugin:@automattic/wpvip/javascript", 5 | "plugin:@automattic/wpvip/react", 6 | "preact" 7 | ], 8 | "rules": { 9 | "jest/no-deprecated-functions": "off" 10 | }, 11 | "settings": { 12 | "react": { 13 | "pragma": "h" 14 | }, 15 | "jsdoc": { 16 | "mode": "typescript" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /search/search-dev-tools/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /build/*.json 3 | /build/*.map 4 | /build/*.html 5 | /*.log 6 | size-plugin.json -------------------------------------------------------------------------------- /search/search-dev-tools/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require( 'autoprefixer' )( { 4 | overrideBrowserslist: [ '> 0.25%', 'IE >= 9' ], 5 | } ), 6 | ], 7 | }; 8 | -------------------------------------------------------------------------------- /search/search-dev-tools/src/assets/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /search/search-dev-tools/src/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/vip-go-mu-plugins/15ba43b107f3e065cd7a26fafca7bf449f0754c6/search/search-dev-tools/src/assets/favicon.ico -------------------------------------------------------------------------------- /search/search-dev-tools/src/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/vip-go-mu-plugins/15ba43b107f3e065cd7a26fafca7bf449f0754c6/search/search-dev-tools/src/assets/icon.png -------------------------------------------------------------------------------- /search/search-dev-tools/src/assets/lg.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /search/search-dev-tools/src/assets/minus.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /search/search-dev-tools/src/assets/plus.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /search/search-dev-tools/src/components/collapsible-list/style.scss: -------------------------------------------------------------------------------- 1 | .collapsible_list { 2 | position: relative; 3 | 4 | strong { 5 | @include text-caption(); 6 | } 7 | 8 | :global(.vip-h4) { 9 | cursor: pointer; 10 | color: var(--vip-brand-60); 11 | } 12 | } 13 | 14 | .collapsible_list_details { 15 | display: none; 16 | position: absolute; 17 | top: calc(100% + 12px); 18 | width: 400px; 19 | 20 | background: #ffffff; 21 | /* Medium */ 22 | box-shadow: 0px 14px 38px rgba(0, 0, 0, 0.07), 23 | 0px 1.6711px 15.8755px rgba(0, 0, 0, 0.0503198), 24 | 0px 0.893452px 8.4878px rgba(0, 0, 0, 0.0417275), 25 | 0px 0.500862px 4.75819px rgba(0, 0, 0, 0.035), 26 | 0px 0.266004px 2.52704px rgba(0, 0, 0, 0.0282725), 27 | 0px 0.11069px 1.05156px rgba(0, 0, 0, 0.0196802); 28 | border-radius: 3px; 29 | align-items: flex-start; 30 | padding: 16px; 31 | list-style-position: inside; 32 | 33 | li { 34 | margin-bottom: 8px; 35 | overflow-wrap: break-word; 36 | @include text-small(); 37 | } 38 | 39 | .visible & { 40 | display: block; 41 | z-index: 2; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /search/search-dev-tools/src/components/overlay/style.scss: -------------------------------------------------------------------------------- 1 | $overlay-horizontal-padding: 1em; 2 | $overlay-horizontal-padding-small-viewport: 0.5em; 3 | :global { 4 | .search-dev-tools__overlay { 5 | position: fixed; 6 | top: 32px; 7 | left: 0; 8 | // #wpadminwrap has a z-index of 9990 9 | z-index: 9991; 10 | width: 100vw; 11 | height: 100vh; 12 | padding: 2rem; 13 | background: rgba(255, 255, 255, 0.975); 14 | overflow-y: auto; 15 | overflow-x: hidden; 16 | transition: opacity 0.15s ease-in-out; 17 | box-sizing: border-box; 18 | 19 | &__close { 20 | background: transparent; 21 | border: 0; 22 | position: absolute; 23 | top: 24px; 24 | right: 24px; 25 | // We use !important here because some themes hijack buttons 26 | background-color: #fff !important; 27 | } 28 | 29 | &.search-dev-tools__overlay--light { 30 | background: #fff; 31 | } 32 | 33 | &.search-dev-tools__overlay--dark { 34 | background: #777777; 35 | } 36 | 37 | *, 38 | *:before, 39 | *:after { 40 | box-sizing: border-box; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /search/search-dev-tools/src/components/style.scss: -------------------------------------------------------------------------------- 1 | .vip_search_dev_tools { 2 | font-family: var(--vip-font-family); 3 | 4 | .main_caption { 5 | margin-bottom: 4px; 6 | } 7 | } 8 | 9 | .ab_btn { 10 | &::before { 11 | content: url('../assets/wpvip.svg'); 12 | margin-right: 7px; 13 | } 14 | 15 | display: flex; 16 | flex-flow: row nowrap; 17 | align-items: center; 18 | border: 0; 19 | background-color: transparent; 20 | color: #eee; 21 | padding: 0 8px !important; 22 | height: 31px; 23 | 24 | &:hover { 25 | color: var(--vip-blue-60); 26 | background: white; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /search/search-dev-tools/src/context.js: -------------------------------------------------------------------------------- 1 | import { createContext } from 'preact'; 2 | 3 | export const SearchContext = createContext( null ); 4 | -------------------------------------------------------------------------------- /search/search-dev-tools/src/index.js: -------------------------------------------------------------------------------- 1 | // Uncomment when developing to enable Preact Dev Tools extension 2 | // require( 'preact/debug' ); 3 | 4 | // This is important to make Webpack correctly load assets from the plugin url (as opposed to the default behavior to load from the document root) 5 | import './webpack-public-path'; 6 | 7 | import { h, render } from 'preact'; 8 | 9 | import SearchDevToolsApp from './components/app'; 10 | 11 | const renderApp = () => render( , document.querySelector( '[data-widget-host="vip-search-dev-tools"]' ) ); 12 | 13 | if ( document.readyState === 'loading' ) { 14 | document.addEventListener( 'DOMContentLoaded', renderApp ); 15 | } else { 16 | renderApp(); 17 | } 18 | -------------------------------------------------------------------------------- /search/search-dev-tools/src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "search", 3 | "short_name": "search", 4 | "start_url": "/", 5 | "display": "standalone", 6 | "orientation": "portrait", 7 | "background_color": "#fff", 8 | "theme_color": "#673ab8", 9 | "icons": [ 10 | { 11 | "src": "/assets/icon.png", 12 | "type": "image/png", 13 | "sizes": "512x512" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /search/search-dev-tools/src/style/style.scss: -------------------------------------------------------------------------------- 1 | @use './vars.scss' as *; 2 | 3 | .vip-h2 { 4 | @include text-h2(); 5 | } 6 | .vip-h3 { 7 | @include text-h3(); 8 | } 9 | .vip-h4 { 10 | @include text-h4(); 11 | } 12 | .vip-h5 { 13 | @include text-h5(); 14 | } 15 | 16 | .search-dev-tools { 17 | &__wrapper { 18 | margin-top: 40px; 19 | display: flex; 20 | justify-content: center; 21 | } 22 | } 23 | 24 | .vip-search-dev-tools-ab { 25 | .ab-item { 26 | display: none !important; 27 | } 28 | } 29 | 30 | .main_caption { 31 | margin-bottom: 4px; 32 | } 33 | -------------------------------------------------------------------------------- /search/search-dev-tools/src/utils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Async helper to post data to a REST andpoint. 3 | * 4 | * This function doesn't handle the Errors that maybe thrown after 5 | * an unsuccessful request. Please handle these in the caller function/method. 6 | * 7 | * @param {string} url Request URL 8 | * @param {Object} data Any data to post. 9 | * @param {string} nonce The nonce verify the permissions 10 | */ 11 | export async function postData( url = '', data = {}, nonce = '' ) { 12 | const response = await fetch( url, { 13 | method: 'POST', 14 | credentials: 'same-origin', 15 | headers: { 16 | 'Content-Type': 'application/json', 17 | 'X-WP-Nonce': nonce, 18 | }, 19 | body: JSON.stringify( data ), 20 | } ); 21 | return response.json(); 22 | } 23 | -------------------------------------------------------------------------------- /search/search-dev-tools/src/webpack-public-path.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable camelcase */ 2 | /* eslint-disable no-undef */ 3 | // Make sure assets are loaded from the correct url (the plugin's build dir) 4 | __webpack_public_path__ = window.VIPSearchDevTools.__webpack_public_path__; 5 | -------------------------------------------------------------------------------- /security/js/password.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", function() { 2 | // Reposition input inside Set New Password dropdown 3 | const el = document.getElementById('current-password-confirm'); 4 | const parent = document.getElementsByClassName('wp-pwd')[0]; 5 | parent.insertBefore(el, parent.firstChild); 6 | el.style.marginBottom = '1em'; 7 | 8 | // Hide no JS fallback UI 9 | const nojsParent = document.getElementById('nojs-current-pass'); 10 | nojsParent.style.display = 'none'; 11 | }); 12 | -------------------------------------------------------------------------------- /security/machine-user.php: -------------------------------------------------------------------------------- 1 | user_login ) { 20 | return [ 'do_not_allow' ]; 21 | } 22 | } 23 | 24 | return $caps; 25 | } 26 | // Use map_meta_cap instead of user_has_cap so we can restrict superadmins as well. 27 | // WP_User::has_cap runs the user_has_cap filter after the superadmin check, which makes it impossible to use for restricting them. 28 | add_filter( 'map_meta_cap', __NAMESPACE__ . '\prevent_machine_user_mods', PHP_INT_MAX, 4 ); 29 | -------------------------------------------------------------------------------- /shared-plugins/two-factor/assets/banner-1544x500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/vip-go-mu-plugins/15ba43b107f3e065cd7a26fafca7bf449f0754c6/shared-plugins/two-factor/assets/banner-1544x500.png -------------------------------------------------------------------------------- /shared-plugins/two-factor/assets/banner-772x250.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/vip-go-mu-plugins/15ba43b107f3e065cd7a26fafca7bf449f0754c6/shared-plugins/two-factor/assets/banner-772x250.png -------------------------------------------------------------------------------- /shared-plugins/two-factor/assets/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/vip-go-mu-plugins/15ba43b107f3e065cd7a26fafca7bf449f0754c6/shared-plugins/two-factor/assets/icon-128x128.png -------------------------------------------------------------------------------- /shared-plugins/two-factor/assets/icon-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/vip-go-mu-plugins/15ba43b107f3e065cd7a26fafca7bf449f0754c6/shared-plugins/two-factor/assets/icon-256x256.png -------------------------------------------------------------------------------- /shared-plugins/two-factor/assets/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /shared-plugins/two-factor/assets/screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/vip-go-mu-plugins/15ba43b107f3e065cd7a26fafca7bf449f0754c6/shared-plugins/two-factor/assets/screenshot-1.png -------------------------------------------------------------------------------- /shared-plugins/two-factor/assets/screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/vip-go-mu-plugins/15ba43b107f3e065cd7a26fafca7bf449f0754c6/shared-plugins/two-factor/assets/screenshot-2.png -------------------------------------------------------------------------------- /shared-plugins/two-factor/assets/screenshot-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Automattic/vip-go-mu-plugins/15ba43b107f3e065cd7a26fafca7bf449f0754c6/shared-plugins/two-factor/assets/screenshot-3.png -------------------------------------------------------------------------------- /shared-plugins/two-factor/providers/css/fido-u2f-admin.css: -------------------------------------------------------------------------------- 1 | #security-keys-section .wp-list-table { 2 | margin-bottom: 2em; 3 | } 4 | 5 | #security-keys-section .register-security-key .spinner { 6 | float: none; 7 | } 8 | 9 | #security-keys-section .security-key-status { 10 | vertical-align: middle; 11 | font-style: italic; 12 | } 13 | -------------------------------------------------------------------------------- /shared-plugins/two-factor/providers/js/fido-u2f-login.js: -------------------------------------------------------------------------------- 1 | /* global window, u2f, u2fL10n, jQuery */ 2 | ( function( $ ) { 3 | if ( ! window.u2fL10n ) { 4 | window.console.error( 'u2fL10n is not defined' ); 5 | return; 6 | } 7 | 8 | u2f.sign( u2fL10n.request[0].appId, u2fL10n.request[0].challenge, u2fL10n.request, function( data ) { 9 | if ( data.errorCode ) { 10 | window.console.error( 'Registration Failed', data.errorCode ); 11 | } else { 12 | $( '#u2f_response' ).val( JSON.stringify( data ) ); 13 | $( '#loginform' ).submit(); 14 | } 15 | } ); 16 | }( jQuery ) ); 17 | -------------------------------------------------------------------------------- /shared-plugins/two-factor/user-edit.css: -------------------------------------------------------------------------------- 1 | .two-factor-methods-table .col-primary, 2 | .two-factor-methods-table .col-enabled { 3 | width: 5%; 4 | } 5 | 6 | .two-factor-methods-table .col-name { 7 | width: 90%; 8 | } 9 | 10 | .two-factor-methods-table tbody th { 11 | text-align: center; 12 | } 13 | 14 | .two-factor-methods-table tbody th, 15 | .two-factor-methods-table tbody td { 16 | vertical-align: top; 17 | } 18 | 19 | .two-factor-methods-table .two-factor-method-label { 20 | display: block; 21 | font-weight: 700; 22 | } 23 | -------------------------------------------------------------------------------- /telemetry/class-telemetry-client.php: -------------------------------------------------------------------------------- 1 | $event_properties Any additional properties 23 | * to include with the event. 24 | * @return bool|WP_Error True if recording the event succeeded. 25 | * False if telemetry is disabled. 26 | * WP_Error if recording the event failed. 27 | */ 28 | abstract public function record_event( 29 | string $event_name, 30 | array $event_properties = [] 31 | ): bool|WP_Error; 32 | } 33 | -------------------------------------------------------------------------------- /telemetry/pendo/class-pendo-track-event-dto.php: -------------------------------------------------------------------------------- 1 | =12" 26 | } 27 | }, 28 | "node_modules/minimist": { 29 | "version": "1.2.8", 30 | "license": "MIT", 31 | "funding": { 32 | "url": "https://github.com/sponsors/ljharb" 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /telemetry/pendo/js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vip-mu-plugins-pendo-lib", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "build": "npx esbuild pendo-agent.mjs --bundle --minify --tree-shaking=true --outfile=pendo-agent.js", 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "browserslist": "> 0.5%, last 2 versions, not dead", 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@pendo/agent": "2.272.0" 14 | }, 15 | "devDependencies": {} 16 | } 17 | -------------------------------------------------------------------------------- /telemetry/pendo/js/pendo-agent.mjs: -------------------------------------------------------------------------------- 1 | import { initialize } from '@pendo/agent'; 2 | 3 | initialize( window.VIP_PENDO_MU_PLUGINS_INIT_DATA ); 4 | -------------------------------------------------------------------------------- /tests/admin-notice/test-admin-notice.php: -------------------------------------------------------------------------------- 1 | markTestSkipped( 'This test needs updated b/c now we load mu-plugins normally, so the require_once here doesn\'t happen to re-register the filter' ); 11 | 12 | remove_all_filters( 'admin_notices' ); 13 | 14 | require_once __DIR__ . '/../../admin-notice/admin-notice.php'; 15 | 16 | $this->assertTrue( has_filter( 'admin_notices' ) ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/cache/mock-header.php: -------------------------------------------------------------------------------- 1 | slug ); 19 | 20 | $block_data_api_integration->load(); 21 | 22 | $this->assertFalse( $block_data_api_integration->is_active() ); 23 | } 24 | 25 | public function test__if_is_loaded_gives_back_false_when_not_loaded(): void { 26 | $block_data_api_integration = new BlockDataApiIntegration( $this->slug ); 27 | 28 | $this->assertFalse( $block_data_api_integration->is_loaded() ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/integrations/test-vip-governance.php: -------------------------------------------------------------------------------- 1 | slug ); 19 | 20 | $vip_governance_integration->load(); 21 | 22 | $this->assertFalse( $vip_governance_integration->is_active() ); 23 | } 24 | 25 | public function test__if_is_loaded_gives_back_false_when_not_loaded(): void { 26 | $vip_governance_integration = new VipGovernanceIntegration( $this->slug ); 27 | 28 | $this->assertFalse( $vip_governance_integration->is_loaded() ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/lib/mock-wpdb.php: -------------------------------------------------------------------------------- 1 | cached_tables[ $table ] = $dataset; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/lib/proxy/test-is-valid-proxy-verification-key.php: -------------------------------------------------------------------------------- 1 | registry; 14 | } 15 | 16 | /** 17 | * @return CollectorInterface[] 18 | */ 19 | public function get_collectors(): array { 20 | return $this->collectors; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/proxy-helpers.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf( Tracks_Event_DTO::class, $event ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/test-core-filters.php: -------------------------------------------------------------------------------- 1 | 'http://example.com', 7 | 1 => 'https://example.com', 8 | ]; 9 | 10 | $expected = [ 11 | 1 => 'https://example.com', 12 | ]; 13 | 14 | $actual = vip_only_https_origins( $input ); 15 | self::assertSame( $expected, $actual ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/test-divi-compatibility.php: -------------------------------------------------------------------------------- 1 | assertTrue( defined( 'ET_DISABLE_FILE_BASED_CACHE' ) ); 16 | $this->assertTrue( constant( 'ET_DISABLE_FILE_BASED_CACHE' ) === true ); 17 | 18 | $this->assertTrue( defined( 'ET_BUILDER_CACHE_ASSETS' ) ); 19 | $this->assertTrue( constant( 'ET_BUILDER_CACHE_ASSETS' ) === false ); 20 | 21 | $this->assertTrue( defined( 'ET_BUILDER_CACHE_MODULES' ) ); 22 | $this->assertTrue( constant( 'ET_BUILDER_CACHE_MODULES' ) === false ); 23 | 24 | $this->assertTrue( defined( 'ET_CORE_CACHE_DIR' ) ); 25 | $this->assertTrue( defined( 'ET_CORE_CACHE_DIR_URL' ) ); 26 | 27 | // Check if the filter is added 28 | $this->assertTrue( has_filter( 'et_cache_wpfs_credentials' ) !== false ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/test-jetpack.php: -------------------------------------------------------------------------------- 1 | Jetpack version 14 | '6.2' => '12.8', 15 | '6.3' => '13.1', 16 | '6.4' => '13.6', 17 | '6.5' => '14.0', 18 | '6.6' => '14.5', 19 | '6.7' => $latest, 20 | ]; 21 | 22 | foreach ( $versions_map as $wordpress_version => $jetpack_version ) { 23 | $wp_version = $wordpress_version; 24 | $this->assertEquals( vip_default_jetpack_version(), $jetpack_version ); 25 | } 26 | 27 | // Reset back to original value. 28 | $wp_version = $saved_wp_version; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/test-plugin-fixes.php: -------------------------------------------------------------------------------- 1 | assertSame( '0', vip_ninja_forms_update_option( 0, '0' ) ); 21 | $this->assertSame( 1, vip_ninja_forms_update_option( 1, '0' ) ); 22 | $this->assertSame( '0', vip_ninja_forms_update_option( '0', '0' ) ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/test-schema.php: -------------------------------------------------------------------------------- 1 | db_version(); 13 | $db_server_info = $wpdb->db_server_info(); 14 | 15 | if ( version_compare( $db_version, '8.0.17', '>=' ) && false === strpos( $db_server_info, 'MariaDB' ) ) { 16 | $deltas = array_filter( $deltas, fn ( $delta ) => ! preg_match( '!Changed type of [^ ]+ from ([^ ]+)( unsigned)? to \1\(\d+\)\2?!', $delta ) ); 17 | } 18 | 19 | $this->assertCount( 1, $deltas, 'More deltas than expected' ); 20 | $this->assertEquals( $deltas[0], 'Added index wptests_postmeta KEY `vip_meta_key_value` (`meta_key`(191),`meta_value`(100))', 'Delta did not find vip_meta_key_value index or assertion needs updating.' ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/trait-assertfiledirectory.php: -------------------------------------------------------------------------------- 1 | markTestSkipped( 'This test needs updated b/c now we load mu-plugins normally, and Akismet already gets loaded, causing a duplicate constant definition error when we load it below' ); 10 | 11 | $this->setExpectedIncorrectUsage( 'wpcom_vip_load_plugin' ); 12 | 13 | // This should have been fired already but just in case 14 | do_action( 'plugins_loaded' ); 15 | 16 | wpcom_vip_load_plugin( 'akismet' ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/vip-helpers/vip-utils/include-vip-utils-include-plugin.php: -------------------------------------------------------------------------------- 1 | assertFalse( isset( $GLOBALS[ TEST_GLOBAL_VARIABLE ] ) ); 10 | 11 | _wpcom_vip_include_plugin( __DIR__ . '/include-vip-utils-include-plugin.php' ); 12 | 13 | $this->assertTrue( $GLOBALS[ TEST_GLOBAL_VARIABLE ] ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/vip-helpers/vip-utils/test-vip-utils-is-vip-convenience-domain.php: -------------------------------------------------------------------------------- 1 | assertEquals( $expected, is_vip_convenience_domain( $domain ) ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/vip-helpers/vip-utils/test-vip-utils-resized-attachments.php: -------------------------------------------------------------------------------- 1 | assertFalse( $actual_url ); 10 | } 11 | 12 | public function test__valid_attachment() { 13 | $expected_end_of_url = '/image.jpg?w=100&h=101'; 14 | 15 | $attachment_id = $this->factory()->attachment->create_object( [ 16 | 'file' => 'image.jpg', 17 | ] ); 18 | 19 | $actual_url = wpcom_vip_get_resized_attachment_url( $attachment_id, 100, 101 ); 20 | 21 | $actual_end_of_url = substr( $actual_url, strrpos( $actual_url, '/' ) ); 22 | 23 | $this->assertEquals( $expected_end_of_url, $actual_end_of_url ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/vip-helpers/vip-utils/test-vip-utils-vip-powered-wpcom-url.php: -------------------------------------------------------------------------------- 1 | assertEquals( $expected, $result ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/vip-helpers/vip-utils/test-vip-utils-wpcom-vip-is-feedservice-ua.php: -------------------------------------------------------------------------------- 1 | assertEquals( $expected, wpcom_vip_is_feedservice_ua() ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/wpcom-vip-two-factor/sms-provider.php: -------------------------------------------------------------------------------- 1 | format_sms_message( $token ); 13 | 14 | $this->assertEquals( $expected, $actual ); 15 | } 16 | 17 | public function test__two_factor_sms_formatting__code_with_leading_zero() { 18 | $token = 0123456; 19 | $expected = '0123456 is your Test Blog verification code.' . "\n\n" . '@example.org #0123456'; 20 | 21 | $two_factor = Two_Factor_SMS::get_instance(); 22 | $actual = $two_factor->format_sms_message( $token ); 23 | 24 | $this->assertEquals( $expected, $actual ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /vip-cache-manager.php: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 |

8 | 9 | 11 | 12 |

13 |
14 | 15 | registry->register( 'Cache', VIP_Go_Feed_Cache::class, false ); 22 | } 23 | 24 | add_action( 'wp_feed_options', 'vipgo_feed_options' ); 25 | -------------------------------------------------------------------------------- /vip-feed-cache/class-vip-go-feed-cache.php: -------------------------------------------------------------------------------- 1 | set_timeout( 3 ); 14 | } ); 15 | -------------------------------------------------------------------------------- /vip-helpers/vip-syndication-cache.php: -------------------------------------------------------------------------------- 1 | record_event( 'wpparsely_delete_widget', compact( 'id_base' ) ); 27 | } 28 | -------------------------------------------------------------------------------- /vip-parsely/Telemetry/Events/track-settings-page-loaded.php: -------------------------------------------------------------------------------- 1 | record_event( 'wpparsely_settings_page_loaded' ); 27 | } 28 | -------------------------------------------------------------------------------- /vip-plugins.php: -------------------------------------------------------------------------------- 1 | Automattic 7 | * License: GPLv2 or later 8 | */ 9 | 10 | if ( ! defined( 'WP_INSTALLING' ) ) { 11 | require_once __DIR__ . '/vip-support/vip-support.php'; 12 | } 13 | -------------------------------------------------------------------------------- /vip-support/vip-support.php: -------------------------------------------------------------------------------- 1 | Automattic 7 | * License: GPLv2 or later 8 | * Text Domain: wpcom-vip-support-role 9 | * Domain Path: /languages 10 | * 11 | * @package WPCOM_VIP_Support_Role 12 | */ 13 | 14 | namespace Automattic\VIP\Support_User; 15 | 16 | require_once __DIR__ . '/class-vip-support-role.php'; 17 | require_once __DIR__ . '/class-vip-support-user.php'; 18 | if ( defined( 'WP_CLI' ) && WP_CLI ) { 19 | require_once __DIR__ . '/class-vip-support-cli.php'; 20 | } 21 | -------------------------------------------------------------------------------- /vip-woocommerce.php: -------------------------------------------------------------------------------- 1 | assoc_args; 11 | 12 | $media_regenerate_before_invoke = function () use ( &$runner, &$assoc_args ) { 13 | // If skip-delete is not set or not true 14 | if ( ! isset( $assoc_args['skip-delete'] ) || 'true' !== $assoc_args['skip-delete'] ) { 15 | // add skip-delete to the assoc_args array 16 | $assoc_args['skip-delete'] = 'true'; 17 | 18 | WP_CLI::line( 'Forcing --skip-delete flag as it\'s required for VIP File Service' ); 19 | WP_CLI::line( 'Re-running...' ); 20 | 21 | // Run the command with the forced skip-delete argument 22 | $runner->run_command( $runner->arguments, $assoc_args ); 23 | 24 | // Exit the run loop to prevent continuing to the invoked command 25 | exit; 26 | } 27 | }; 28 | 29 | WP_CLI::add_hook( 'before_invoke:media regenerate', $media_regenerate_before_invoke ); 30 | -------------------------------------------------------------------------------- /wp-cli/vip-fixers.php: -------------------------------------------------------------------------------- 1 |