languages/envato-market.pot000064400000032611147177457130012036 0ustar00# Copyright (C) 2024 Envato # This file is distributed under the same license as the Envato Market package. msgid "" msgstr "" "Project-Id-Version: Envato Market 2.0.12\n" "Report-Msgid-Bugs-To: Envato Support Team \n" "POT-Creation-Date: 2024-08-14 01:28:42+00:00\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2024-MO-DA HO:MI+ZONE\n" "Last-Translator: Envato Support Team \n" "Language-Team: Envato Support Team \n" "X-Generator: grunt-wp-i18n 1.0.3\n" #: envato-market.php:99 msgid "" "The Envato Market plugin requires PHP version 5.4+, plugin is currently NOT " "ACTIVE. Please contact the hosting provider to upgrade the version of PHP." msgstr "" #: envato-market.php:118 msgid "" "Envato Market plugin is not installed correctly. Please delete this plugin " "and get the correct zip file from %s." msgstr "" #: inc/admin/class-envato-market-admin.php:78 #: inc/admin/class-envato-market-admin.php:88 #: inc/class-envato-market-api.php:80 inc/class-envato-market-api.php:90 #: inc/class-envato-market-github.php:87 inc/class-envato-market-github.php:97 #: inc/class-envato-market-items.php:100 inc/class-envato-market-items.php:110 #: inc/class-envato-market.php:151 inc/class-envato-market.php:161 msgid "Cheatin’ huh?" msgstr "" #: inc/admin/class-envato-market-admin.php:282 msgid "You do not have sufficient permissions to delete transients." msgstr "" #. Plugin Name of the plugin/theme msgid "Envato Market" msgstr "" #: inc/admin/class-envato-market-admin.php:437 msgid "Save" msgstr "" #: inc/admin/class-envato-market-admin.php:438 msgid "Remove" msgstr "" #: inc/admin/class-envato-market-admin.php:439 msgid "Cancel" msgstr "" #: inc/admin/class-envato-market-admin.php:440 msgid "An unknown error occurred. Try again." msgstr "" #: inc/admin/class-envato-market-admin.php:463 #: inc/admin/view/partials/settings.php:21 msgid "Test API Connection" msgstr "" #: inc/admin/class-envato-market-admin.php:468 #: inc/admin/view/callback/setting/items.php:22 msgid "ID" msgstr "" #: inc/admin/class-envato-market-admin.php:471 inc/admin/functions.php:341 #: inc/admin/view/callback/setting/items.php:24 msgid "Delete" msgstr "" #: inc/admin/class-envato-market-admin.php:492 msgid "Remove Item" msgstr "" #: inc/admin/class-envato-market-admin.php:493 msgid "" "You are about to remove the connection between the Envato Market API and " "this item. You cannot undo this action." msgstr "" #: inc/admin/class-envato-market-admin.php:498 #: inc/admin/view/callback/setting/items.php:37 msgid "Add Item" msgstr "" #: inc/admin/class-envato-market-admin.php:501 #: inc/admin/class-envato-market-admin.php:578 msgid "Token" msgstr "" #: inc/admin/class-envato-market-admin.php:504 msgid "Enter the Envato API Personal Token." msgstr "" #: inc/admin/class-envato-market-admin.php:505 msgid "Item ID" msgstr "" #: inc/admin/class-envato-market-admin.php:507 msgid "Enter the Envato Item ID." msgstr "" #: inc/admin/class-envato-market-admin.php:531 inc/admin/functions.php:165 #: inc/admin/functions.php:166 inc/admin/functions.php:407 #: inc/admin/functions.php:408 msgid "Version %s" msgstr "" #: inc/admin/class-envato-market-admin.php:531 msgid "Version" msgstr "" #: inc/admin/class-envato-market-admin.php:540 inc/admin/functions.php:176 #: inc/admin/functions.php:418 msgid "By" msgstr "" #: inc/admin/class-envato-market-admin.php:547 #: inc/admin/class-envato-market-admin.php:548 inc/admin/functions.php:146 #: inc/admin/functions.php:388 msgid "Install" msgstr "" #: inc/admin/class-envato-market-admin.php:570 msgid "Getting Started (Simple)" msgstr "" #: inc/admin/class-envato-market-admin.php:587 msgid "Single Item Tokens (Advanced)" msgstr "" #: inc/admin/class-envato-market-admin.php:595 msgid "Envato Market Items" msgstr "" #: inc/admin/class-envato-market-admin.php:1023 #: inc/admin/class-envato-market-admin.php:1048 msgid "Installing Plugin..." msgstr "" #: inc/admin/class-envato-market-admin.php:1024 msgid "You do not have sufficient permissions to install plugins on this site." msgstr "" #: inc/admin/class-envato-market-admin.php:1025 #: inc/admin/class-envato-market-admin.php:1050 #: inc/admin/class-envato-market-admin.php:1108 #: inc/admin/class-envato-market-theme-installer-skin.php:113 msgid "Return to Plugin Installer" msgstr "" #: inc/admin/class-envato-market-admin.php:1049 #: inc/admin/class-envato-market-admin.php:1107 msgid "An error occurred, please check that the item ID is correct." msgstr "" #: inc/admin/class-envato-market-admin.php:1055 msgid "Installing Plugin: %s" msgstr "" #: inc/admin/class-envato-market-admin.php:1081 #: inc/admin/class-envato-market-admin.php:1106 msgid "Installing Theme..." msgstr "" #: inc/admin/class-envato-market-admin.php:1082 msgid "You do not have sufficient permissions to install themes on this site." msgstr "" #: inc/admin/class-envato-market-admin.php:1083 #: inc/admin/class-envato-market-theme-installer-skin.php:67 msgid "Return to Theme Installer" msgstr "" #: inc/admin/class-envato-market-admin.php:1115 msgid "Installing Theme: %s" msgstr "" #: inc/admin/class-envato-market-admin.php:1143 msgid "The Token is missing." msgstr "" #: inc/admin/class-envato-market-admin.php:1145 #: inc/admin/class-envato-market-admin.php:1248 msgid "The Item ID is missing." msgstr "" #: inc/admin/class-envato-market-admin.php:1147 #: inc/admin/class-envato-market-admin.php:1294 msgid "User not allowed to install items." msgstr "" #: inc/admin/class-envato-market-admin.php:1158 msgid "The Token or Item ID is incorrect." msgstr "" #: inc/admin/class-envato-market-admin.php:1162 msgid "The item cannot be downloaded." msgstr "" #: inc/admin/class-envato-market-admin.php:1231 msgid "An unknown error occurred." msgstr "" #: inc/admin/class-envato-market-admin.php:1250 #: inc/class-envato-market-github.php:358 msgid "User not allowed to update items." msgstr "" #: inc/admin/class-envato-market-theme-installer-skin.php:56 #: inc/admin/functions.php:130 msgid "Live Preview" msgstr "" #: inc/admin/class-envato-market-theme-installer-skin.php:56 #: inc/admin/functions.php:130 msgid "Live Preview “%s”" msgstr "" #: inc/admin/class-envato-market-theme-installer-skin.php:61 #: inc/admin/functions.php:107 msgid "Network Enable" msgstr "" #: inc/admin/class-envato-market-theme-installer-skin.php:65 #: inc/admin/functions.php:123 inc/admin/functions.php:358 msgid "Activate" msgstr "" #: inc/admin/class-envato-market-theme-installer-skin.php:65 #: inc/admin/functions.php:123 msgid "Activate “%s”" msgstr "" #: inc/admin/class-envato-market-theme-installer-skin.php:102 msgid "Activate Plugin" msgstr "" #: inc/admin/class-envato-market-theme-installer-skin.php:109 #: inc/admin/functions.php:369 msgid "Network Activate" msgstr "" #: inc/admin/class-envato-market-theme-upgrader.php:34 #: inc/admin/class-envato-market-theme-upgrader.php:72 msgid "Downloading the Envato Market upgrade package…" msgstr "" #: inc/admin/class-envato-market-theme-upgrader.php:45 #: inc/admin/class-envato-market-theme-upgrader.php:83 msgid "Downloading the Envato Market install package…" msgstr "" #: inc/admin/functions.php:71 inc/admin/functions.php:290 msgid "Update %s now" msgstr "" #: inc/admin/functions.php:75 inc/admin/functions.php:295 msgid "Update Available" msgstr "" #: inc/admin/functions.php:83 inc/admin/functions.php:303 msgid "View version %1$s details." msgstr "" #: inc/admin/functions.php:98 msgid "Customize" msgstr "" #: inc/admin/functions.php:98 msgid "Customize “%s”" msgstr "" #: inc/admin/functions.php:107 msgid "Network Enable “%s”" msgstr "" #: inc/admin/functions.php:147 inc/admin/functions.php:389 msgid "Install %s" msgstr "" #: inc/admin/functions.php:325 msgid "Deactivate" msgstr "" #: inc/admin/functions.php:326 msgid "Deactivate %s" msgstr "" #: inc/admin/functions.php:342 msgid "Delete %s" msgstr "" #: inc/admin/functions.php:359 msgid "Activate %s" msgstr "" #: inc/admin/functions.php:370 msgid "Network Activate %s" msgstr "" #: inc/admin/view/callback/section/items.php:10 msgid "" "Add Envato Market themes & plugins using multiple OAuth tokens. This is " "especially useful when an item has been purchased on behalf of a " "third-party. This works similarly to the global OAuth Personal Token, but " "for individual items and additionally requires the Envato Market item ID." msgstr "" #: inc/admin/view/callback/section/items.php:12 msgid "Warning: These tokens can be revoked by the account holder at any time." msgstr "" #: inc/admin/view/callback/section/oauth.php:12 msgid "" "This area enables WordPress Theme & Plugin updates from Envato Market. " "Read more about how this process works at %s." msgstr "" #: inc/admin/view/callback/section/oauth.php:12 msgid "envato.com" msgstr "" #: inc/admin/view/callback/section/oauth.php:15 msgid "Please follow the steps below:" msgstr "" #: inc/admin/view/callback/section/oauth.php:18 msgid "Generate an Envato API Personal Token by %s." msgstr "" #: inc/admin/view/callback/section/oauth.php:18 msgid "clicking this link" msgstr "" #: inc/admin/view/callback/section/oauth.php:19 msgid "Name the token eg “My WordPress site”." msgstr "" #: inc/admin/view/callback/section/oauth.php:20 msgid "Ensure the following permissions are enabled:" msgstr "" #: inc/admin/view/callback/section/oauth.php:22 msgid "View and search Envato sites" msgstr "" #: inc/admin/view/callback/section/oauth.php:23 msgid "Download your purchased items" msgstr "" #: inc/admin/view/callback/section/oauth.php:24 msgid "List purchases you've made" msgstr "" #: inc/admin/view/callback/section/oauth.php:27 msgid "Copy the token into the box below." msgstr "" #: inc/admin/view/callback/section/oauth.php:28 msgid "Click the \"Save Changes\" button." msgstr "" #: inc/admin/view/callback/section/oauth.php:29 msgid "A list of purchased Themes & Plugins from Envato Market will appear." msgstr "" #: inc/admin/view/callback/setting/token.php:12 msgid "Enter your Envato API Personal Token." msgstr "" #: inc/admin/view/notice/error-http.php:11 msgid "" "Failed to connect to the Envato API. Please contact the hosting providier " "with this message: \"The Envato Market WordPress plugin requires TLS " "version 1.2 or above, please confirm if this hosting account supports TLS " "version 1.2 and allows connections from WordPress to the host " "api.envato.com\"." msgstr "" #: inc/admin/view/notice/error-missing-zip.php:11 msgid "" "Failed to locate the package file for this item. Please contact the item " "author for support, or install/upgrade the item manually from the %s." msgstr "" #: inc/admin/view/notice/error-permissions.php:11 msgid "" "Incorrect token permissions, please generate another token or fix the " "permissions on the existing token." msgstr "" #: inc/admin/view/notice/error-permissions.php:12 msgid "Please ensure only the following permissions are enabled: " msgstr "" #: inc/admin/view/notice/error-single-use.php:11 msgid "" "One or more Single Use OAuth Personal Tokens could not be verified and " "should be removed." msgstr "" #: inc/admin/view/notice/error.php:11 msgid "" "The OAuth Personal Token could not be verified. Please check that the Token " "has been entered correctly and has the minimum required permissions." msgstr "" #: inc/admin/view/notice/success-no-items.php:11 msgid "" "Your OAuth Personal Token has been verified. However, there are no " "WordPress downloadable items in your account." msgstr "" #: inc/admin/view/notice/success-single-use.php:11 msgid "All Single Use OAuth Personal Tokens have been verified." msgstr "" #: inc/admin/view/notice/success.php:11 msgid "Your OAuth Personal Token has been verified." msgstr "" #: inc/admin/view/partials/intro.php:13 msgid "Welcome!" msgstr "" #: inc/admin/view/partials/intro.php:14 msgid "" "This plugin can install WordPress themes and plugins purchased from " "ThemeForest & CodeCanyon by connecting with the Envato Market API using a " "secure OAuth personal token. Once your themes & plugins are installed " "WordPress will periodically check for updates, so keeping your items up to " "date is as simple as a few clicks." msgstr "" #: inc/admin/view/partials/intro.php:15 msgid "Find out more at %1$senvato.com%2$s." msgstr "" #: inc/admin/view/partials/settings.php:19 msgid "Save Changes" msgstr "" #: inc/admin/view/partials/tabs.php:28 msgid "Themes" msgstr "" #: inc/admin/view/partials/tabs.php:42 msgid "Plugins" msgstr "" #: inc/admin/view/partials/tabs.php:45 msgid "Settings" msgstr "" #: inc/admin/view/partials/tabs.php:48 msgid "Help" msgstr "" #: inc/class-envato-market-api.php:127 msgid "An API token is required." msgstr "" #: inc/class-envato-market-api.php:160 inc/class-envato-market-api.php:164 msgid "An unknown API error occurred." msgstr "" #: inc/class-envato-market-github.php:306 msgid "" "%1$sActivate the Envato Market plugin%2$s to get updates for your " "ThemeForest and CodeCanyon items." msgstr "" #: inc/class-envato-market-github.php:320 msgid "" "%1$sInstall the Envato Market plugin%2$s to get updates for your " "ThemeForest and CodeCanyon items." msgstr "" #. Plugin URI of the plugin/theme msgid "https://envato.com/market-plugin/" msgstr "" #. Description of the plugin/theme msgid "WordPress Theme & Plugin management for the Envato Market." msgstr "" #. Author of the plugin/theme msgid "Envato" msgstr "" #. Author URI of the plugin/theme msgid "https://envato.com" msgstr ""readme.txt000064400000000631147177457130006562 0ustar00=== Envato Market === Website: https://www.envato.com/lp/market-plugin/ Contributors: valendesigns, dtbaker, aaronrutley Requires at least: 5.1 Tested up to: 6.1 Stable tag: 2.0.12 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html WordPress Theme & Plugin management for the Envato Market. == Description == Please see https://www.envato.com/lp/market-plugin/ for more details. css/envato-market.css000064400000020771147177457130010652 0ustar00.about-wrap{overflow:hidden}.about-wrap .about-title{margin-right:0}.about-wrap .about-title sup{background:#fff;color:#666;font-size:33.333%;font-weight:700;padding:5px 10px;white-space:nowrap}.about-wrap .about-title+p{font-size:1.2em}.about-wrap img.about-logo{width:280px!important;margin-right:5px}.about-wrap h2.nav-tab-wrapper{float:left;width:100%;box-sizing:border-box;margin-bottom:1em}.about-wrap h2.nav-tab-wrapper .nav-tab{float:left;font-weight:400;margin-bottom:0}.about-wrap h2.nav-tab-wrapper .nav-tab.hidden{display:none}.about-wrap h2.nav-tab-wrapper .nav-tab-active,.about-wrap h2.nav-tab-wrapper .nav-tab-active:hover{border-bottom:0}.about-wrap h2.nav-tab-wrapper .nav-tab-active{position:relative}.about-wrap h2.nav-tab-wrapper .nav-tab-active:after{content:"";display:block;position:absolute;width:100%;bottom:-1px;height:1px;left:0;background:#f1f1f1}.about-wrap .notice:not(.hidden){display:block!important;margin-top:15px;margin-bottom:0;width:100%;box-sizing:border-box}.about-wrap .last-feature{margin-right:0!important}.about-wrap .panel{border-bottom:none;display:none;float:left;width:100%}.about-wrap .panel:first-child{display:block}.js .about-wrap .panel{display:none}.about-wrap .panel .submit{clear:both}.about-wrap .envato-market-blocks{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between}.about-wrap .envato-market-block{margin-bottom:20px;width:49%;width:calc(50% - 10px)}.about-wrap .envato-market-block ol ul{padding:10px 0 5px 17px;list-style:disc}.about-wrap .screenshot-image{text-align:right}.about-wrap .screenshot-image img{max-width:100%;height:auto}.about-wrap .screenshot-image span{background:#0074a2;color:#fff;font-size:.618em;text-transform:uppercase;padding:.53em 1em;position:absolute;top:0;right:0}.about-wrap .plugin-card{width:100%}.about-wrap .plugin-card .plugin-action-buttons{font-size:13px}.about-wrap #envato-market-items{margin:0;padding:0}.about-wrap #envato-market-items li{background-color:#fff;border:1px solid #dedede;-moz-box-sizing:border-box;box-sizing:border-box;min-height:40px;padding:10px;padding-right:40px;position:relative}.about-wrap #envato-market-items li.not-authorized{border-color:#dc3232}.about-wrap #envato-market-items .item-delete{background:0 0;border:none;box-shadow:none;color:#b3b9be;cursor:pointer;padding:0;position:absolute;right:0;top:0;width:38px;height:38px}.about-wrap #envato-market-items .item-delete:focus,.about-wrap #envato-market-items .item-delete:hover{color:#d61c00}.about-wrap #envato-market-items .item-delete:focus{-webkit-box-shadow:0 0 0 1px #5b9dd9,0 0 2px 1px rgba(30,140,190,.8);box-shadow:0 0 0 1px #5b9dd9,0 0 2px 1px rgba(30,140,190,.8)}#envato-market-dialog-form div.notice,#envato-market-dialog-remove div.notice{margin:0 0 10px 0!important}.envato-card{background-color:#fff;border:1px solid #dedede;box-sizing:border-box;margin:0;width:100%;display:flex;flex-direction:column;height:100%}.envato-card.active{border-color:#aaa}.envato-card .envato-card-top{min-height:140px;padding:20px;position:relative;flex-grow:1}.envato-card .envato-card-top .column-icon{height:80px;left:20px;margin:0 20px 20px 0;position:absolute;top:20px;width:80px}.envato-card .envato-card-top .column-name{margin-left:100px}.envato-card .envato-card-top .column-name h4{font-size:18px;line-height:1.3;margin:0 0 12px}.envato-card .envato-card-top .column-name h4 span{color:#999;display:inline-block;font-size:13px;font-weight:400;margin-left:5px}.envato-card .envato-card-top .column-description{margin-left:100px}.envato-card .envato-card-top .column-description .description{display:block;width:100%}.envato-card .envato-card-top .column-description .description.closed{max-height:45px;overflow:hidden}.envato-card .envato-card-top .column-description .description p:last-child{margin:0}.envato-card .envato-card-top .column-description a.read-more{margin-top:.5em}.envato-card .envato-card-top .column-description a.read-more:active,.envato-card .envato-card-top .column-description a.read-more:focus{-webkit-box-shadow:none;box-shadow:none}.envato-card .envato-card-top .column-description .author{margin-bottom:0}.envato-card .envato-card-top .column-update{background:#d54e21;background:rgba(213,78,33,.9);color:#fff;display:block;font-size:13px;font-weight:400;min-height:48px;line-height:1;padding:0 10px;position:absolute;top:0;left:0;border-bottom:1px solid rgba(0,0,0,.2);overflow:hidden;width:100%;box-sizing:border-box}.envato-card .envato-card-top .column-update.update-complete{background:#79ba49;background:rgba(121,186,73,.9)}.envato-card .envato-card-top .column-update a{color:#fff;outline:0;text-decoration:none}.envato-card .envato-card-top .column-update a:hover{text-decoration:underline}.envato-card .envato-card-top .column-update a:active,.envato-card .envato-card-top .column-update a:focus{outline:0;box-shadow:none}.envato-card .envato-card-top .column-update .update-now{display:block;float:left;padding:12px 0}.envato-card .envato-card-top .column-update .update-now:before{color:#fff;content:'\f463';display:inline-block;font:normal 20px/1 dashicons;margin:0 5px -1px 0;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;vertical-align:text-bottom}.envato-card .envato-card-top .column-update .updating-message:before{content:'\f463';-webkit-animation:rotation 2s infinite linear;animation:rotation 2s infinite linear}.envato-card .envato-card-top .column-update .updated-message:before{content:'\f147'}.envato-card .envato-card-top .column-update .details{display:block;float:right;padding:18px 0 8px}.envato-card .envato-card-bottom{background-color:#fafafa;border-top:1px solid #dedede;clear:both;overflow:hidden;padding:12px 20px}.envato-card .envato-card-bottom .column-rating{float:left;margin-top:4px}.envato-card .envato-card-bottom .column-actions{float:right}.envato-card .envato-card-bottom .column-actions .button{margin-left:10px;margin-bottom:0!important}.envato-card .envato-card-bottom .column-actions .button:first-child{margin-left:0}.envato-card .envato-card-bottom .star-rating{display:inline}.envato-card .envato-card-bottom .num-ratings{font-size:13px;line-height:23px}.envato-card.active .envato-card-bottom{border-top-color:#aaa}.envato-card .button-delete{color:#a00;padding:0 5px;line-height:2;text-decoration:none}.envato-card .button-delete:hover{color:red;border:none}@-webkit-keyframes rotation{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes rotation{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@media screen and (min-width:783px) and (max-width:1030px){.envato-card .envato-card-bottom .num-ratings{display:none}}@media screen and (min-width:783px){.about-wrap h2.nav-tab-wrapper .nav-tab-active{box-shadow:none}.about-wrap #settings .form-table td,.about-wrap #settings .form-table th{float:left;display:block;width:100%}.about-wrap #settings .form-table th{padding-bottom:0}.about-wrap #settings .form-table td{padding-left:0;padding-right:0}.about-wrap p.submit{margin-top:0;padding-top:0}}@media screen and (max-width:782px){.about-wrap h2.nav-tab-wrapper{border:none;padding:0}.about-wrap h2.nav-tab-wrapper .nav-tab{border-bottom:1px solid #ccc;text-align:center;margin:0 0 1% 0;padding:2%;width:100%;box-sizing:border-box}.about-wrap h2.nav-tab-wrapper .nav-tab-active,.about-wrap h2.nav-tab-wrapper .nav-tab-active:hover{background:#fff;border-bottom:1px solid #ccc}.about-wrap h2.nav-tab-wrapper .nav-tab-active:after,.about-wrap h2.nav-tab-wrapper .nav-tab-active:hover:after{display:none}.about-wrap .envato-market-block{width:100%}.about-wrap #plugins>div:first-child,.about-wrap #themes>div:first-child{margin-top:0!important}.about-wrap p.submit{float:left;margin-top:1.25em;width:100%}.about-wrap .screenshot-image{text-align:left}.about-wrap .screenshot-image img{max-width:100%}.about-wrap .button-delete{font-size:15px}.about-wrap .column-description .description{max-height:none!important;overflow:visible!important}.about-wrap .column-description a.read-more{display:none!important}}.healthcheck-error,.healthcheck-item,.healthcheck-ok{padding:0 0 14px 25px;position:relative}.healthcheck-error::before,.healthcheck-item::before,.healthcheck-ok::before{position:absolute;opacity:.7;font-family:dashicons;font-size:16px;vertical-align:bottom;left:0}.healthcheck-ok::before{content:'\f12a';color:#80b341}.healthcheck-error::before{content:'\f153';color:#ef3962}.healthcheck-error .limitTitle{color:#ef3962}.healthcheck-item-title{font-weight:500;white-space:nowrap}.healthcheck-item-message{margin-left:5px}css/envato-market-rtl.css000064400000021006147177457130011441 0ustar00.about-wrap{overflow:hidden}.about-wrap .about-title{margin-left:0}.about-wrap .about-title sup{background:#fff;color:#666;font-size:33.333%;font-weight:700;padding:5px 10px;white-space:nowrap}.about-wrap .about-title+p{font-size:1.2em}.about-wrap img.about-logo{width:280px!important;margin-left:5px}.about-wrap h2.nav-tab-wrapper{float:right;width:100%;box-sizing:border-box;margin-bottom:1em}.about-wrap h2.nav-tab-wrapper .nav-tab{float:right;font-weight:400;margin-bottom:0}.about-wrap h2.nav-tab-wrapper .nav-tab.hidden{display:none}.about-wrap h2.nav-tab-wrapper .nav-tab-active,.about-wrap h2.nav-tab-wrapper .nav-tab-active:hover{border-bottom:0}.about-wrap h2.nav-tab-wrapper .nav-tab-active{position:relative}.about-wrap h2.nav-tab-wrapper .nav-tab-active:after{content:"";display:block;position:absolute;width:100%;bottom:-1px;height:1px;right:0;background:#f1f1f1}.about-wrap .notice:not(.hidden){display:block!important;margin-top:15px;margin-bottom:0;width:100%;box-sizing:border-box}.about-wrap .last-feature{margin-left:0!important}.about-wrap .panel{border-bottom:none;display:none;float:right;width:100%}.about-wrap .panel:first-child{display:block}.js .about-wrap .panel{display:none}.about-wrap .panel .submit{clear:both}.about-wrap .envato-market-blocks{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between}.about-wrap .envato-market-block{margin-bottom:20px;width:49%;width:calc(50% - 10px)}.about-wrap .envato-market-block ol ul{padding:10px 17px 5px 0;list-style:disc}.about-wrap .screenshot-image{text-align:left}.about-wrap .screenshot-image img{max-width:100%;height:auto}.about-wrap .screenshot-image span{background:#0074a2;color:#fff;font-size:.618em;text-transform:uppercase;padding:.53em 1em;position:absolute;top:0;left:0}.about-wrap .plugin-card{width:100%}.about-wrap .plugin-card .plugin-action-buttons{font-size:13px}.about-wrap #envato-market-items{margin:0;padding:0}.about-wrap #envato-market-items li{background-color:#fff;border:1px solid #dedede;-moz-box-sizing:border-box;box-sizing:border-box;min-height:40px;padding:10px;padding-left:40px;position:relative}.about-wrap #envato-market-items li.not-authorized{border-color:#dc3232}.about-wrap #envato-market-items .item-delete{background:0 0;border:none;box-shadow:none;color:#b3b9be;cursor:pointer;padding:0;position:absolute;left:0;top:0;width:38px;height:38px}.about-wrap #envato-market-items .item-delete:focus,.about-wrap #envato-market-items .item-delete:hover{color:#d61c00}.about-wrap #envato-market-items .item-delete:focus{-webkit-box-shadow:0 0 0 1px #5b9dd9,0 0 2px 1px rgba(30,140,190,.8);box-shadow:0 0 0 1px #5b9dd9,0 0 2px 1px rgba(30,140,190,.8)}#envato-market-dialog-form div.notice,#envato-market-dialog-remove div.notice{margin:0 0 10px 0!important}.envato-card{background-color:#fff;border:1px solid #dedede;box-sizing:border-box;margin:0;width:100%;display:flex;flex-direction:column;height:100%}.envato-card.active{border-color:#aaa}.envato-card .envato-card-top{min-height:140px;padding:20px;position:relative;flex-grow:1}.envato-card .envato-card-top .column-icon{height:80px;right:20px;margin:0 0 20px 20px;position:absolute;top:20px;width:80px}.envato-card .envato-card-top .column-name{margin-right:100px}.envato-card .envato-card-top .column-name h4{font-size:18px;line-height:1.3;margin:0 0 12px}.envato-card .envato-card-top .column-name h4 span{color:#999;display:inline-block;font-size:13px;font-weight:400;margin-right:5px}.envato-card .envato-card-top .column-description{margin-right:100px}.envato-card .envato-card-top .column-description .description{display:block;width:100%}.envato-card .envato-card-top .column-description .description.closed{max-height:45px;overflow:hidden}.envato-card .envato-card-top .column-description .description p:last-child{margin:0}.envato-card .envato-card-top .column-description a.read-more{margin-top:.5em}.envato-card .envato-card-top .column-description a.read-more:active,.envato-card .envato-card-top .column-description a.read-more:focus{-webkit-box-shadow:none;box-shadow:none}.envato-card .envato-card-top .column-description .author{margin-bottom:0}.envato-card .envato-card-top .column-update{background:#d54e21;background:rgba(213,78,33,.9);color:#fff;display:block;font-size:13px;font-weight:400;min-height:48px;line-height:1;padding:0 10px;position:absolute;top:0;right:0;border-bottom:1px solid rgba(0,0,0,.2);overflow:hidden;width:100%;box-sizing:border-box}.envato-card .envato-card-top .column-update.update-complete{background:#79ba49;background:rgba(121,186,73,.9)}.envato-card .envato-card-top .column-update a{color:#fff;outline:0;text-decoration:none}.envato-card .envato-card-top .column-update a:hover{text-decoration:underline}.envato-card .envato-card-top .column-update a:active,.envato-card .envato-card-top .column-update a:focus{outline:0;box-shadow:none}.envato-card .envato-card-top .column-update .update-now{display:block;float:right;padding:12px 0}.envato-card .envato-card-top .column-update .update-now:before{color:#fff;content:'\f463';display:inline-block;font:normal 20px/1 dashicons;margin:0 0 -1px 5px;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;vertical-align:text-bottom}.envato-card .envato-card-top .column-update .updating-message:before{content:'\f463';-webkit-animation:rotation 2s infinite linear;animation:rotation 2s infinite linear}.envato-card .envato-card-top .column-update .updated-message:before{content:'\f147'}.envato-card .envato-card-top .column-update .details{display:block;float:left;padding:18px 0 8px}.envato-card .envato-card-bottom{background-color:#fafafa;border-top:1px solid #dedede;clear:both;overflow:hidden;padding:12px 20px}.envato-card .envato-card-bottom .column-rating{float:right;margin-top:4px}.envato-card .envato-card-bottom .column-actions{float:left}.envato-card .envato-card-bottom .column-actions .button{margin-right:10px;margin-bottom:0!important}.envato-card .envato-card-bottom .column-actions .button:first-child{margin-right:0}.envato-card .envato-card-bottom .star-rating{display:inline}.envato-card .envato-card-bottom .num-ratings{font-size:13px;line-height:23px}.envato-card.active .envato-card-bottom{border-top-color:#aaa}.envato-card .button-delete{color:#a00;padding:0 5px;line-height:2;text-decoration:none}.envato-card .button-delete:hover{color:red;border:none}@-webkit-keyframes rotation{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(-359deg);transform:rotate(-359deg)}}@keyframes rotation{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(-359deg);transform:rotate(-359deg)}}@media screen and (min-width:783px) and (max-width:1030px){.envato-card .envato-card-bottom .num-ratings{display:none}}@media screen and (min-width:783px){.about-wrap h2.nav-tab-wrapper .nav-tab-active{box-shadow:none}.about-wrap #settings .form-table td,.about-wrap #settings .form-table th{float:right;display:block;width:100%}.about-wrap #settings .form-table th{padding-bottom:0}.about-wrap #settings .form-table td{padding-right:0;padding-left:0}.about-wrap p.submit{margin-top:0;padding-top:0}}@media screen and (max-width:782px){.about-wrap h2.nav-tab-wrapper{border:none;padding:0}.about-wrap h2.nav-tab-wrapper .nav-tab{border-bottom:1px solid #ccc;text-align:center;margin:0 0 1% 0;padding:2%;width:100%;box-sizing:border-box}.about-wrap h2.nav-tab-wrapper .nav-tab-active,.about-wrap h2.nav-tab-wrapper .nav-tab-active:hover{background:#fff;border-bottom:1px solid #ccc}.about-wrap h2.nav-tab-wrapper .nav-tab-active:after,.about-wrap h2.nav-tab-wrapper .nav-tab-active:hover:after{display:none}.about-wrap .envato-market-block{width:100%}.about-wrap #plugins>div:first-child,.about-wrap #themes>div:first-child{margin-top:0!important}.about-wrap p.submit{float:right;margin-top:1.25em;width:100%}.about-wrap .screenshot-image{text-align:right}.about-wrap .screenshot-image img{max-width:100%}.about-wrap .button-delete{font-size:15px}.about-wrap .column-description .description{max-height:none!important;overflow:visible!important}.about-wrap .column-description a.read-more{display:none!important}}.healthcheck-error,.healthcheck-item,.healthcheck-ok{padding:0 25px 14px 0;position:relative}.healthcheck-error::before,.healthcheck-item::before,.healthcheck-ok::before{position:absolute;opacity:.7;font-family:dashicons;font-size:16px;vertical-align:bottom;right:0}.healthcheck-ok::before{content:'\f12a';color:#80b341}.healthcheck-error::before{content:'\f153';color:#ef3962}.healthcheck-error .limitTitle{color:#ef3962}.healthcheck-item-title{font-weight:500;white-space:nowrap}.healthcheck-item-message{margin-right:5px}images/envato-market-logo.svg000064400000013714147177457130012273 0ustar00inc/admin/view/partials/themes.php000064400000000715147177457130013217 0ustar00items()->themes( 'purchased' ); ?>
inc/admin/view/partials/plugins.php000064400000000726147177457130013415 0ustar00items()->plugins( 'purchased' ); ?>
inc/admin/view/partials/help.php000064400000005201147177457130012655 0ustar00

Troubleshooting:

If you’re having trouble with the plugin, please

  1. Confirm the old Envato Toolkit plugin is not installed.
  2. Confirm the latest version of WordPress is installed.
  3. Confirm the latest version of the Envato Market plugin is installed.
  4. Try creating a new API token has from the build.envato.com website - ensure only the following permissions have been granted
    • View and search Envato sites
    • Download your purchased items
    • List purchases you've made
  5. Check with the hosting provider to ensure the API connection to api.envato.com is not blocked.
  6. Check with the hosting provider that the minimum TLS version is 1.2 or above on the server.
  7. If you can’t see your items - check with the item author to confirm the Theme or Plugin is compatible with the Envato Market plugin.
  8. Confirm your Envato account is still active and the items are still visible from your downloads page.
  9. Note - if an item has been recently updated, it may take up to 24 hours for the latest version to appear in the Envato Market plugin.

Health Check:

Problem starting healthcheck. Please check javascript console for errors.

Support:

The Envato Market plugin is maintained - we ensure it works best on the latest version of WordPress and on a modern hosting platform, however we can’t guarantee it’ll work on all WordPress sites or hosting environments.

If you’ve tried all the troubleshooting steps and you’re still unable to get the Envato Market plugin to work on your site/hosting, at this time, our advice is to remove the Envato Market plugin and instead visit the Downloads section of ThemeForest/CodeCanyon to download the latest version of your items.

If you’re having trouble with a specific item from ThemeForest or CodeCanyon, it’s best you browse to the Theme or Plugin item page, visit the ‘support’ tab and follow the next steps.

inc/admin/view/partials/settings.php000064400000001760147177457130013573 0ustar00get_option( 'token' ); $items = envato_market()->get_option( 'items', array() ); ?>
get_slug() ); ?> get_slug(), 2 ); ?>

inc/admin/view/partials/tabs.php000064400000002724147177457130012665 0ustar00items()->themes( 'purchased' ); $plugins = envato_market()->items()->plugins( 'purchased' ); ?> inc/admin/view/partials/intro.php000064400000001671147177457130013067 0ustar00

get_version() ); ?>

', '' ); ?>

inc/admin/view/notice/error-missing-zip.php000064400000000645147177457130014776 0ustar00

downloads page' ); ?>

inc/admin/view/notice/error-permissions.php000064400000001054147177457130015073 0ustar00

    get_required_permissions() as $permission ) { ?>
inc/admin/view/notice/error-http.php000064400000000741147177457130013501 0ustar00

inc/admin/view/notice/error.php000064400000000513147177457130012521 0ustar00

inc/admin/view/notice/success.php000064400000000353147177457130013042 0ustar00

inc/admin/view/notice/success-no-items.php000064400000000457147177457130014600 0ustar00

inc/admin/view/notice/error-details.php000064400000000466147177457130014153 0ustar00

Additional Error Details:
%s.
%s
%s', esc_html( $title ), esc_html( $message ), esc_html( json_encode( $data ) ) ); ?>

inc/admin/view/notice/error-single-use.php000064400000000424147177457130014573 0ustar00

inc/admin/view/notice/success-single-use.php000064400000000367147177457130015120 0ustar00

inc/admin/view/callback/setting/items.php000064400000003531147177457130014444 0ustar00get_option( 'items', array() ); ?>
    $item ) { if ( empty( $item['name'] ) || empty( $item['token'] ) || empty( $item['id'] ) || empty( $item['type'] ) || empty( $item['authorized'] ) ) { continue; } $class = 'success' === $item['authorized'] ? 'is-authorized' : 'not-authorized'; echo '
  • ' . esc_html__( 'ID', 'envato-market' ) . ': ' . esc_html( $item['id'] ) . ' - ' . esc_html( $item['name'] ) . '
  • '; } } ?>
inc/admin/view/callback/setting/token.php000064400000000612147177457130014440 0ustar00

inc/admin/view/callback/admin.php000064400000002011147177457130012726 0ustar00

' . esc_html__( 'envato.com', 'envato-market' ) . '' ); ?>

  1. admin()->get_generate_token_url() . '" target="_blank">' . esc_html__( 'clicking this link', 'envato-market' ) . '' ); ?>
inc/admin/view/callback/section/items.php000064400000001032147177457130014425 0ustar00

inc/admin/class-envato-market-admin.php000064400000162261147177457130014114 0ustar00init_actions(); } return self::$_instance; } /** * A dummy constructor to prevent this class from being loaded more than once. * * @see Envato_Market_Admin::instance() * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function __construct() { /* We do nothing here! */ } /** * You cannot clone this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __clone() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * You cannot unserialize instances of this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __wakeup() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * Setup the hooks, actions and filters. * * @uses add_action() To add actions. * @uses add_filter() To add filters. * * @since 1.0.0 */ public function init_actions() { // @codeCoverageIgnoreStart if ( false === envato_market()->get_data( 'admin' ) && false === envato_market()->get_option( 'is_plugin_active' ) ) { // Turns the UI off if allowed. return; } // @codeCoverageIgnoreEnd // Deferred Download. add_action( 'upgrader_package_options', array( $this, 'maybe_deferred_download' ), 9 ); // Add pre download filter to help with 3rd party plugin integration. add_filter( 'upgrader_pre_download', array( $this, 'upgrader_pre_download' ), 2, 4 ); // Add item AJAX handler. add_action( 'wp_ajax_' . self::AJAX_ACTION . '_add_item', array( $this, 'ajax_add_item' ) ); // Remove item AJAX handler. add_action( 'wp_ajax_' . self::AJAX_ACTION . '_remove_item', array( $this, 'ajax_remove_item' ) ); // Health check AJAX handler add_action( 'wp_ajax_' . self::AJAX_ACTION . '_healthcheck', array( $this, 'ajax_healthcheck' ) ); // Maybe delete the site transients. add_action( 'init', array( $this, 'maybe_delete_transients' ), 11 ); // Add the menu. add_action( 'admin_menu', array( $this, 'add_menu_page' ) ); // Register the settings. add_action( 'admin_init', array( $this, 'register_settings' ) ); // We may need to redirect after an item is enabled. add_action( 'current_screen', array( $this, 'maybe_redirect' ) ); // Add authorization notices. add_action( 'current_screen', array( $this, 'add_notices' ) ); // Set the API values. add_action( 'current_screen', array( $this, 'set_items' ) ); // Hook to verify the API token before saving it. add_filter( 'pre_update_option_' . envato_market()->get_option_name(), array( $this, 'check_api_token_before_saving', ), 9, 3 ); add_filter( 'pre_update_site_option_' . envato_market()->get_option_name(), array( $this, 'check_api_token_before_saving', ), 9, 3 ); // When network enabled, add the network options menu. add_action( 'network_admin_menu', array( $this, 'add_menu_page' ) ); // Ability to make use of the Settings API when in multisite mode. add_action( 'network_admin_edit_envato_market_network_settings', array( $this, 'save_network_settings' ) ); } /** * This runs before we save the Envato Market options array. * If the token has changed then we set a transient so we can do the update check. * * @param array $value The option to save. * @param array $old_value The old option value. * @param array $option Serialized option value. * * @return array $value The updated option value. * @since 2.0.1 */ public function check_api_token_before_saving( $value, $old_value, $option ) { if ( ! empty( $value['token'] ) && ( empty( $old_value['token'] ) || $old_value['token'] != $value['token'] || isset( $_POST['envato_market'] ) ) ) { set_site_transient( envato_market()->get_option_name() . '_check_token', $value['token'], HOUR_IN_SECONDS ); } return $value; } /** * Defers building the API download url until the last responsible moment to limit file requests. * * Filter the package options before running an update. * * @param array $options { * Options used by the upgrader. * * @type string $package Package for update. * @type string $destination Update location. * @type bool $clear_destination Clear the destination resource. * @type bool $clear_working Clear the working resource. * @type bool $abort_if_destination_exists Abort if the Destination directory exists. * @type bool $is_multi Whether the upgrader is running multiple times. * @type array $hook_extra Extra hook arguments. * } * @since 1.0.0 */ public function maybe_deferred_download( $options ) { $package = $options['package']; if ( false !== strrpos( $package, 'deferred_download' ) && false !== strrpos( $package, 'item_id' ) ) { parse_str( parse_url( $package, PHP_URL_QUERY ), $vars ); if ( $vars['item_id'] ) { $args = $this->set_bearer_args( $vars['item_id'] ); $options['package'] = envato_market()->api()->download( $vars['item_id'], $args ); } } return $options; } /** * We want to stop certain popular 3rd party scripts from blocking the update process by * adjusting the plugin name slightly so the 3rd party plugin checks stop. * * Currently works for: Visual Composer. * * @param string $reply Package URL. * @param string $package Package URL. * @param object $updater Updater Object. * * @return string $reply New Package URL. * @since 2.0.0 */ public function upgrader_pre_download( $reply, $package, $updater ) { if ( strpos( $package, 'marketplace.envato.com/short-dl' ) !== false ) { if ( isset( $updater->skin->plugin_info ) && ! empty( $updater->skin->plugin_info['Name'] ) ) { $updater->skin->plugin_info['Name'] = $updater->skin->plugin_info['Name'] . '.'; } else { $updater->skin->plugin_info = array( 'Name' => 'Name', ); } } return $reply; } /** * Returns the bearer arguments for a request with a single use API Token. * * @param int $id The item ID. * * @return array * @since 1.0.0 */ public function set_bearer_args( $id ) { $token = ''; $args = array(); foreach ( envato_market()->get_option( 'items', array() ) as $item ) { if ( absint( $item['id'] ) === absint( $id ) ) { $token = $item['token']; break; } } if ( ! empty( $token ) ) { $args = array( 'headers' => array( 'Authorization' => 'Bearer ' . $token, ), ); } return $args; } /** * Maybe delete the site transients. * * @since 1.0.0 * @codeCoverageIgnore */ public function maybe_delete_transients() { if ( isset( $_POST[ envato_market()->get_option_name() ] ) ) { // Nonce check. if ( isset( $_POST['_wpnonce'] ) && ! wp_verify_nonce( $_POST['_wpnonce'], envato_market()->get_slug() . '-options' ) ) { wp_die( __( 'You do not have sufficient permissions to delete transients.', 'envato-market' ) ); } self::delete_transients(); } elseif ( ! envato_market()->get_option( 'installed_version', 0 ) || version_compare( envato_market()->get_version(), envato_market()->get_option( 'installed_version', 0 ), '<' ) ) { // When the plugin updates we want to delete transients. envato_market()->set_option( 'installed_version', envato_market()->get_version() ); self::delete_transients(); } } /** * Delete the site transients. * * @since 1.0.0 * @access private */ private function delete_transients() { delete_site_transient( envato_market()->get_option_name() . '_themes' ); delete_site_transient( envato_market()->get_option_name() . '_plugins' ); } /** * Prints out all settings sections added to a particular settings page in columns. * * @param string $page The slug name of the page whos settings sections you want to output. * @param int $columns The number of columns in each row. * * @since 1.0.0 * * @global array $wp_settings_sections Storage array of all settings sections added to admin pages * @global array $wp_settings_fields Storage array of settings fields and info about their pages/sections */ public static function do_settings_sections( $page, $columns = 2 ) { global $wp_settings_sections, $wp_settings_fields; // @codeCoverageIgnoreStart if ( ! isset( $wp_settings_sections[ $page ] ) ) { return; } // @codeCoverageIgnoreEnd foreach ( (array) $wp_settings_sections[ $page ] as $section ) { // @codeCoverageIgnoreStart if ( ! isset( $wp_settings_fields ) || ! isset( $wp_settings_fields[ $page ] ) || ! isset( $wp_settings_fields[ $page ][ $section['id'] ] ) ) { continue; } // @codeCoverageIgnoreEnd // Set the column class. $class = 'envato-market-block'; ?>
' . esc_html( $section['title'] ) . '' . "\n"; } if ( ! empty( $section['callback'] ) ) { call_user_func( $section['callback'], $section ); } ?>
'; $page = add_menu_page( __( 'Envato Market', 'envato-market' ), __( 'Envato Market', 'envato-market' ), 'manage_options', envato_market()->get_slug(), array( $this, 'render_admin_callback', ), 'data:image/svg+xml;base64,' . base64_encode($svg_icon) ); // Enqueue admin CSS. add_action( 'admin_print_styles-' . $page, array( $this, 'admin_enqueue_style' ) ); // Enqueue admin JavaScript. add_action( 'admin_print_scripts-' . $page, array( $this, 'admin_enqueue_script' ) ); // Add Underscore.js templates. add_action( 'admin_footer-' . $page, array( $this, 'render_templates' ) ); } /** * Enqueue admin css. * * @since 1.0.0 */ public function admin_enqueue_style() { $file_url = envato_market()->get_plugin_url() . 'css/envato-market' . ( is_rtl() ? '-rtl' : '' ) . '.css'; wp_enqueue_style( envato_market()->get_slug(), $file_url, array( 'wp-jquery-ui-dialog' ), envato_market()->get_version() ); } /** * Enqueue admin script. * * @since 1.0.0 */ public function admin_enqueue_script() { $min = ( WP_DEBUG ? '' : '.min' ); $slug = envato_market()->get_slug(); $version = envato_market()->get_version(); $plugin_url = envato_market()->get_plugin_url(); wp_enqueue_script( $slug, $plugin_url . 'js/envato-market' . $min . '.js', array( 'jquery', 'jquery-ui-dialog', 'wp-util', ), $version, true ); wp_enqueue_script( $slug . '-updates', $plugin_url . 'js/updates' . $min . '.js', array( 'jquery', 'updates', 'wp-a11y', 'wp-util', ), $version, true ); // Script data array. $exports = array( 'nonce' => wp_create_nonce( self::AJAX_ACTION ), 'action' => self::AJAX_ACTION, 'i18n' => array( 'save' => __( 'Save', 'envato-market' ), 'remove' => __( 'Remove', 'envato-market' ), 'cancel' => __( 'Cancel', 'envato-market' ), 'error' => __( 'An unknown error occurred. Try again.', 'envato-market' ), ), ); // Export data to JS. wp_scripts()->add_data( $slug, 'data', sprintf( 'var _envatoMarket = %s;', wp_json_encode( $exports ) ) ); } /** * Underscore (JS) templates for dialog windows. * * @codeCoverageIgnore */ public function render_templates() { ?> get_slug(), envato_market()->get_option_name() ); // OAuth section. add_settings_section( envato_market()->get_option_name() . '_oauth_section', __( 'Getting Started (Simple)', 'envato-market' ), array( $this, 'render_oauth_section_callback' ), envato_market()->get_slug() ); // Token setting. add_settings_field( 'token', __( 'Token', 'envato-market' ), array( $this, 'render_token_setting_callback' ), envato_market()->get_slug(), envato_market()->get_option_name() . '_oauth_section' ); // Items section. add_settings_section( envato_market()->get_option_name() . '_items_section', __( 'Single Item Tokens (Advanced)', 'envato-market' ), array( $this, 'render_items_section_callback' ), envato_market()->get_slug() ); // Items setting. add_settings_field( 'items', __( 'Envato Market Items', 'envato-market' ), array( $this, 'render_items_setting_callback' ), envato_market()->get_slug(), envato_market()->get_option_name() . '_items_section' ); } /** * Redirect after the enable action runs. * * @since 1.0.0 * @codeCoverageIgnore */ public function maybe_redirect() { if ( $this->are_we_on_settings_page() ) { if ( ! empty( $_GET['action'] ) && 'install-theme' === $_GET['action'] && ! empty( $_GET['enabled'] ) ) { wp_safe_redirect( esc_url( envato_market()->get_page_url() ) ); exit; } } } /** * Add authorization notices. * * @since 1.0.0 */ public function add_notices() { if ( $this->are_we_on_settings_page() ) { // @codeCoverageIgnoreStart if ( get_site_transient( envato_market()->get_option_name() . '_check_token' ) || ( isset( $_GET['authorization'] ) && 'check' === $_GET['authorization'] ) ) { delete_site_transient( envato_market()->get_option_name() . '_check_token' ); self::authorization_redirect(); } // @codeCoverageIgnoreEnd // Get the option array. $option = envato_market()->get_options(); // Display success/error notices. if ( ! empty( $option['notices'] ) ) { self::delete_transients(); // Show succes notice. if ( isset( $option['notices']['success'] ) ) { add_action( ( ENVATO_MARKET_NETWORK_ACTIVATED ? 'network_' : '' ) . 'admin_notices', array( $this, 'render_success_notice', ) ); } // Show succes no-items notice. if ( isset( $option['notices']['success-no-items'] ) ) { add_action( ( ENVATO_MARKET_NETWORK_ACTIVATED ? 'network_' : '' ) . 'admin_notices', array( $this, 'render_success_no_items_notice', ) ); } // Show single-use succes notice. if ( isset( $option['notices']['success-single-use'] ) ) { add_action( ( ENVATO_MARKET_NETWORK_ACTIVATED ? 'network_' : '' ) . 'admin_notices', array( $this, 'render_success_single_use_notice', ) ); } // Show error notice. if ( isset( $option['notices']['error'] ) ) { add_action( ( ENVATO_MARKET_NETWORK_ACTIVATED ? 'network_' : '' ) . 'admin_notices', array( $this, 'render_error_notice', ) ); } // Show invalid permissions error notice. if ( isset( $option['notices']['error-permissions'] ) ) { add_action( ( ENVATO_MARKET_NETWORK_ACTIVATED ? 'network_' : '' ) . 'admin_notices', array( $this, 'render_error_permissions', ) ); } // Show single-use error notice. if ( isset( $option['notices']['error-single-use'] ) ) { add_action( ( ENVATO_MARKET_NETWORK_ACTIVATED ? 'network_' : '' ) . 'admin_notices', array( $this, 'render_error_single_use_notice', ) ); } // Show missing zip notice. if ( isset( $option['notices']['missing-package-zip'] ) ) { add_action( ( ENVATO_MARKET_NETWORK_ACTIVATED ? 'network_' : '' ) . 'admin_notices', array( $this, 'render_error_missing_zip', ) ); } // Show missing http connection error. if ( isset( $option['notices']['http_error'] ) ) { add_action( ( ENVATO_MARKET_NETWORK_ACTIVATED ? 'network_' : '' ) . 'admin_notices', array( $this, 'render_error_http', ) ); } // Update the saved data so the notice disappears on the next page load. unset( $option['notices'] ); envato_market()->set_options( $option ); } } } /** * Set the API values. * * @since 1.0.0 */ public function set_items() { if ( $this->are_we_on_settings_page() ) { envato_market()->items()->set_themes(); envato_market()->items()->set_plugins(); } } /** * Check if we're on the settings page. * * @since 2.0.0 * @access private */ private function are_we_on_settings_page() { return 'toplevel_page_' . envato_market()->get_slug() === get_current_screen()->id || 'toplevel_page_' . envato_market()->get_slug() . '-network' === get_current_screen()->id; } /** * Check for authorization and redirect. * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function authorization_redirect() { self::authorization(); wp_safe_redirect( esc_url( envato_market()->get_page_url() . '#settings' ) ); exit; } /** * Set the Envato API authorization value. * * @since 1.0.0 */ public function authorization() { // Get the option array. $option = envato_market()->get_options(); $option['notices'] = array(); // Check for global token. if ( envato_market()->get_option( 'token' ) || envato_market()->api()->token ) { $notice = 'success'; $scope_check = $this->authorize_token_permissions(); if ( 'http_error' === $scope_check ) { $notice = 'http_error'; } elseif ( 'error' === $this->authorize_total_items() || 'error' === $scope_check ) { $notice = 'error'; } else { if ( 'missing-permissions' == $scope_check ) { $notice = 'error-permissions'; } elseif ( 'too-many-permissions' === $scope_check ) { $notice = 'error-permissions'; } else { $themes_notice = $this->authorize_themes(); $plugins_notice = $this->authorize_plugins(); if ( 'error' === $themes_notice || 'error' === $plugins_notice ) { $notice = 'error'; } elseif ( 'success-no-themes' === $themes_notice && 'success-no-plugins' === $plugins_notice ) { $notice = 'success-no-items'; } } } $option['notices'][ $notice ] = true; } // Check for single-use token. if ( ! empty( $option['items'] ) ) { $failed = false; foreach ( $option['items'] as $key => $item ) { if ( empty( $item['name'] ) || empty( $item['token'] ) || empty( $item['id'] ) || empty( $item['type'] ) || empty( $item['authorized'] ) ) { continue; } $request_args = array( 'headers' => array( 'Authorization' => 'Bearer ' . $item['token'], ), ); // Uncached API response with single-use token. $response = envato_market()->api()->item( $item['id'], $request_args ); if ( ! is_wp_error( $response ) && isset( $response['id'] ) ) { $option['items'][ $key ]['authorized'] = 'success'; } else { if ( is_wp_error( $response ) ) { $this->store_additional_error_debug_information( 'Unable to query single item ID ' . $item['id'], $response->get_error_message(), $response->get_error_data() ); } $failed = true; $option['items'][ $key ]['authorized'] = 'failed'; } } if ( true === $failed ) { $option['notices']['error-single-use'] = true; } else { $option['notices']['success-single-use'] = true; } } // Set the option array. if ( ! empty( $option['notices'] ) ) { envato_market()->set_options( $option ); } } /** * Check that themes are authorized. * * @return bool * @since 1.0.0 */ public function authorize_total_items() { $domain = envato_market()->get_envato_api_domain(); $path = envato_market()->api()->api_path_for('total-items'); $url = $domain . $path; $response = envato_market()->api()->request( $url ); $notice = 'success'; if ( is_wp_error( $response ) ) { $notice = 'error'; $this->store_additional_error_debug_information( 'Failed to query total number of items in API response', $response->get_error_message(), $response->get_error_data() ); } elseif ( ! isset( $response['total-items'] ) ) { $notice = 'error'; $this->store_additional_error_debug_information( 'Incorrect response from API when querying total items' ); } return $notice; } /** * Get the required API permissions for this plugin to work. * * @single 2.0.1 * * @return array */ public function get_required_permissions() { return apply_filters( 'envato_market_required_permissions', array( 'default' => 'View and search Envato sites', 'purchase:download' => 'Download your purchased items', 'purchase:list' => 'List purchases you\'ve made', ) ); } /** * Return the URL a user needs to click to generate a personal token. * * @single 2.0.1 * * @return string The full URL to request a token. */ public function get_generate_token_url() { return 'https://build.envato.com/create-token/?' . implode( '&', array_map( function ( $val ) { return $val . '=t'; }, array_keys( $this->get_required_permissions() ) ) ); } /** * Check that themes are authorized. * * @return bool * @since 1.0.0 */ public function authorize_token_permissions() { if ( defined('ENVATO_LOCAL_DEVELOPMENT') ) { return 'success'; } $notice = 'success'; $response = envato_market()->api()->request( 'https://api.envato.com/whoami' ); if ( is_wp_error( $response ) && ( $response->get_error_code() === 'http_error' || $response->get_error_code() == 500 ) ) { $this->store_additional_error_debug_information( 'An error occured checking token permissions', $response->get_error_message(), $response->get_error_data() ); $notice = 'http_error'; } elseif ( is_wp_error( $response ) || ! isset( $response['scopes'] ) || ! is_array( $response['scopes'] ) ) { $this->store_additional_error_debug_information( 'No scopes found in API response message', $response->get_error_message(), $response->get_error_data() ); $notice = 'error'; } else { $minimum_scopes = $this->get_required_permissions(); $maximum_scopes = array( 'default' => 'Default' ) + $minimum_scopes; foreach ( $minimum_scopes as $required_scope => $required_scope_name ) { if ( ! in_array( $required_scope, $response['scopes'] ) ) { // The scope minimum required scope doesn't exist. $this->store_additional_error_debug_information( 'Could not find required API permission scope in output.', $required_scope ); $notice = 'missing-permissions'; } } foreach ( $response['scopes'] as $scope ) { if ( ! isset( $maximum_scopes[ $scope ] ) ) { // The available scope is outside our maximum bounds. $this->store_additional_error_debug_information( 'Found too many permissions on token.', $scope ); $notice = 'too-many-permissions'; } } } return $notice; } /** * Check that themes or plugins are authorized and downloadable. * * @param string $type The filter type, either 'themes' or 'plugins'. Default 'themes'. * * @return bool|null * @since 1.0.0 */ public function authorize_items( $type = 'themes' ) { $domain = envato_market()->get_envato_api_domain(); $path = envato_market()->api()->api_path_for('list-purchases'); $api_url = $domain . $path . '?filter_by=wordpress-' . $type; $response = envato_market()->api()->request( $api_url ); $notice = 'success'; if ( is_wp_error( $response ) ) { $notice = 'error'; $this->store_additional_error_debug_information( 'Error listing buyer purchases.', $response->get_error_message(), $response->get_error_data() ); } elseif ( empty( $response ) ) { $notice = 'error'; $this->store_additional_error_debug_information( 'Empty API result listing buyer purchases' ); } elseif ( empty( $response['results'] ) ) { $notice = 'success-no-' . $type; } else { shuffle( $response['results'] ); $item = array_shift( $response['results'] ); if ( ! isset( $item['item']['id'] ) || ! envato_market()->api()->download( $item['item']['id'] ) ) { $this->store_additional_error_debug_information( 'Failed to find the correct item format in API response' ); $notice = 'error'; } } return $notice; } /** * Check that themes are authorized. * * @return bool * @since 1.0.0 */ public function authorize_themes() { return $this->authorize_items( 'themes' ); } /** * Check that plugins are authorized. * * @return bool * @since 1.0.0 */ public function authorize_plugins() { return $this->authorize_items( 'plugins' ); } /** * Install plugin. * * @param string $plugin The plugin item ID. * * @since 1.0.0 * @codeCoverageIgnore */ public function install_plugin( $plugin ) { if ( ! current_user_can( 'install_plugins' ) ) { $msg = '

' . __( 'Installing Plugin...', 'envato-market' ) . '

' . __( 'You do not have sufficient permissions to install plugins on this site.', 'envato-market' ) . '

' . __( 'Return to Plugin Installer', 'envato-market' ) . '
'; wp_die( $msg ); } check_admin_referer( 'install-plugin_' . $plugin ); envato_market()->items()->set_plugins( true ); $install = envato_market()->items()->plugins( 'install' ); $api = new stdClass(); foreach ( $install as $value ) { if ( absint( $value['id'] ) === absint( $plugin ) ) { $api->name = $value['name']; $api->version = $value['version']; } } $array_api = (array) $api; if ( empty( $array_api ) ) { $msg = '

' . __( 'Installing Plugin...', 'envato-market' ) . '

' . __( 'An error occurred, please check that the item ID is correct.', 'envato-market' ) . '

' . __( 'Return to Plugin Installer', 'envato-market' ) . '
'; wp_die( $msg ); } $title = sprintf( __( 'Installing Plugin: %s', 'envato-market' ), esc_html( $api->name . ' ' . $api->version ) ); $nonce = 'install-plugin_' . $plugin; $url = 'admin.php?page=' . envato_market()->get_slug() . '&action=install-plugin&plugin=' . urlencode( $plugin ); $type = 'web'; // Install plugin type, From Web or an Upload. $api->download_link = envato_market()->api()->download( $plugin, $this->set_bearer_args( $plugin ) ); // Must have the upgrader & skin. require envato_market()->get_plugin_path() . '/inc/admin/class-envato-market-theme-upgrader.php'; require envato_market()->get_plugin_path() . '/inc/admin/class-envato-market-theme-installer-skin.php'; $upgrader = new Envato_Market_Plugin_Upgrader( new Envato_Market_Plugin_Installer_Skin( compact( 'title', 'url', 'nonce', 'plugin', 'api' ) ) ); $upgrader->install( $api->download_link ); } /** * Install theme. * * @param string $theme The theme item ID. * * @since 1.0.0 * @codeCoverageIgnore */ public function install_theme( $theme ) { if ( ! current_user_can( 'install_themes' ) ) { $msg = '

' . __( 'Installing Theme...', 'envato-market' ) . '

' . __( 'You do not have sufficient permissions to install themes on this site.', 'envato-market' ) . '

' . __( 'Return to Theme Installer', 'envato-market' ) . '
'; wp_die( $msg ); } check_admin_referer( 'install-theme_' . $theme ); envato_market()->items()->set_themes( true ); $install = envato_market()->items()->themes( 'install' ); $api = new stdClass(); foreach ( $install as $value ) { if ( absint( $value['id'] ) === absint( $theme ) ) { $api->name = $value['name']; $api->version = $value['version']; } } $array_api = (array) $api; if ( empty( $array_api ) ) { $msg = '

' . __( 'Installing Theme...', 'envato-market' ) . '

' . __( 'An error occurred, please check that the item ID is correct.', 'envato-market' ) . '

' . __( 'Return to Plugin Installer', 'envato-market' ) . '
'; wp_die( $msg ); } wp_enqueue_script( 'customize-loader' ); $title = sprintf( __( 'Installing Theme: %s', 'envato-market' ), esc_html( $api->name . ' ' . $api->version ) ); $nonce = 'install-theme_' . $theme; $url = 'admin.php?page=' . envato_market()->get_slug() . '&action=install-theme&theme=' . urlencode( $theme ); $type = 'web'; // Install theme type, From Web or an Upload. $api->download_link = envato_market()->api()->download( $theme, $this->set_bearer_args( $theme ) ); // Must have the upgrader & skin. require_once envato_market()->get_plugin_path() . '/inc/admin/class-envato-market-theme-upgrader.php'; require_once envato_market()->get_plugin_path() . '/inc/admin/class-envato-market-theme-installer-skin.php'; $upgrader = new Envato_Market_Theme_Upgrader( new Envato_Market_Theme_Installer_Skin( compact( 'title', 'url', 'nonce', 'api' ) ) ); $upgrader->install( $api->download_link ); } /** * AJAX handler for adding items that use a non global token. * * @since 1.0.0 * @codeCoverageIgnore */ public function ajax_add_item() { if ( ! check_ajax_referer( self::AJAX_ACTION, 'nonce', false ) ) { status_header( 400 ); wp_send_json_error( 'bad_nonce' ); } elseif ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) { status_header( 405 ); wp_send_json_error( 'bad_method' ); } elseif ( empty( $_POST['token'] ) ) { wp_send_json_error( array( 'message' => __( 'The Token is missing.', 'envato-market' ) ) ); } elseif ( empty( $_POST['id'] ) ) { wp_send_json_error( array( 'message' => __( 'The Item ID is missing.', 'envato-market' ) ) ); } elseif ( ! current_user_can( 'install_themes' ) || ! current_user_can( 'install_plugins' ) ) { wp_send_json_error( array( 'message' => __( 'User not allowed to install items.', 'envato-market' ) ) ); } $args = array( 'headers' => array( 'Authorization' => 'Bearer ' . $_POST['token'], ), ); $request = envato_market()->api()->item( $_POST['id'], $args ); if ( false === $request ) { wp_send_json_error( array( 'message' => __( 'The Token or Item ID is incorrect.', 'envato-market' ) ) ); } if ( false === envato_market()->api()->download( $_POST['id'], $args ) ) { wp_send_json_error( array( 'message' => __( 'The item cannot be downloaded.', 'envato-market' ) ) ); } if ( isset( $request['number_of_sales'] ) ) { $type = 'plugin'; } else { $type = 'theme'; } if ( isset( $type ) ) { $response = array( 'name' => $request['name'], 'token' => $_POST['token'], 'id' => $_POST['id'], 'type' => $type, 'authorized' => 'success', ); $options = get_option( envato_market()->get_option_name(), array() ); if ( ! empty( $options['items'] ) ) { $options['items'] = array_values( $options['items'] ); $key = count( $options['items'] ); } else { $options['items'] = array(); $key = 0; } $options['items'][] = $response; envato_market()->set_options( $options ); // Rebuild the theme cache. if ( 'theme' === $type ) { envato_market()->items()->set_themes( true, false ); $install_link = add_query_arg( array( 'page' => envato_market()->get_slug(), 'action' => 'install-theme', 'id' => $_POST['id'], ), self_admin_url( 'admin.php' ) ); $request['install'] = wp_nonce_url( $install_link, 'install-theme_' . $_POST['id'] ); } // Rebuild the plugin cache. if ( 'plugin' === $type ) { envato_market()->items()->set_plugins( true, false ); $install_link = add_query_arg( array( 'page' => envato_market()->get_slug(), 'action' => 'install-plugin', 'id' => $_POST['id'], ), self_admin_url( 'admin.php' ) ); $request['install'] = wp_nonce_url( $install_link, 'install-plugin_' . $_POST['id'] ); } $response['key'] = $key; $response['item'] = $request; wp_send_json_success( $response ); } wp_send_json_error( array( 'message' => __( 'An unknown error occurred.', 'envato-market' ) ) ); } /** * AJAX handler for removing items that use a non global token. * * @since 1.0.0 * @codeCoverageIgnore */ public function ajax_remove_item() { if ( ! check_ajax_referer( self::AJAX_ACTION, 'nonce', false ) ) { status_header( 400 ); wp_send_json_error( 'bad_nonce' ); } elseif ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) { status_header( 405 ); wp_send_json_error( 'bad_method' ); } elseif ( empty( $_POST['id'] ) ) { wp_send_json_error( array( 'message' => __( 'The Item ID is missing.', 'envato-market' ) ) ); } elseif ( ! current_user_can( 'delete_plugins' ) || ! current_user_can( 'delete_themes' ) ) { wp_send_json_error( array( 'message' => __( 'User not allowed to update items.', 'envato-market' ) ) ); } $options = get_option( envato_market()->get_option_name(), array() ); $type = ''; foreach ( $options['items'] as $key => $item ) { if ( $item['id'] === $_POST['id'] ) { $type = $item['type']; unset( $options['items'][ $key ] ); break; } } $options['items'] = array_values( $options['items'] ); envato_market()->set_options( $options ); // Rebuild the theme cache. if ( 'theme' === $type ) { envato_market()->items()->set_themes( true, false ); } // Rebuild the plugin cache. if ( 'plugin' === $type ) { envato_market()->items()->set_plugins( true, false ); } wp_send_json_success(); } /** * AJAX handler for performing a healthcheck of the current website. * * @since 2.0.6 * @codeCoverageIgnore */ public function ajax_healthcheck() { if ( ! check_ajax_referer( self::AJAX_ACTION, 'nonce', false ) ) { status_header( 400 ); wp_send_json_error( 'bad_nonce' ); } elseif ( 'POST' !== $_SERVER['REQUEST_METHOD'] ) { status_header( 405 ); wp_send_json_error( 'bad_method' ); } elseif ( ! current_user_can( 'install_themes' ) || ! current_user_can( 'install_plugins' ) ) { wp_send_json_error( array( 'message' => __( 'User not allowed to install items.', 'envato-market' ) ) ); } $limits = $this->get_server_limits(); wp_send_json_success( array( 'limits' => $limits ) ); } /** * AJAX handler for performing a healthcheck of the current website. * * @since 2.0.6 * @codeCoverageIgnore */ public function get_server_limits() { $limits = []; // Check memory limit is > 256 M try { $memory_limit = wp_convert_hr_to_bytes( ini_get( 'memory_limit' ) ); $memory_limit_desired = 256; $memory_limit_ok = $memory_limit < 0 || $memory_limit >= $memory_limit_desired * 1024 * 1024; $memory_limit_in_mb = $memory_limit < 0 ? 'Unlimited' : floor( $memory_limit / ( 1024 * 1024 ) ) . 'M'; $limits['memory_limit'] = [ 'title' => 'PHP Memory Limit', 'ok' => $memory_limit_ok, 'message' => $memory_limit_ok ? "is ok at {$memory_limit_in_mb}." : "{$memory_limit_in_mb} may be too small. If you are having issues please set your PHP memory limit to at least 256M - or ask your hosting provider to do this if you're unsure." ]; } catch ( \Exception $e ) { $limits['memory_limit'] = [ 'title' => 'PHP Memory Limit', 'ok' => false, 'message' => 'Failed to check memory limit. If you are having issues please ask hosting provider to raise the memory limit for you.' ]; } // Check upload size. try { $upload_size_desired = 80; $upload_max_filesize = wp_max_upload_size(); $upload_max_filesize_ok = $upload_max_filesize < 0 || $upload_max_filesize >= $upload_size_desired * 1024 * 1024; $upload_max_filesize_in_mb = $upload_max_filesize < 0 ? 'Unlimited' : floor( $upload_max_filesize / ( 1024 * 1024 ) ) . 'M'; $limits['upload'] = [ 'ok' => $upload_max_filesize_ok, 'title' => 'PHP Upload Limits', 'message' => $upload_max_filesize_ok ? "is ok at $upload_max_filesize_in_mb." : "$upload_max_filesize_in_mb may be too small. If you are having issues please set your PHP upload limits to at least {$upload_size_desired}M - or ask your hosting provider to do this if you're unsure.", ]; } catch ( \Exception $e ) { $limits['upload'] = [ 'title' => 'PHP Upload Limits', 'ok' => false, 'message' => 'Failed to check upload limit. If you are having issues please ask hosting provider to raise the upload limit for you.' ]; } // Check max_input_vars. try { $max_input_vars = ini_get( 'max_input_vars' ); $max_input_vars_desired = 1000; $max_input_vars_ok = $max_input_vars < 0 || $max_input_vars >= $max_input_vars_desired; $limits['max_input_vars'] = [ 'ok' => $max_input_vars_ok, 'title' => 'PHP Max Input Vars', 'message' => $max_input_vars_ok ? "is ok at $max_input_vars." : "$max_input_vars may be too small. If you are having issues please set your PHP max input vars to at least $max_input_vars_desired - or ask your hosting provider to do this if you're unsure.", ]; } catch ( \Exception $e ) { $limits['max_input_vars'] = [ 'title' => 'PHP Max Input Vars', 'ok' => false, 'message' => 'Failed to check input vars limit. If you are having issues please ask hosting provider to raise the input vars limit for you.' ]; } // Check max_execution_time. try { $max_execution_time = ini_get( 'max_execution_time' ); $max_execution_time_desired = 60; $max_execution_time_ok = $max_execution_time <= 0 || $max_execution_time >= $max_execution_time_desired; $limits['max_execution_time'] = [ 'ok' => $max_execution_time_ok, 'title' => 'PHP Execution Time', 'message' => $max_execution_time_ok ? "PHP execution time limit is ok at {$max_execution_time}." : "$max_execution_time is too small. Please set your PHP max execution time to at least $max_execution_time_desired - or ask your hosting provider to do this if you're unsure.", ]; } catch ( \Exception $e ) { $limits['max_execution_time'] = [ 'title' => 'PHP Execution Time', 'ok' => false, 'message' => 'Failed to check PHP execution time limit. Please ask hosting provider to raise this limit for you.' ]; } // Check various hostname connectivity. $hosts_to_check = array( array( 'hostname' => 'envato.github.io', 'url' => 'https://envato.github.io/wp-envato-market/dist/update-check.json', 'title' => 'Plugin Update API', ), array( 'hostname' => 'api.envato.com', 'url' => 'https://api.envato.com/ping', 'title' => 'Envato Market API', ), array( 'hostname' => 'marketplace.envato.com', 'url' => 'https://marketplace.envato.com/robots.txt', 'title' => 'Download API', ), ); foreach ( $hosts_to_check as $host ) { try { $response = wp_remote_get( $host['url'], [ 'user-agent' => 'WordPress - Envato Market ' . envato_market()->get_version(), 'timeout' => 5, ] ); $response_code = wp_remote_retrieve_response_code( $response ); if ( $response && ! is_wp_error( $response ) && $response_code === 200 ) { $limits[ $host['hostname'] ] = [ 'ok' => true, 'title' => $host['title'], 'message' => 'Connected ok.', ]; } else { $limits[ $host['hostname'] ] = [ 'ok' => false, 'title' => $host['title'], 'message' => "Connection failed. Status '$response_code'. Please ensure PHP is allowed to connect to the host '" . $host['hostname'] . "' - or ask your hosting provider to do this if you’re unsure. " . ( is_wp_error( $response ) ? $response->get_error_message() : '' ), ]; } } catch ( \Exception $e ) { $limits[ $host['hostname'] ] = [ 'ok' => true, 'title' => $host['title'], 'message' => "Connection failed. Please contact the hosting provider and ensure PHP is allowed to connect to the host '" . $host['hostname'] . "'. " . $e->getMessage(), ]; } } // Check authenticated API request if ( !defined('ENVATO_LOCAL_DEVELOPMENT') ) { $response = envato_market()->api()->request( 'https://api.envato.com/whoami' ); if ( is_wp_error( $response ) ) { $limits['authentication'] = [ 'ok' => false, 'title' => 'Envato API Authentication', 'message' => "Not currently authenticated with the Envato API. Please add your API token. " . $response->get_error_message(), ]; } elseif ( ! isset( $response['scopes'] ) ) { $limits['authentication'] = [ 'ok' => false, 'title' => 'Envato API Authentication', 'message' => "Missing API permissions. Please re-create your Envato API token with the correct permissions. ", ]; } else { $minimum_scopes = $this->get_required_permissions(); $maximum_scopes = array( 'default' => 'Default' ) + $minimum_scopes; $missing_scopes = array(); $additional_scopes = array(); foreach ( $minimum_scopes as $required_scope => $required_scope_name ) { if ( ! in_array( $required_scope, $response['scopes'] ) ) { // The scope minimum required scope doesn't exist. $missing_scopes [] = $required_scope; } } foreach ( $response['scopes'] as $scope ) { if ( ! isset( $maximum_scopes[ $scope ] ) ) { // The available scope is outside our maximum bounds. $additional_scopes [] = $scope; } } $limits['authentication'] = [ 'ok' => true, 'title' => 'Envato API Authentication', 'message' => "Authenticated successfully with correct scopes: " . implode( ', ', $response['scopes'] ), ]; } } $debug_enabled = defined( 'WP_DEBUG' ) && WP_DEBUG; $limits['wp_debug'] = [ 'ok' => ! $debug_enabled, 'title' => 'WP Debug', 'message' => $debug_enabled ? 'If you’re on a production website, it’s best to set WP_DEBUG to false, please ask your hosting provider to do this if you’re unsure.' : 'WP Debug is disabled, all ok.', ]; $zip_archive_installed = class_exists( '\ZipArchive' ); $limits['zip_archive'] = [ 'ok' => $zip_archive_installed, 'title' => 'ZipArchive Support', 'message' => $zip_archive_installed ? 'ZipArchive is available.' : 'ZipArchive is not available. If you have issues installing or updating items please ask your hosting provider to enable ZipArchive.', ]; $php_version_ok = version_compare( PHP_VERSION, '7.0', '>=' ); $limits['php_version'] = [ 'ok' => $php_version_ok, 'title' => 'PHP Version', 'message' => $php_version_ok ? 'PHP version is ok at ' . PHP_VERSION . '.' : 'Please ask the hosting provider to upgrade your PHP version to at least 7.0 or above.', ]; require_once( ABSPATH . 'wp-admin/includes/file.php' ); $current_filesystem_method = get_filesystem_method(); if ( $current_filesystem_method !== 'direct' ) { $limits['filesystem_method'] = [ 'ok' => false, 'title' => 'WordPress Filesystem', 'message' => 'Please enable WordPress FS_METHOD direct - or ask your hosting provider to do this if you’re unsure.', ]; } $wp_upload_dir = wp_upload_dir(); $upload_base_dir = $wp_upload_dir['basedir']; $upload_base_dir_writable = is_writable( $upload_base_dir ); $limits['wp_content_writable'] = [ 'ok' => $upload_base_dir_writable, 'title' => 'WordPress File Permissions', 'message' => $upload_base_dir_writable ? 'is ok.' : 'Please set correct WordPress PHP write permissions for the wp-content directory - or ask your hosting provider to do this if you’re unsure.', ]; $active_plugins = get_option( 'active_plugins' ); $active_plugins_ok = count( $active_plugins ) < 15; if ( ! $active_plugins_ok ) { $limits['active_plugins'] = [ 'ok' => false, 'title' => 'Active Plugins', 'message' => 'Please try to reduce the number of active plugins on your WordPress site, as this will slow things down.', ]; } return $limits; } /** * Admin page callback. * * @since 1.0.0 */ public function render_admin_callback() { require( envato_market()->get_plugin_path() . 'inc/admin/view/callback/admin.php' ); } /** * OAuth section callback. * * @since 1.0.0 */ public function render_oauth_section_callback() { require( envato_market()->get_plugin_path() . 'inc/admin/view/callback/section/oauth.php' ); } /** * Items section callback. * * @since 1.0.0 */ public function render_items_section_callback() { require( envato_market()->get_plugin_path() . 'inc/admin/view/callback/section/items.php' ); } /** * Token setting callback. * * @since 1.0.0 */ public function render_token_setting_callback() { require( envato_market()->get_plugin_path() . 'inc/admin/view/callback/setting/token.php' ); } /** * Items setting callback. * * @since 1.0.0 */ public function render_items_setting_callback() { require( envato_market()->get_plugin_path() . 'inc/admin/view/callback/setting/items.php' ); } /** * Intro * * @since 1.0.0 */ public function render_intro_partial() { require( envato_market()->get_plugin_path() . 'inc/admin/view/partials/intro.php' ); } /** * Tabs * * @since 1.0.0 */ public function render_tabs_partial() { require( envato_market()->get_plugin_path() . 'inc/admin/view/partials/tabs.php' ); } /** * Settings panel * * @since 1.0.0 */ public function render_settings_panel_partial() { require( envato_market()->get_plugin_path() . 'inc/admin/view/partials/settings.php' ); } /** * Help panel * * @since 2.0.1 */ public function render_help_panel_partial() { require( envato_market()->get_plugin_path() . 'inc/admin/view/partials/help.php' ); } /** * Themes panel * * @since 1.0.0 */ public function render_themes_panel_partial() { require( envato_market()->get_plugin_path() . 'inc/admin/view/partials/themes.php' ); } /** * Plugins panel * * @since 1.0.0 */ public function render_plugins_panel_partial() { require( envato_market()->get_plugin_path() . 'inc/admin/view/partials/plugins.php' ); } /** * Success notice. * * @since 1.0.0 */ public function render_success_notice() { require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/success.php' ); } /** * Success no-items notice. * * @since 1.0.0 */ public function render_success_no_items_notice() { require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/success-no-items.php' ); } /** * Success single-use notice. * * @since 1.0.0 */ public function render_success_single_use_notice() { require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/success-single-use.php' ); } /** * Error details. * * @since 2.0.2 */ public function render_additional_error_details() { $error_details = get_site_transient( envato_market()->get_option_name() . '_error_information' ); if ( $error_details && ! empty( $error_details['title'] ) ) { extract( $error_details ); require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/error-details.php' ); } } /** * Error notice. * * @since 1.0.0 */ public function render_error_notice() { require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/error.php' ); $this->render_additional_error_details(); } /** * Permission error notice. * * @since 2.0.1 */ public function render_error_permissions() { require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/error-permissions.php' ); $this->render_additional_error_details(); } /** * Error single-use notice. * * @since 1.0.0 */ public function render_error_single_use_notice() { require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/error-single-use.php' ); $this->render_additional_error_details(); } /** * Error missing zip. * * @since 2.0.1 */ public function render_error_missing_zip() { require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/error-missing-zip.php' ); $this->render_additional_error_details(); } /** * Error http * * @since 2.0.1 */ public function render_error_http() { require( envato_market()->get_plugin_path() . 'inc/admin/view/notice/error-http.php' ); $this->render_additional_error_details(); } /** * Use the Settings API when in network mode. * * This allows us to make use of the same WordPress Settings API when displaying the menu item in network mode. * * @since 2.0.0 */ public function save_network_settings() { check_admin_referer( envato_market()->get_slug() . '-options' ); global $new_whitelist_options; $options = $new_whitelist_options[ envato_market()->get_slug() ]; foreach ( $options as $option ) { if ( isset( $_POST[ $option ] ) ) { update_site_option( $option, $_POST[ $option ] ); } else { delete_site_option( $option ); } } wp_redirect( envato_market()->get_page_url() ); exit; } /** * Store additional error information in transient so users can self debug. * * @since 2.0.2 */ public function store_additional_error_debug_information( $title, $message = '', $data = [] ) { set_site_transient( envato_market()->get_option_name() . '_error_information', [ 'title' => $title, 'message' => $message, 'data' => $data, ], 120 ); } } endif; inc/admin/functions.php000064400000040477147177457130011162 0ustar00items()->themes( $group ); if ( empty( $premium ) ) { return; } foreach ( $premium as $slug => $theme ) : $name = $theme['name']; $author = $theme['author']; $version = $theme['version']; $description = $theme['description']; $url = $theme['url']; $author_url = $theme['author_url']; $theme['hasUpdate'] = false; if ( 'active' === $group || 'installed' === $group ) { $get_theme = wp_get_theme( $slug ); if ( $get_theme->exists() ) { $name = $get_theme->get( 'Name' ); $author = $get_theme->get( 'Author' ); $version = $get_theme->get( 'Version' ); $description = $get_theme->get( 'Description' ); $author_url = $get_theme->get( 'AuthorURI' ); if ( version_compare( $version, $theme['version'], '<' ) ) { $theme['hasUpdate'] = true; } } } // Setup the column CSS classes. $classes = array( 'envato-card', 'theme' ); if ( 'active' === $group ) { $classes[] = 'active'; } // Setup the update action links. $update_actions = array(); if ( true === $theme['hasUpdate'] ) { $classes[] = 'update'; $classes[] = 'envato-card-' . esc_attr( $slug ); if ( current_user_can( 'update_themes' ) ) { // Upgrade link. $upgrade_link = add_query_arg( array( 'action' => 'upgrade-theme', 'theme' => esc_attr( $slug ), ), self_admin_url( 'update.php' ) ); $update_actions['update'] = sprintf( '%6$s', wp_nonce_url( $upgrade_link, 'upgrade-theme_' . $slug ), esc_attr__( 'Update %s now', 'envato-market' ), esc_attr( $name ), esc_attr( $slug ), esc_attr( $theme['version'] ), esc_html__( 'Update Available', 'envato-market' ) ); $update_actions['details'] = sprintf( '%3$s', esc_url( $url ), esc_attr( $name ), sprintf( __( 'View version %1$s details.', 'envato-market' ), $theme['version'] ) ); } } // Setup the action links. $actions = array(); if ( 'active' === $group && current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) { // Customize theme. $customize_url = admin_url( 'customize.php' ); $customize_url .= '?theme=' . urlencode( $slug ); $customize_url .= '&return=' . urlencode( envato_market()->get_page_url() . '#themes' ); $actions['customize'] = '' . sprintf( __( 'Customize “%s”', 'envato-market' ), $name ) . ''; } elseif ( 'installed' === $group ) { $can_activate = true; // @codeCoverageIgnoreStart // Multisite needs special attention. if ( is_multisite() && ! $get_theme->is_allowed( 'both' ) && current_user_can( 'manage_sites' ) ) { $can_activate = false; if ( current_user_can( 'manage_network_themes' ) ) { $actions['network_enable'] = '' . sprintf( __( 'Network Enable “%s”', 'envato-market' ), $name ) . ''; } } // @codeCoverageIgnoreEnd // Can activate theme. if ( $can_activate && current_user_can( 'switch_themes' ) ) { $activate_link = add_query_arg( array( 'action' => 'activate', 'stylesheet' => urlencode( $slug ), ), admin_url( 'themes.php' ) ); $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $slug ); // Activate link. $actions['activate'] = '' . sprintf( __( 'Activate “%s”', 'envato-market' ), $name ) . ''; // Preview theme. if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) { $preview_url = admin_url( 'customize.php' ); $preview_url .= '?theme=' . urlencode( $slug ); $preview_url .= '&return=' . urlencode( envato_market()->get_page_url() . '#themes' ); $actions['customize_preview'] = '' . sprintf( __( 'Live Preview “%s”', 'envato-market' ), $name ) . ''; } } } elseif ( 'install' === $group && current_user_can( 'install_themes' ) ) { // Install link. $install_link = add_query_arg( array( 'page' => envato_market()->get_slug(), 'action' => 'install-theme', 'id' => $theme['id'], ), self_admin_url( 'admin.php' ) ); $actions['install'] = ' ' . sprintf( __( 'Install %s', 'envato-market' ), $name ) . ' '; } if ( 0 === strrpos( html_entity_decode( $author ), '' . esc_html( $author ) . ''; } ?>
$count > 0 ? ( $rating / 5 * 100 ) : 0, 'type' => 'percent', 'number' => $count, ) ); } else { wp_star_rating( array( 'rating' => $theme['rating'] > 0 ? ( $theme['rating'] / 5 * 100 ) : 0, 'type' => 'percent', ) ); } } ?>
items()->plugins( $group ); if ( empty( $premium ) ) { return; } $plugins = envato_market()->items()->wp_plugins(); foreach ( $premium as $slug => $plugin ) : $name = $plugin['name']; $author = $plugin['author']; $version = $plugin['version']; $description = $plugin['description']; $url = $plugin['url']; $author_url = $plugin['author_url']; $plugin['hasUpdate'] = false; // Setup the column CSS classes. $classes = array( 'envato-card', 'plugin' ); if ( 'active' === $group ) { $classes[] = 'active'; } // Setup the update action links. $update_actions = array(); // Check for an update. if ( isset( $plugins[ $slug ] ) && version_compare( $plugins[ $slug ]['Version'], $plugin['version'], '<' ) ) { $plugin['hasUpdate'] = true; $classes[] = 'update'; $classes[] = 'envato-card-' . sanitize_key( dirname( $slug ) ); if ( current_user_can( 'update_plugins' ) ) { // Upgrade link. $upgrade_link = add_query_arg( array( 'action' => 'upgrade-plugin', 'plugin' => $slug, ), self_admin_url( 'update.php' ) ); // Details link. $details_link = add_query_arg( array( 'action' => 'upgrade-plugin', 'tab' => 'plugin-information', 'plugin' => dirname( $slug ), 'section' => 'changelog', 'TB_iframe' => 'true', 'width' => 640, 'height' => 662, ), self_admin_url( 'plugin-install.php' ) ); $update_actions['update'] = sprintf( '%7$s', wp_nonce_url( $upgrade_link, 'upgrade-plugin_' . $slug ), esc_attr__( 'Update %s now', 'envato-market' ), esc_attr( $name ), esc_attr( $slug ), sanitize_key( dirname( $slug ) ), esc_attr( $version ), esc_html__( 'Update Available', 'envato-market' ) ); $update_actions['details'] = sprintf( '%3$s', esc_url( $details_link ), esc_attr( $name ), sprintf( __( 'View version %1$s details.', 'envato-market' ), $version ) ); } } // Setup the action links. $actions = array(); if ( 'active' === $group ) { // Deactivate link. $deactivate_link = add_query_arg( array( 'action' => 'deactivate', 'plugin' => $slug, ), self_admin_url( 'plugins.php' ) ); $actions['deactivate'] = ' ' . sprintf( __( 'Deactivate %s', 'envato-market' ), $name ) . ' '; } elseif ( 'installed' === $group ) { if ( ! is_multisite() && current_user_can( 'delete_plugins' ) ) { // Delete link. $delete_link = add_query_arg( array( 'action' => 'delete-selected', 'checked[]' => $slug, ), self_admin_url( 'plugins.php' ) ); $actions['delete'] = ' ' . sprintf( __( 'Delete %s', 'envato-market' ), $name ) . ' '; } if ( ! is_multisite() && current_user_can( 'activate_plugins' ) ) { // Activate link. $activate_link = add_query_arg( array( 'action' => 'activate', 'plugin' => $slug, ), self_admin_url( 'plugins.php' ) ); $actions['activate'] = ' ' . sprintf( __( 'Activate %s', 'envato-market' ), $name ) . ' '; } // @codeCoverageIgnoreStart // Multisite needs special attention. if ( is_multisite() ) { if ( current_user_can( 'manage_network_plugins' ) ) { $actions['network_activate'] = ' ' . sprintf( __( 'Network Activate %s', 'envato-market' ), $name ) . ' '; } } // @codeCoverageIgnoreEnd } elseif ( 'install' === $group && current_user_can( 'install_plugins' ) ) { // Install link. $install_link = add_query_arg( array( 'page' => envato_market()->get_slug(), 'action' => 'install-plugin', 'id' => $plugin['id'], ), self_admin_url( 'admin.php' ) ); $actions['install'] = ' ' . sprintf( __( 'Install %s', 'envato-market' ), $name ) . ' '; } if ( 0 === strrpos( html_entity_decode( $author ), '' . esc_html( $author ) . ''; } ?>
$plugin['rating']['rating'] > 0 ? ( $plugin['rating']['rating'] / 5 * 100 ) : 0, 'type' => 'percent', 'number' => $plugin['rating']['count'], ) ); } else { wp_star_rating( array( 'rating' => $plugin['rating'] > 0 ? ( $plugin['rating'] / 5 * 100 ) : 0, 'type' => 'percent', ) ); } } ?>
strings['downloading_package'] = __( 'Downloading the Envato Market upgrade package…', 'envato-market' ); } /** * Initialize the install strings. * * @since 1.0.0 */ public function install_strings() { parent::install_strings(); $this->strings['downloading_package'] = __( 'Downloading the Envato Market install package…', 'envato-market' ); } } endif; if ( ! class_exists( 'Envato_Market_Plugin_Upgrader' ) ) : /** * Extends the WordPress Plugin_Upgrader class. * * This class makes modifications to the strings during install & upgrade. * * @class Envato_Market_Plugin_Upgrader * @version 1.0.0 * @since 1.0.0 */ class Envato_Market_Plugin_Upgrader extends Plugin_Upgrader { /** * Initialize the upgrade strings. * * @since 1.0.0 */ public function upgrade_strings() { parent::upgrade_strings(); $this->strings['downloading_package'] = __( 'Downloading the Envato Market upgrade package…', 'envato-market' ); } /** * Initialize the install strings. * * @since 1.0.0 */ public function install_strings() { parent::install_strings(); $this->strings['downloading_package'] = __( 'Downloading the Envato Market install package…', 'envato-market' ); } } endif; inc/admin/class-envato-market-theme-installer-skin.php000064400000011106147177457130017052 0ustar00upgrader->result['destination_name'] ) ) { return; } $theme_info = $this->upgrader->theme_info(); if ( empty( $theme_info ) ) { return; } $name = $theme_info->display( 'Name' ); $stylesheet = $this->upgrader->result['destination_name']; $template = $theme_info->get_template(); $activate_link = add_query_arg( array( 'action' => 'activate', 'template' => urlencode( $template ), 'stylesheet' => urlencode( $stylesheet ), ), admin_url( 'themes.php' ) ); $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet ); $install_actions = array(); if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) { $install_actions['preview'] = '' . sprintf( __( 'Live Preview “%s”', 'envato-market' ), $name ) . ''; } if ( is_multisite() ) { if ( current_user_can( 'manage_network_themes' ) ) { $install_actions['network_enable'] = '' . __( 'Network Enable', 'envato-market' ) . ''; } } $install_actions['activate'] = '' . sprintf( __( 'Activate “%s”', 'envato-market' ), $name ) . ''; $install_actions['themes_page'] = '' . __( 'Return to Theme Installer', 'envato-market' ) . ''; if ( ! $this->result || is_wp_error( $this->result ) || is_multisite() || ! current_user_can( 'switch_themes' ) ) { unset( $install_actions['activate'], $install_actions['preview'] ); } if ( ! empty( $install_actions ) ) { $this->feedback( implode( ' | ', $install_actions ) ); } } } endif; if ( ! class_exists( 'Envato_Market_Plugin_Installer_Skin' ) ) : /** * Plugin Installer Skin. * * @class Envato_Market_Plugin_Installer_Skin * @version 1.0.0 * @since 1.0.0 */ class Envato_Market_Plugin_Installer_Skin extends Plugin_Installer_Skin { /** * Modify the install actions. * * @since 1.0.0 */ public function after() { $plugin_file = $this->upgrader->plugin_info(); $install_actions = array(); if ( current_user_can( 'activate_plugins' ) ) { $install_actions['activate_plugin'] = '' . __( 'Activate Plugin', 'envato-market' ) . ''; } if ( is_multisite() ) { unset( $install_actions['activate_plugin'] ); if ( current_user_can( 'manage_network_plugins' ) ) { $install_actions['network_activate'] = '' . __( 'Network Activate', 'envato-market' ) . ''; } } $install_actions['plugins_page'] = '' . __( 'Return to Plugin Installer', 'envato-market' ) . ''; if ( ! $this->result || is_wp_error( $this->result ) ) { unset( $install_actions['activate_plugin'], $install_actions['site_activate'], $install_actions['network_activate'] ); } if ( ! empty( $install_actions ) ) { $this->feedback( implode( ' | ', $install_actions ) ); } } } endif; inc/class-envato-market.php000064400000024235147177457130011734 0ustar00init_globals(); self::$_instance->init_includes(); self::$_instance->init_actions(); } return self::$_instance; } /** * A dummy constructor to prevent this class from being loaded more than once. * * @see Envato_Market::instance() * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function __construct() { /* We do nothing here! */ } /** * You cannot clone this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __clone() { _doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * You cannot unserialize instances of this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __wakeup() { _doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * Setup the class globals. * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function init_globals() { $this->data = new stdClass(); $this->version = ENVATO_MARKET_VERSION; $this->slug = 'envato-market'; $this->option_name = self::sanitize_key( $this->slug ); $this->plugin_url = ENVATO_MARKET_URI; $this->plugin_path = ENVATO_MARKET_PATH; $this->page_url = ENVATO_MARKET_NETWORK_ACTIVATED ? network_admin_url( 'admin.php?page=' . $this->slug ) : admin_url( 'admin.php?page=' . $this->slug ); $this->data->admin = true; if ( defined('ENVATO_LOCAL_DEVELOPMENT') ) { $this->envato_api_domain = ENVATO_API_DOMAIN; $this->envato_api_headers = ENVATO_API_HEADERS; } else { $this->envato_api_headers = [ 'Authorization' => 'Bearer ' . $this->get_option( 'token' ) ]; $this->envato_api_domain = 'https://api.envato.com'; } } /** * Include required files. * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function init_includes() { require $this->plugin_path . '/inc/admin/class-envato-market-admin.php'; require $this->plugin_path . '/inc/admin/functions.php'; require $this->plugin_path . '/inc/class-envato-market-api.php'; require $this->plugin_path . '/inc/class-envato-market-items.php'; require $this->plugin_path . '/inc/class-envato-market-github.php'; } /** * Setup the hooks, actions and filters. * * @uses add_action() To add actions. * @uses add_filter() To add filters. * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function init_actions() { // Activate plugin. register_activation_hook( ENVATO_MARKET_CORE_FILE, array( $this, 'activate' ) ); // Deactivate plugin. register_deactivation_hook( ENVATO_MARKET_CORE_FILE, array( $this, 'deactivate' ) ); // Load the textdomain. add_action( 'init', array( $this, 'load_textdomain' ) ); // Load OAuth. add_action( 'init', array( $this, 'admin' ) ); // Load Upgrader. add_action( 'init', array( $this, 'items' ) ); } /** * Activate plugin. * * @since 1.0.0 * @codeCoverageIgnore */ public function activate() { self::set_plugin_state( true ); } /** * Deactivate plugin. * * @since 1.0.0 * @codeCoverageIgnore */ public function deactivate() { self::set_plugin_state( false ); } /** * Loads the plugin's translated strings. * * @since 1.0.0 * @codeCoverageIgnore */ public function load_textdomain() { load_plugin_textdomain( 'envato-market', false, ENVATO_MARKET_PATH . 'languages/' ); } /** * Sanitize data key. * * @since 1.0.0 * @access private * * @param string $key An alpha numeric string to sanitize. * @return string */ private function sanitize_key( $key ) { return preg_replace( '/[^A-Za-z0-9\_]/i', '', str_replace( array( '-', ':' ), '_', $key ) ); } /** * Recursively converts data arrays to objects. * * @since 1.0.0 * @access private * * @param array $array An array of data. * @return object */ private function convert_data( $array ) { foreach ( (array) $array as $key => $value ) { if ( is_array( $value ) ) { $array[ $key ] = self::convert_data( $value ); } } return (object) $array; } /** * Set the `is_plugin_active` option. * * This setting helps determine context. Since the plugin can be included in your theme root you * might want to hide the admin UI when the plugin is not activated and implement your own. * * @since 1.0.0 * @access private * * @param bool $value Whether or not the plugin is active. */ private function set_plugin_state( $value ) { self::set_option( 'is_plugin_active', $value ); } /** * Set option value. * * @since 1.0.0 * * @param string $name Option name. * @param mixed $option Option data. */ public function set_option( $name, $option ) { $options = self::get_options(); $name = self::sanitize_key( $name ); $options[ $name ] = esc_html( $option ); $this->set_options( $options ); } /** * Set option. * * @since 2.0.0 * * @param mixed $options Option data. */ public function set_options( $options ) { ENVATO_MARKET_NETWORK_ACTIVATED ? update_site_option( $this->option_name, $options ) : update_option( $this->option_name, $options ); } /** * Return the option settings array. * * @since 1.0.0 */ public function get_options() { return ENVATO_MARKET_NETWORK_ACTIVATED ? get_site_option( $this->option_name, array() ) : get_option( $this->option_name, array() ); } /** * Return a value from the option settings array. * * @since 1.0.0 * * @param string $name Option name. * @param mixed $default The default value if nothing is set. * @return mixed */ public function get_option( $name, $default = '' ) { $options = self::get_options(); $name = self::sanitize_key( $name ); return isset( $options[ $name ] ) ? $options[ $name ] : $default; } /** * Set data. * * @since 1.0.0 * * @param string $key Unique object key. * @param mixed $data Any kind of data. */ public function set_data( $key, $data ) { if ( ! empty( $key ) ) { if ( is_array( $data ) ) { $data = self::convert_data( $data ); } $key = self::sanitize_key( $key ); // @codingStandardsIgnoreStart $this->data->$key = $data; // @codingStandardsIgnoreEnd } } /** * Get data. * * @since 1.0.0 * * @param string $key Unique object key. * @return string|object */ public function get_data( $key ) { return isset( $this->data->$key ) ? $this->data->$key : ''; } /** * Return the plugin slug. * * @since 1.0.0 * * @return string */ public function get_slug() { return $this->slug; } /** * Return the plugin version number. * * @since 1.0.0 * * @return string */ public function get_version() { return $this->version; } /** * Return the plugin URL. * * @since 1.0.0 * * @return string */ public function get_plugin_url() { return $this->plugin_url; } /** * Return the plugin path. * * @since 1.0.0 * * @return string */ public function get_plugin_path() { return $this->plugin_path; } /** * Return the plugin page URL. * * @since 1.0.0 * * @return string */ public function get_page_url() { return $this->page_url; } /** * Return the option settings name. * * @since 1.0.0 * * @return string */ public function get_option_name() { return $this->option_name; } /** * Admin UI class. * * @since 1.0.0 * * @return Envato_Market_Admin */ public function admin() { return Envato_Market_Admin::instance(); } /** * Envato API class. * * @since 1.0.0 * * @return Envato_Market_API */ public function api() { return Envato_Market_API::instance(); } /** * Items class. * * @since 1.0.0 * * @return Envato_Market_Items */ public function items() { return Envato_Market_Items::instance(); } public function get_envato_api_domain() { return $this->envato_api_domain; } public function get_envato_api_headers() { return $this->envato_api_headers; } } endif; inc/class-envato-market-items.php000064400000041660147177457130013054 0ustar00init_actions(); } return self::$_instance; } /** * A dummy constructor to prevent this class from being loaded more than once. * * @see Envato_Market_Items::instance() * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function __construct() { /* We do nothing here! */ } /** * You cannot clone this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __clone() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * You cannot unserialize instances of this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __wakeup() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * Setup the hooks, actions and filters. * * @uses add_action() To add actions. * @uses add_filter() To add filters. * * @since 1.0.0 */ public function init_actions() { // Check for theme & plugin updates. add_filter( 'http_request_args', array( $this, 'update_check' ), 5, 2 ); // Inject plugin updates into the response array. add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'update_plugins' ), 5, 1 ); add_filter( 'pre_set_transient_update_plugins', array( $this, 'update_plugins' ), 5, 1 ); // Inject theme updates into the response array. add_filter( 'pre_set_site_transient_update_themes', array( $this, 'update_themes' ), 1, 99999 ); add_filter( 'pre_set_transient_update_themes', array( $this, 'update_themes' ), 1, 99999 ); // Inject plugin information into the API calls. add_filter( 'plugins_api', array( $this, 'plugins_api' ), 10, 3 ); // Rebuild the saved theme data. add_action( 'after_switch_theme', array( $this, 'rebuild_themes' ) ); // Rebuild the saved plugin data. add_action( 'activated_plugin', array( $this, 'rebuild_plugins' ) ); add_action( 'deactivated_plugin', array( $this, 'rebuild_plugins' ) ); } /** * Get the premium plugins list. * * @since 1.0.0 * * @param string $group The plugin group. Options are 'purchased', 'active', 'installed', or 'install'. * @return array */ public function plugins( $group = '' ) { if ( ! empty( $group ) ) { if ( isset( self::$plugins[ $group ] ) ) { return self::$plugins[ $group ]; } else { return array(); } } return self::$plugins; } /** * Get the premium themes list. * * @since 1.0.0 * * @param string $group The theme group. Options are 'purchased', 'active', 'installed', or 'install'. * @return array */ public function themes( $group = '' ) { if ( ! empty( $group ) ) { if ( isset( self::$themes[ $group ] ) ) { return self::$themes[ $group ]; } else { return array(); } } return self::$themes; } /** * Get the list of WordPress plugins * * @since 1.0.0 * * @param bool $flush Forces a cache flush. Default is 'false'. * @return array */ public function wp_plugins( $flush = false ) { if ( empty( self::$wp_plugins ) || true === $flush ) { wp_cache_set( 'plugins', false, 'plugins' ); self::$wp_plugins = get_plugins(); } return self::$wp_plugins; } /** * Disables requests to the wp.org repository for premium themes. * * @since 1.0.0 * * @param array $request An array of HTTP request arguments. * @param string $url The request URL. * @return array */ public function update_check( $request, $url ) { // Theme update request. if ( false !== strpos( $url, '//api.wordpress.org/themes/update-check/1.1/' ) ) { /** * Excluded theme slugs that should never ping the WordPress API. * We don't need the extra http requests for themes we know are premium. */ self::set_themes(); $installed = self::$themes['installed']; // Decode JSON so we can manipulate the array. $data = json_decode( $request['body']['themes'] ); // Remove the excluded themes. foreach ( $installed as $slug => $id ) { unset( $data->themes->$slug ); } // Encode back into JSON and update the response. $request['body']['themes'] = wp_json_encode( $data ); } // Plugin update request. if ( false !== strpos( $url, '//api.wordpress.org/plugins/update-check/1.1/' ) ) { /** * Excluded theme slugs that should never ping the WordPress API. * We don't need the extra http requests for themes we know are premium. */ self::set_plugins(); $installed = self::$plugins['installed']; // Decode JSON so we can manipulate the array. $data = json_decode( $request['body']['plugins'] ); // Remove the excluded themes. foreach ( $installed as $slug => $id ) { unset( $data->plugins->$slug ); } // Encode back into JSON and update the response. $request['body']['plugins'] = wp_json_encode( $data ); } return $request; } /** * Inject update data for premium themes. * * @since 1.0.0 * * @param object $transient The pre-saved value of the `update_themes` site transient. * @return object */ public function update_themes( $transient ) { // Process premium theme updates. if ( isset( $transient->checked ) ) { self::set_themes( true ); $installed = array_merge( self::$themes['active'], self::$themes['installed'] ); foreach ( $installed as $slug => $premium ) { $theme = wp_get_theme( $slug ); if ( $theme->exists() && version_compare( $theme->get( 'Version' ), $premium['version'], '<' ) ) { $transient->response[ $slug ] = array( 'theme' => $slug, 'new_version' => $premium['version'], 'url' => $premium['url'], 'package' => envato_market()->api()->deferred_download( $premium['id'] ), ); } } } return $transient; } /** * Inject update data for premium plugins. * * @since 1.0.0 * * @param object $transient The pre-saved value of the `update_plugins` site transient. * @return object */ public function update_plugins( $transient ) { self::set_plugins( true ); // Process premium plugin updates. $installed = array_merge( self::$plugins['active'], self::$plugins['installed'] ); $plugins = self::wp_plugins(); foreach ( $installed as $plugin => $premium ) { if ( isset( $plugins[ $plugin ] ) && version_compare( $plugins[ $plugin ]['Version'], $premium['version'], '<' ) ) { $_plugin = array( 'slug' => dirname( $plugin ), 'plugin' => $plugin, 'new_version' => $premium['version'], 'url' => $premium['url'], 'package' => envato_market()->api()->deferred_download( $premium['id'] ), ); $transient->response[ $plugin ] = (object) $_plugin; } } return $transient; } /** * Inject API data for premium plugins. * * @since 1.0.0 * * @param bool $response Always false. * @param string $action The API action being performed. * @param object $args Plugin arguments. * @return bool|object $response The plugin info or false. */ public function plugins_api( $response, $action, $args ) { self::set_plugins( true ); // Process premium theme updates. if ( 'plugin_information' === $action && isset( $args->slug ) ) { $installed = array_merge( self::$plugins['active'], self::$plugins['installed'] ); foreach ( $installed as $slug => $plugin ) { if ( dirname( $slug ) === $args->slug ) { $response = new stdClass(); $response->slug = $args->slug; $response->plugin = $slug; $response->plugin_name = $plugin['name']; $response->name = $plugin['name']; $response->version = $plugin['version']; $response->author = $plugin['author']; $response->homepage = $plugin['url']; $response->requires = $plugin['requires']; $response->tested = $plugin['tested']; $response->downloaded = $plugin['number_of_sales']; $response->last_updated = $plugin['updated_at']; $response->sections = array( 'description' => $plugin['description'] ); $response->banners['low'] = $plugin['landscape_url']; $response->rating = ! empty( $plugin['rating'] ) && ! empty( $plugin['rating']['rating'] ) && $plugin['rating']['rating'] > 0 ? $plugin['rating']['rating'] / 5 * 100 : 0; $response->num_ratings = ! empty( $plugin['rating'] ) && ! empty( $plugin['rating']['count'] ) ? $plugin['rating']['count'] : 0; $response->download_link = envato_market()->api()->deferred_download( $plugin['id'] ); break; } } } return $response; } /** * Set the list of themes * * @since 1.0.0 * * @param bool $forced Forces an API request. Default is 'false'. * @param bool $use_cache Attempts to rebuild from the cache before making an API request. */ public function set_themes( $forced = false, $use_cache = false ) { $themes_transient = get_site_transient( envato_market()->get_option_name() . '_themes' ); self::$themes = is_array($themes_transient) ? $themes_transient : array(); if ( empty(self::$themes) || true === $forced ) { $themes = envato_market()->api()->themes(); foreach ( envato_market()->get_option( 'items', array() ) as $item ) { if ( empty( $item ) ) { continue; } if ( 'theme' === $item['type'] ) { $request_args = array( 'headers' => array( 'Authorization' => 'Bearer ' . $item['token'], ), ); $request = envato_market()->api()->item( $item['id'], $request_args ); if ( false !== $request ) { $themes[] = $request; } } } self::process_themes( $themes ); } elseif ( true === $use_cache ) { self::process_themes( self::$themes['purchased'] ); } } /** * Set the list of plugins * * @since 1.0.0 * * @param bool $forced Forces an API request. Default is 'false'. * @param bool $use_cache Attempts to rebuild from the cache before making an API request. * @param array $args Used to remove or add a plugin during activate and deactivate routines. */ public function set_plugins( $forced = false, $use_cache = false, $args = array() ) { $plugins_transient = get_site_transient( envato_market()->get_option_name() . '_plugins' ); self::$plugins = is_array($plugins_transient) ? $plugins_transient : array(); if ( empty(self::$plugins) || true === $forced ) { $plugins = envato_market()->api()->plugins(); foreach ( envato_market()->get_option( 'items', array() ) as $item ) { if ( empty( $item ) ) { continue; } if ( 'plugin' === $item['type'] ) { $request_args = array( 'headers' => array( 'Authorization' => 'Bearer ' . $item['token'], ), ); $request = envato_market()->api()->item( $item['id'], $request_args ); if ( false !== $request ) { $plugins[] = $request; } } } self::process_plugins( $plugins, $args ); } elseif ( true === $use_cache ) { self::process_plugins( self::$plugins['purchased'], $args ); } } /** * Rebuild the themes array using the cache value if possible. * * @since 1.0.0 * * @param mixed $filter Any data being filtered. * @return mixed */ public function rebuild_themes( $filter ) { self::set_themes( false, true ); return $filter; } /** * Rebuild the plugins array using the cache value if possible. * * @since 1.0.0 * * @param string $plugin The plugin to add or remove. */ public function rebuild_plugins( $plugin ) { $remove = ( 'deactivated_plugin' === current_filter() ) ? true : false; self::set_plugins( false, true, array( 'plugin' => $plugin, 'remove' => $remove, ) ); } /** * Normalizes a string to do a value check against. * * Strip all HTML tags including script and style & then decode the * HTML entities so `&` will equal `&` in the value check and * finally lower case the entire string. This is required becuase some * themes & plugins add a link to the Author field or ambersands to the * names, or change the case of their files or names, which will not match * the saved value in the database causing a false negative. * * @since 1.0.0 * * @param string $string The string to normalize. * @return string */ public function normalize( $string ) { return strtolower( html_entity_decode( wp_strip_all_tags( $string ) ) ); } /** * Process the themes and save the transient. * * @since 1.0.0 * * @param array $purchased The purchased themes array. */ private function process_themes( $purchased ) { if ( is_wp_error( $purchased ) ) { $purchased = array(); } $current = wp_get_theme()->get_template(); $active = array(); $installed = array(); $install = $purchased; if ( ! empty( $purchased ) ) { foreach ( wp_get_themes() as $theme ) { /** * WP_Theme object. * * @var WP_Theme $theme */ $template = $theme->get_template(); $title = $theme->get( 'Name' ); $author = $theme->get( 'Author' ); foreach ( $install as $key => $value ) { if ( $this->normalize( $value['name'] ) === $this->normalize( $title ) && $this->normalize( $value['author'] ) === $this->normalize( $author ) ) { $installed[ $template ] = $value; unset( $install[ $key ] ); } } } } if ( isset( $installed[ $current ] ) ) { $active[ $current ] = $installed[ $current ]; unset( $installed[ $current ] ); } self::$themes['purchased'] = array_unique( $purchased, SORT_REGULAR ); self::$themes['active'] = array_unique( $active, SORT_REGULAR ); self::$themes['installed'] = array_unique( $installed, SORT_REGULAR ); self::$themes['install'] = array_unique( array_values( $install ), SORT_REGULAR ); set_site_transient( envato_market()->get_option_name() . '_themes', self::$themes, HOUR_IN_SECONDS ); } /** * Process the plugins and save the transient. * * @since 1.0.0 * * @param array $purchased The purchased plugins array. * @param array $args Used to remove or add a plugin during activate and deactivate routines. */ private function process_plugins( $purchased, $args = array() ) { if ( is_wp_error( $purchased ) ) { $purchased = array(); } $active = array(); $installed = array(); $install = $purchased; if ( ! empty( $purchased ) ) { foreach ( self::wp_plugins( true ) as $slug => $plugin ) { foreach ( $install as $key => $value ) { if ( $this->normalize( $value['name'] ) === $this->normalize( $plugin['Name'] ) && $this->normalize( $value['author'] ) === $this->normalize( $plugin['Author'] ) && file_exists( WP_PLUGIN_DIR . '/' . $slug ) ) { $installed[ $slug ] = $value; unset( $install[ $key ] ); } } } } foreach ( $installed as $slug => $plugin ) { $condition = false; if ( ! empty( $args ) && $slug === $args['plugin'] ) { if ( true === $args['remove'] ) { continue; } $condition = true; } if ( $condition || is_plugin_active( $slug ) ) { $active[ $slug ] = $plugin; unset( $installed[ $slug ] ); } } self::$plugins['purchased'] = array_unique( $purchased, SORT_REGULAR ); self::$plugins['active'] = array_unique( $active, SORT_REGULAR ); self::$plugins['installed'] = array_unique( $installed, SORT_REGULAR ); self::$plugins['install'] = array_unique( array_values( $install ), SORT_REGULAR ); set_site_transient( envato_market()->get_option_name() . '_plugins', self::$plugins, HOUR_IN_SECONDS ); } } endif; inc/class-envato-market-github.php000064400000023435147177457130013215 0ustar00init_actions(); } return self::$_instance; } /** * A dummy constructor to prevent this class from being loaded more than once. * * @see Envato_Market_Github::instance() * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function __construct() { /* We do nothing here! */ } /** * You cannot clone this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __clone() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * You cannot unserialize instances of this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __wakeup() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * Setup the actions and filters. * * @uses add_action() To add actions. * @uses add_filter() To add filters. * * @since 1.0.0 */ public function init_actions() { // Bail outside of the WP Admin panel. if ( ! is_admin() ) { return; } add_filter( 'http_request_args', array( $this, 'update_check' ), 5, 2 ); add_filter( 'plugins_api', array( $this, 'plugins_api' ), 10, 3 ); add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'update_plugins' ) ); add_filter( 'pre_set_transient_update_plugins', array( $this, 'update_plugins' ) ); add_filter( 'site_transient_update_plugins', array( $this, 'update_state' ) ); add_filter( 'transient_update_plugins', array( $this, 'update_state' ) ); add_action( 'admin_notices', array( $this, 'notice' ) ); add_action( 'wp_ajax_' . self::AJAX_ACTION, array( $this, 'dismiss_notice' ) ); } /** * Check Github for an update. * * @since 1.0.0 * * @return false|object */ public function api_check() { $raw_response = wp_remote_get( self::$api_url ); if ( is_wp_error( $raw_response ) ) { return false; } if ( ! empty( $raw_response['body'] ) ) { $raw_body = json_decode( $raw_response['body'], true ); if ( $raw_body ) { return (object) $raw_body; } } return false; } /** * Disables requests to the wp.org repository for Envato Market. * * @since 1.0.0 * * @param array $request An array of HTTP request arguments. * @param string $url The request URL. * @return array */ public function update_check( $request, $url ) { // Plugin update request. if ( false !== strpos( $url, '//api.wordpress.org/plugins/update-check/1.1/' ) ) { // Decode JSON so we can manipulate the array. $data = json_decode( $request['body']['plugins'] ); // Remove the Envato Market. unset( $data->plugins->{'envato-market/envato-market.php'} ); // Encode back into JSON and update the response. $request['body']['plugins'] = wp_json_encode( $data ); } return $request; } /** * API check. * * @since 1.0.0 * * @param bool $api Always false. * @param string $action The API action being performed. * @param object $args Plugin arguments. * @return mixed $api The plugin info or false. */ public function plugins_api( $api, $action, $args ) { if ( isset( $args->slug ) && 'envato-market' === $args->slug ) { $api_check = $this->api_check(); if ( is_object( $api_check ) ) { $api = $api_check; } } return $api; } /** * Update check. * * @since 1.0.0 * * @param object $transient The pre-saved value of the `update_plugins` site transient. * @return object */ public function update_plugins( $transient ) { $state = $this->state(); if ( 'activated' === $state ) { $api_check = $this->api_check(); if ( is_object( $api_check ) && version_compare( envato_market()->get_version(), $api_check->version, '<' ) ) { $transient->response['envato-market/envato-market.php'] = (object) array( 'slug' => 'envato-market', 'plugin' => 'envato-market/envato-market.php', 'new_version' => $api_check->version, 'url' => 'https://github.com/envato/wp-envato-market', 'package' => $api_check->download_link, ); } } return $transient; } /** * Set the plugin state. * * @since 1.0.0 * * @return string */ public function state() { $option = 'envato_market_state'; $active_plugins = apply_filters( 'active_plugins', get_option( 'active_plugins' ) ); // We also have to check network activated plugins. Otherwise this plugin won't update on multisite. $active_sitewide_plugins = get_site_option( 'active_sitewide_plugins' ); if ( ! is_array( $active_plugins ) ) { $active_plugins = array(); } if ( ! is_array( $active_sitewide_plugins ) ) { $active_sitewide_plugins = array(); } $active_plugins = array_merge( $active_plugins, array_keys( $active_sitewide_plugins ) ); if ( in_array( 'envato-market/envato-market.php', $active_plugins ) ) { $state = 'activated'; update_option( $option, $state ); } else { $state = 'install'; update_option( $option, $state ); foreach ( array_keys( get_plugins() ) as $plugin ) { if ( strpos( $plugin, 'envato-market.php' ) !== false ) { $state = 'deactivated'; update_option( $option, $state ); } } } return $state; } /** * Force the plugin state to be updated. * * @since 1.0.0 * * @param object $transient The saved value of the `update_plugins` site transient. * @return object */ public function update_state( $transient ) { $state = $this->state(); return $transient; } /** * Admin notices. * * @since 1.0.0 * * @return string */ public function notice() { $screen = get_current_screen(); $slug = 'envato-market'; $state = get_option( 'envato_market_state' ); $notice = get_option( self::AJAX_ACTION ); if ( empty( $state ) ) { $state = $this->state(); } if ( 'activated' === $state || 'update-core' === $screen->id || 'update' === $screen->id || 'plugins' === $screen->id && isset( $_GET['action'] ) && 'delete-selected' === $_GET['action'] || 'dismissed' === $notice ) { return; } if ( 'deactivated' === $state ) { $activate_url = add_query_arg( array( 'action' => 'activate', 'plugin' => urlencode( "$slug/$slug.php" ), '_wpnonce' => urlencode( wp_create_nonce( "activate-plugin_$slug/$slug.php" ) ), ), self_admin_url( 'plugins.php' ) ); $message = sprintf( esc_html__( '%1$sActivate the Envato Market plugin%2$s to get updates for your ThemeForest and CodeCanyon items.', 'envato-market' ), '', '' ); } elseif ( 'install' === $state ) { $install_url = add_query_arg( array( 'action' => 'install-plugin', 'plugin' => $slug, ), self_admin_url( 'update.php' ) ); $message = sprintf( esc_html__( '%1$sInstall the Envato Market plugin%2$s to get updates for your ThemeForest and CodeCanyon items.', 'envato-market' ), '', '' ); } if ( isset( $message ) ) { ?>

__( 'User not allowed to update items.', 'envato-market' ) ) ); } update_option( self::AJAX_ACTION, 'dismissed' ); wp_send_json_success(); } } if ( ! function_exists( 'envato_market_github' ) ) : /** * Envato_Market_Github Instance * * @since 1.0.0 * * @return Envato_Market_Github */ function envato_market_github() { return Envato_Market_Github::instance(); } endif; /** * Loads the main instance of Envato_Market_Github * * @since 1.0.0 */ add_action( 'after_setup_theme', 'envato_market_github', 99 ); endif; inc/class-envato-market-api.php000064400000034405147177457130012503 0ustar00init_globals(); } return self::$_instance; } /** * A dummy constructor to prevent this class from being loaded more than once. * * @see Envato_Market_API::instance() * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function __construct() { /* We do nothing here! */ } /** * You cannot clone this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __clone() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * You cannot unserialize instances of this class. * * @since 1.0.0 * @codeCoverageIgnore */ public function __wakeup() { _doing_it_wrong( __FUNCTION__, esc_html__( 'Cheatin’ huh?', 'envato-market' ), '1.0.0' ); } /** * Setup the class globals. * * @since 1.0.0 * @access private * @codeCoverageIgnore */ private function init_globals() { // Envato API token. $this->token = envato_market()->get_option( 'token' ); } /** * Query the Envato API. * * @uses wp_remote_get() To perform an HTTP request. * * @since 1.0.0 * * @param string $url API request URL, including the request method, parameters, & file type. * @param array $args The arguments passed to `wp_remote_get`. * @return array|WP_Error The HTTP response. */ public function request( $url, $args = array() ) { $defaults = array( 'sslverify' => !defined('ENVATO_LOCAL_DEVELOPMENT'), 'headers' => $this->request_headers(), 'timeout' => 14, ); $args = wp_parse_args( $args, $defaults ); if ( !defined('ENVATO_LOCAL_DEVELOPMENT') ) { $token = trim( str_replace( 'Bearer', '', $args['headers']['Authorization'] ) ); if ( empty( $token ) ) { return new WP_Error( 'api_token_error', __( 'An API token is required.', 'envato-market' ) ); } } $debugging_information = [ 'request_url' => $url, ]; // Make an API request. $response = wp_remote_get( esc_url_raw( $url ), $args ); // Check the response code. $response_code = wp_remote_retrieve_response_code( $response ); $response_message = wp_remote_retrieve_response_message( $response ); $debugging_information['response_code'] = $response_code; $debugging_information['response_cf_ray'] = wp_remote_retrieve_header( $response, 'cf-ray' ); $debugging_information['response_server'] = wp_remote_retrieve_header( $response, 'server' ); if ( ! empty( $response->errors ) && isset( $response->errors['http_request_failed'] ) ) { // API connectivity issue, inject notice into transient with more details. $option = envato_market()->get_options(); if ( empty( $option['notices'] ) ) { $option['notices'] = []; } $option['notices']['http_error'] = current( $response->errors['http_request_failed'] ); envato_market()->set_options( $option ); return new WP_Error( 'http_error', esc_html( current( $response->errors['http_request_failed'] ) ), $debugging_information ); } if ( 200 !== $response_code && ! empty( $response_message ) ) { return new WP_Error( $response_code, $response_message, $debugging_information ); } elseif ( 200 !== $response_code ) { return new WP_Error( $response_code, __( 'An unknown API error occurred.', 'envato-market' ), $debugging_information ); } else { $return = json_decode( wp_remote_retrieve_body( $response ), true ); if ( null === $return ) { return new WP_Error( 'api_error', __( 'An unknown API error occurred.', 'envato-market' ), $debugging_information ); } return $return; } } /** * Deferred item download URL. * * @since 1.0.0 * * @param int $id The item ID. * @return string. */ public function deferred_download( $id ) { if ( empty( $id ) ) { return ''; } $args = array( 'deferred_download' => true, 'item_id' => $id, ); return add_query_arg( $args, esc_url( envato_market()->get_page_url() ) ); } /** * Get the item download. * * @since 1.0.0 * * @param int $id The item ID. * @param array $args The arguments passed to `wp_remote_get`. * @return bool|array The HTTP response. */ public function download( $id, $args = array() ) { if ( empty( $id ) ) { return false; } $domain = envato_market()->get_envato_api_domain(); $path = $this->api_path_for('download'); $url = $domain . $path . '?item_id=' . $id . '&shorten_url=true'; $response = $this->request( $url, $args ); // @todo Find out which errors could be returned & handle them in the UI. if ( is_wp_error( $response ) || empty( $response ) || ! empty( $response['error'] ) ) { return false; } if ( ! empty( $response['wordpress_theme'] ) ) { return $response['wordpress_theme']; } if ( ! empty( $response['wordpress_plugin'] ) ) { return $response['wordpress_plugin']; } // Missing a WordPress theme and plugin, report an error. $option = envato_market()->get_options(); if ( ! isset( $option['notices'] ) ) { $option['notices'] = []; } $option['notices']['missing-package-zip'] = true; envato_market()->set_options( $option ); return false; } /** * Get an item by ID and type. * * @since 1.0.0 * * @param int $id The item ID. * @param array $args The arguments passed to `wp_remote_get`. * @return array The HTTP response. */ public function item( $id, $args = array() ) { $domain = envato_market()->get_envato_api_domain(); $path = $this->api_path_for('catalog-item'); $url = $domain . $path . '?id=' . $id; $response = $this->request( $url, $args ); if ( is_wp_error( $response ) || empty( $response ) ) { return false; } if ( ! empty( $response['wordpress_theme_metadata'] ) ) { return $this->normalize_theme( $response ); } if ( ! empty( $response['wordpress_plugin_metadata'] ) ) { return $this->normalize_plugin( $response ); } return false; } /** * Get the list of available themes. * * @since 1.0.0 * * @param array $args The arguments passed to `wp_remote_get`. * @return array The HTTP response. */ public function themes( $args = array() ) { $themes = array(); $domain = envato_market()->get_envato_api_domain(); $path = $this->api_path_for('list-purchases'); $url = $domain . $path . '?filter_by=wordpress-themes'; $response = $this->request( $url, $args ); if ( is_wp_error( $response ) || empty( $response ) || empty( $response['results'] ) ) { return $themes; } foreach ( $response['results'] as $theme ) { $themes[] = $this->normalize_theme( $theme['item'] ); } return $themes; } /** * Normalize a theme. * * @since 1.0.0 * * @param array $theme An array of API request values. * @return array A normalized array of values. */ public function normalize_theme( $theme ) { $normalized_theme = array( 'id' => $theme['id'], 'name' => ( ! empty( $theme['wordpress_theme_metadata']['theme_name'] ) ? $theme['wordpress_theme_metadata']['theme_name'] : '' ), 'author' => ( ! empty( $theme['wordpress_theme_metadata']['author_name'] ) ? $theme['wordpress_theme_metadata']['author_name'] : '' ), 'version' => ( ! empty( $theme['wordpress_theme_metadata']['version'] ) ? $theme['wordpress_theme_metadata']['version'] : '' ), 'description' => self::remove_non_unicode( strip_tags( $theme['wordpress_theme_metadata']['description'] ) ), 'url' => ( ! empty( $theme['url'] ) ? $theme['url'] : '' ), 'author_url' => ( ! empty( $theme['author_url'] ) ? $theme['author_url'] : '' ), 'thumbnail_url' => ( ! empty( $theme['thumbnail_url'] ) ? $theme['thumbnail_url'] : '' ), 'rating' => ( ! empty( $theme['rating'] ) ? $theme['rating'] : '' ), 'landscape_url' => '', ); // No main thumbnail in API response, so we grab it from the preview array. if ( empty( $normalized_theme['thumbnail_url'] ) && ! empty( $theme['previews'] ) && is_array( $theme['previews'] ) ) { foreach ( $theme['previews'] as $possible_preview ) { if ( ! empty( $possible_preview['landscape_url'] ) ) { $normalized_theme['landscape_url'] = $possible_preview['landscape_url']; break; } } } if ( empty( $normalized_theme['thumbnail_url'] ) && ! empty( $theme['previews'] ) && is_array( $theme['previews'] ) ) { foreach ( $theme['previews'] as $possible_preview ) { if ( ! empty( $possible_preview['icon_url'] ) ) { $normalized_theme['thumbnail_url'] = $possible_preview['icon_url']; break; } } } return $normalized_theme; } /** * Get the list of available plugins. * * @since 1.0.0 * * @param array $args The arguments passed to `wp_remote_get`. * @return array The HTTP response. */ public function plugins( $args = array() ) { $plugins = array(); $domain = envato_market()->get_envato_api_domain(); $path = $this->api_path_for('list-purchases'); $url = $domain . $path . '?filter_by=wordpress-plugins'; $response = $this->request( $url, $args ); if ( is_wp_error( $response ) || empty( $response ) || empty( $response['results'] ) ) { return $plugins; } foreach ( $response['results'] as $plugin ) { $plugins[] = $this->normalize_plugin( $plugin['item'] ); } return $plugins; } /** * Normalize a plugin. * * @since 1.0.0 * * @param array $plugin An array of API request values. * @return array A normalized array of values. */ public function normalize_plugin( $plugin ) { $requires = null; $tested = null; $versions = array(); // Set the required and tested WordPress version numbers. foreach ( $plugin['attributes'] as $k => $v ) { if ( ! empty( $v['name'] ) && 'compatible-software' === $v['name'] && ! empty( $v['value'] ) && is_array( $v['value'] ) ) { foreach ( $v['value'] as $version ) { $versions[] = str_replace( 'WordPress ', '', trim( $version ) ); } if ( ! empty( $versions ) ) { $requires = $versions[ count( $versions ) - 1 ]; $tested = $versions[0]; } break; } } $plugin_normalized = array( 'id' => $plugin['id'], 'name' => ( ! empty( $plugin['wordpress_plugin_metadata']['plugin_name'] ) ? $plugin['wordpress_plugin_metadata']['plugin_name'] : '' ), 'author' => ( ! empty( $plugin['wordpress_plugin_metadata']['author'] ) ? $plugin['wordpress_plugin_metadata']['author'] : '' ), 'version' => ( ! empty( $plugin['wordpress_plugin_metadata']['version'] ) ? $plugin['wordpress_plugin_metadata']['version'] : '' ), 'description' => self::remove_non_unicode( strip_tags( $plugin['wordpress_plugin_metadata']['description'] ) ), 'url' => ( ! empty( $plugin['url'] ) ? $plugin['url'] : '' ), 'author_url' => ( ! empty( $plugin['author_url'] ) ? $plugin['author_url'] : '' ), 'thumbnail_url' => ( ! empty( $plugin['thumbnail_url'] ) ? $plugin['thumbnail_url'] : '' ), 'landscape_url' => ( ! empty( $plugin['previews']['landscape_preview']['landscape_url'] ) ? $plugin['previews']['landscape_preview']['landscape_url'] : '' ), 'requires' => $requires, 'tested' => $tested, 'number_of_sales' => ( ! empty( $plugin['number_of_sales'] ) ? $plugin['number_of_sales'] : '' ), 'updated_at' => ( ! empty( $plugin['updated_at'] ) ? $plugin['updated_at'] : '' ), 'rating' => ( ! empty( $plugin['rating'] ) ? $plugin['rating'] : '' ), ); // No main thumbnail in API response, so we grab it from the preview array. if ( empty( $plugin_normalized['landscape_url'] ) && ! empty( $plugin['previews'] ) && is_array( $plugin['previews'] ) ) { foreach ( $plugin['previews'] as $possible_preview ) { if ( ! empty( $possible_preview['landscape_url'] ) ) { $plugin_normalized['landscape_url'] = $possible_preview['landscape_url']; break; } } } if ( empty( $plugin_normalized['thumbnail_url'] ) && ! empty( $plugin['previews'] ) && is_array( $plugin['previews'] ) ) { foreach ( $plugin['previews'] as $possible_preview ) { if ( ! empty( $possible_preview['icon_url'] ) ) { $plugin_normalized['thumbnail_url'] = $possible_preview['icon_url']; break; } } } return $plugin_normalized; } public function api_path_for( $path ) { if ( defined('ENVATO_LOCAL_DEVELOPMENT') ) { $paths = MONOLITH_API_PATHS; } else { $paths = array( 'download' => '/v2/market/buyer/download', 'catalog-item' => '/v2/market/catalog/item', 'list-purchases' => '/v2/market/buyer/list-purchases', 'total-items' => '/v1/market/total-items.json' ); } return $paths[$path]; } /** * Remove all non unicode characters in a string * * @since 1.0.0 * * @param string $retval The string to fix. * @return string */ static private function remove_non_unicode( $retval ) { return preg_replace( '/[\x00-\x1F\x80-\xFF]/', '', $retval ); } private function request_headers() { $user_agent = array('User-Agent' => 'WordPress - Envato Market ' . envato_market()->get_version()); $headers = array_merge($user_agent, envato_market()->get_envato_api_headers()); return $headers; } } endif; js/updates.js000064400000037036147177457130007214 0ustar00/* global tb_remove, JSON */ window.wp = window.wp || {}; (function ($, wp) { 'use strict' wp.envato = {} /** * User nonce for ajax calls. * * @since 1.0.0 * * @var string */ wp.envato.ajaxNonce = window._wpUpdatesSettings.ajax_nonce /** * Whether filesystem credentials need to be requested from the user. * * @since 1.0.0 * * @var bool */ wp.envato.shouldRequestFilesystemCredentials = null /** * Filesystem credentials to be packaged along with the request. * * @since 1.0.0 * * @var object */ wp.envato.filesystemCredentials = { ftp: { host: null, username: null, password: null, connectionType: null }, ssh: { publicKey: null, privateKey: null } } /** * Flag if we're waiting for an update to complete. * * @since 1.0.0 * * @var bool */ wp.envato.updateLock = false /** * * Flag if we've done an update successfully. * * @since 1.0.0 * * @var bool */ wp.envato.updateDoneSuccessfully = false /** * If the user tries to update a plugin while an update is * already happening, it can be placed in this queue to perform later. * * @since 1.0.0 * * @var array */ wp.envato.updateQueue = [] /** * Store a jQuery reference to return focus to when exiting the request credentials modal. * * @since 1.0.0 * * @var jQuery object */ wp.envato.$elToReturnFocusToFromCredentialsModal = null /** * Decrement update counts throughout the various menus. * * @since 3.9.0 * * @param {string} upgradeType */ wp.envato.decrementCount = function (upgradeType) { var count var pluginCount const $adminBarUpdateCount = $('#wp-admin-bar-updates .ab-label') const $dashboardNavMenuUpdateCount = $('a[href="update-core.php"] .update-plugins') const $pluginsMenuItem = $('#menu-plugins') count = $adminBarUpdateCount.text() count = parseInt(count, 10) - 1 if (count < 0 || isNaN(count)) { return } $('#wp-admin-bar-updates .ab-item').removeAttr('title') $adminBarUpdateCount.text(count) $dashboardNavMenuUpdateCount.each(function (index, elem) { elem.className = elem.className.replace(/count-\d+/, 'count-' + count) }) $dashboardNavMenuUpdateCount.removeAttr('title') $dashboardNavMenuUpdateCount.find('.update-count').text(count) if (upgradeType === 'plugin') { pluginCount = $pluginsMenuItem.find('.plugin-count').eq(0).text() pluginCount = parseInt(pluginCount, 10) - 1 if (pluginCount < 0 || isNaN(pluginCount)) { return } $pluginsMenuItem.find('.plugin-count').text(pluginCount) $pluginsMenuItem.find('.update-plugins').each(function (index, elem) { elem.className = elem.className.replace(/count-\d+/, 'count-' + pluginCount) }) if (pluginCount > 0) { $('.subsubsub .upgrade .count').text('(' + pluginCount + ')') } else { $('.subsubsub .upgrade').remove() } } } /** * Send an Ajax request to the server to update a plugin. * * @since 1.0.0 * * @param {string} plugin * @param {string} slug */ wp.envato.updatePlugin = function (plugin, slug) { let data const $message = $('.envato-card-' + slug).find('.update-now') const name = $message.data('name') const updatingMessage = wp.i18n.sprintf(wp.i18n.__('Updating %s...', 'envato-market'), name) $message.attr('aria-label', updatingMessage) $message.addClass('updating-message') if ($message.html() !== updatingMessage) { $message.data('originaltext', $message.html()) } $message.text(updatingMessage) if (wp.envato.updateLock) { wp.envato.updateQueue.push({ type: 'update-plugin', data: { plugin, slug } }) return } wp.envato.updateLock = true data = { _ajax_nonce: wp.envato.ajaxNonce, plugin, slug, username: wp.envato.filesystemCredentials.ftp.username, password: wp.envato.filesystemCredentials.ftp.password, hostname: wp.envato.filesystemCredentials.ftp.hostname, connection_type: wp.envato.filesystemCredentials.ftp.connectionType, public_key: wp.envato.filesystemCredentials.ssh.publicKey, private_key: wp.envato.filesystemCredentials.ssh.privateKey } wp.ajax.post('update-plugin', data) .done(wp.envato.updateSuccess) .fail(wp.envato.updateError) } /** * Send an Ajax request to the server to update a theme. * * @since 1.0.0 * * @param {string} plugin * @param {string} slug */ wp.envato.updateTheme = function (slug) { let data const $message = $('.envato-card-' + slug).find('.update-now') const name = $message.data('name') const updatingMessage = wp.i18n.sprintf(wp.i18n.__('Updating %s...', 'envato-market'), name) $message.attr('aria-label', updatingMessage) $message.addClass('updating-message') if ($message.html() !== updatingMessage) { $message.data('originaltext', $message.html()) } $message.text(updatingMessage) if (wp.envato.updateLock) { wp.envato.updateQueue.push({ type: 'update-theme', data: { theme: slug } }) return } wp.envato.updateLock = true data = { _ajax_nonce: wp.envato.ajaxNonce, theme: slug, slug, username: wp.envato.filesystemCredentials.ftp.username, password: wp.envato.filesystemCredentials.ftp.password, hostname: wp.envato.filesystemCredentials.ftp.hostname, connection_type: wp.envato.filesystemCredentials.ftp.connectionType, public_key: wp.envato.filesystemCredentials.ssh.publicKey, private_key: wp.envato.filesystemCredentials.ssh.privateKey } wp.ajax.post('update-theme', data) .done(wp.envato.updateSuccess) .fail(wp.envato.updateError) } /** * On a successful plugin update, update the UI with the result. * * @since 1.0.0 * * @param {object} response */ wp.envato.updateSuccess = function (response) { let $card, $updateColumn, $updateMessage, $updateVersion, name, version, versionText $card = $('.envato-card-' + response.slug) $updateColumn = $card.find('.column-update') $updateMessage = $card.find('.update-now') $updateVersion = $card.find('.version') name = $updateMessage.data('name') version = $updateMessage.data('version') versionText = $updateVersion.attr('aria-label').replace('%s', version) $updateMessage.addClass('disabled') const updateMessage = wp.i18n.sprintf(wp.i18n.__('Updating %s...', 'envato-market'), name) $updateMessage.attr('aria-label', updateMessage) $updateVersion.text(versionText) $updateMessage.removeClass('updating-message').addClass('updated-message') $updateMessage.text(wp.i18n.__('Updated!', 'envato-market')) wp.a11y.speak(updateMessage) $updateColumn.addClass('update-complete').delay(1000).fadeOut() wp.envato.decrementCount('plugin') wp.envato.updateDoneSuccessfully = true /* * The lock can be released since the update was successful, * and any other updates can commence. */ wp.envato.updateLock = false $(document).trigger('envato-update-success', response) wp.envato.queueChecker() } /** * On a plugin update error, update the UI appropriately. * * @since 1.0.0 * * @param {object} response */ wp.envato.updateError = function (response) { let $message, name wp.envato.updateDoneSuccessfully = false if (response.errorCode && response.errorCode === 'unable_to_connect_to_filesystem' && wp.envato.shouldRequestFilesystemCredentials) { wp.envato.credentialError(response, 'update-plugin') return } $message = $('.envato-card-' + response.slug).find('.update-now') name = $message.data('name') $message.attr('aria-label', wp.i18n.__('Updating failed', 'envato-market')) $message.removeClass('updating-message') $message.html(wp.i18n.sprintf(wp.i18n.__('Updating failed %s...', 'envato-market'), typeof 'undefined' !== response.errorMessage ? response.errorMessage : response.error)) /* * The lock can be released since this failure was * after the credentials form. */ wp.envato.updateLock = false $(document).trigger('envato-update-error', response) wp.envato.queueChecker() } /** * Show an error message in the request for credentials form. * * @param {string} message * @since 1.0.0 */ wp.envato.showErrorInCredentialsForm = function (message) { const $modal = $('.notification-dialog') // Remove any existing error. $modal.find('.error').remove() $modal.find('h3').after('
' + message + '
') } /** * Events that need to happen when there is a credential error * * @since 1.0.0 */ wp.envato.credentialError = function (response, type) { wp.envato.updateQueue.push({ type, data: { // Not cool that we're depending on response for this data. // This would feel more whole in a view all tied together. plugin: response.plugin, slug: response.slug } }) wp.envato.showErrorInCredentialsForm(response.error) wp.envato.requestFilesystemCredentials() } /** * If an update job has been placed in the queue, queueChecker pulls it out and runs it. * * @since 1.0.0 */ wp.envato.queueChecker = function () { let job if (wp.envato.updateLock || wp.envato.updateQueue.length <= 0) { return } job = wp.envato.updateQueue.shift() wp.envato.updatePlugin(job.data.plugin, job.data.slug) } /** * Request the users filesystem credentials if we don't have them already. * * @since 1.0.0 */ wp.envato.requestFilesystemCredentials = function (event) { if (wp.envato.updateDoneSuccessfully === false) { wp.envato.$elToReturnFocusToFromCredentialsModal = $(event.target) wp.envato.updateLock = true wp.envato.requestForCredentialsModalOpen() } } /** * Keydown handler for the request for credentials modal. * * Close the modal when the escape key is pressed. * Constrain keyboard navigation to inside the modal. * * @since 1.0.0 */ wp.envato.keydown = function (event) { if (event.keyCode === 27) { wp.envato.requestForCredentialsModalCancel() } else if (event.keyCode === 9) { // #upgrade button must always be the last focusable element in the dialog. if (event.target.id === 'upgrade' && !event.shiftKey) { $('#hostname').focus() event.preventDefault() } else if (event.target.id === 'hostname' && event.shiftKey) { $('#upgrade').focus() event.preventDefault() } } } /** * Open the request for credentials modal. * * @since 1.0.0 */ wp.envato.requestForCredentialsModalOpen = function () { const $modal = $('#request-filesystem-credentials-dialog') $('body').addClass('modal-open') $modal.show() $modal.find('input:enabled:first').focus() $modal.keydown(wp.envato.keydown) } /** * Close the request for credentials modal. * * @since 1.0.0 */ wp.envato.requestForCredentialsModalClose = function () { $('#request-filesystem-credentials-dialog').hide() $('body').removeClass('modal-open') wp.envato.$elToReturnFocusToFromCredentialsModal.focus() } /** * The steps that need to happen when the modal is canceled out * * @since 1.0.0 */ wp.envato.requestForCredentialsModalCancel = function () { let slug, $message // No updateLock and no updateQueue means we already have cleared things up if (wp.envato.updateLock === false && wp.envato.updateQueue.length === 0) { return } slug = wp.envato.updateQueue[0].data.slug, // Remove the lock, and clear the queue wp.envato.updateLock = false wp.envato.updateQueue = [] wp.envato.requestForCredentialsModalClose() $message = $('.envato-card-' + slug).find('.update-now') $message.removeClass('updating-message') $message.html($message.data('originaltext')) } /** * Potentially add an AYS to a user attempting to leave the page * * If an update is on-going and a user attempts to leave the page, * open an "Are you sure?" alert. * * @since 1.0.0 */ wp.envato.beforeunload = function () { if (wp.envato.updateLock) { return wp.i18n.__('Update in progress, really leave?', 'envato-market') } } $(document).ready(function () { /* * Check whether a user needs to submit filesystem credentials based on whether * the form was output on the page server-side. * * @see {wp_print_request_filesystem_credentials_modal() in PHP} */ wp.envato.shouldRequestFilesystemCredentials = !(($('#request-filesystem-credentials-dialog').length <= 0)) // File system credentials form submit noop-er / handler. $('#request-filesystem-credentials-dialog form').on('submit', function () { // Persist the credentials input by the user for the duration of the page load. wp.envato.filesystemCredentials.ftp.hostname = $('#hostname').val() wp.envato.filesystemCredentials.ftp.username = $('#username').val() wp.envato.filesystemCredentials.ftp.password = $('#password').val() wp.envato.filesystemCredentials.ftp.connectionType = $('input[name="connection_type"]:checked').val() wp.envato.filesystemCredentials.ssh.publicKey = $('#public_key').val() wp.envato.filesystemCredentials.ssh.privateKey = $('#private_key').val() wp.envato.requestForCredentialsModalClose() // Unlock and invoke the queue. wp.envato.updateLock = false wp.envato.queueChecker() return false }) // Close the request credentials modal when $('#request-filesystem-credentials-dialog [data-js-action="close"], .notification-dialog-background').on('click', function () { wp.envato.requestForCredentialsModalCancel() }) // Hide SSH fields when not selected $('#request-filesystem-credentials-dialog input[name="connection_type"]').on('change', function () { $(this).parents('form').find('#private_key, #public_key').parents('label').toggle(($(this).val() === 'ssh')) }).change() // Click handler for plugin updates. $('.envato-card.plugin').on('click', '.update-now', function (e) { const $button = $(e.target) e.preventDefault() if (wp.envato.shouldRequestFilesystemCredentials && !wp.envato.updateLock) { wp.envato.requestFilesystemCredentials(e) } wp.envato.updatePlugin($button.data('plugin'), $button.data('slug')) }) // Click handler for theme updates. $('.envato-card.theme').on('click', '.update-now', function (e) { const $button = $(e.target) e.preventDefault() if (wp.envato.shouldRequestFilesystemCredentials && !wp.envato.updateLock) { wp.envato.requestFilesystemCredentials(e) } wp.envato.updateTheme($button.data('slug')) }) // @todo $('#plugin_update_from_iframe').on('click', function (e) { let target, data target = window.parent === window ? null : window.parent, $.support.postMessage = !!window.postMessage if ($.support.postMessage === false || target === null || window.parent.location.pathname.indexOf('update-core.php') !== -1) { return } e.preventDefault() data = { action: 'updatePlugin', slug: $(this).data('slug') } target.postMessage(JSON.stringify(data), window.location.origin) }) }) $(window).on('message', function (e) { const event = e.originalEvent let message const loc = document.location const expectedOrigin = loc.protocol + '//' + loc.hostname if (event.origin !== expectedOrigin) { return } if (event.data) { try { message = $.parseJSON(event.data) } catch (error) { message = event.data } try { if (typeof message.action === 'undefined') { return } } catch (error) { } try { switch (message.action) { case 'decrementUpdateCount' : wp.envato.decrementCount(message.upgradeType) break case 'updatePlugin' : tb_remove() $('.envato-card-' + message.slug).find('h4 a').focus() $('.envato-card-' + message.slug).find('[data-slug="' + message.slug + '"]').trigger('click') break default: } } catch (error) { } } }) $(window).on('beforeunload', wp.envato.beforeunload) })(jQuery, window.wp, window.ajaxurl) js/envato-market.min.js000064400000011130147177457130011071 0ustar00!function(r){"use strict";var o,i={cache:{},init:function(){this.bindEvents()},bindEvents:function(){var e=this;e.addItem(),e.removeItem(),e.tabbedNav(),r(document).on("click",".envato-card a.thickbox",function(){return tb_click.call(this),r("#TB_title").css({"background-color":"#23282d",color:"#cfcfcf"}),!1})},addItem:function(){r(document).on("click",".add-envato-market-item",function(e){var t="envato-market-dialog-form";e.preventDefault(),0===r("#"+t).length&&r("body").append(wp.template(t)),o=r("#"+t).dialog({autoOpen:!0,modal:!0,width:350,buttons:{Save:{text:_envatoMarket.i18n.save,click:function(){var e,t=r(this);t.on("submit",function(e){e.preventDefault()}),e=t.find('input[name="token"]').val(),t=t.find('input[name="id"]').val(),(e=wp.ajax.post(_envatoMarket.action+"_add_item",{nonce:_envatoMarket.nonce,token:e,id:t})).done(function(e){var t=wp.template("envato-market-item"),a=wp.template("envato-market-card"),n=wp.template("envato-market-auth-check-button");r(".nav-tab-wrapper").find('[data-id="'+e.type+'"]').removeClass("hidden"),e.item.type=e.type,r("#"+e.type+"s").append(a(e.item)).removeClass("hidden"),r("#envato-market-items").append(t({name:e.name,token:e.token,id:e.id,key:e.key,type:e.type,authorized:e.authorized})),0===r(".auth-check-button").length&&r("p.submit").append(n),o.dialog("close"),i.addReadmore()}),e.fail(function(e){var t=wp.template("envato-market-dialog-error"),e={message:e.message||_envatoMarket.i18n.error};o.find(".notice").remove(),o.find("form").prepend(t(e)),o.find(".notice").fadeIn("fast")})}},Cancel:{text:_envatoMarket.i18n.cancel,click:function(){o.dialog("close")}}},close:function(){o.find(".notice").remove(),o.find("form")[0].reset()}})})},removeItem:function(){r(document).on("click","#envato-market-items .item-delete",function(e){const n=this;var t="envato-market-dialog-remove";e.preventDefault(),0===r("#"+t).length&&r("body").append(wp.template(t)),o=r("#"+t).dialog({autoOpen:!0,modal:!0,width:350,buttons:{Save:{text:_envatoMarket.i18n.remove,click:function(){var e=r(this);let a;e.on("submit",function(e){e.preventDefault()}),a=r(n).parents("li").data("id"),(e=wp.ajax.post(_envatoMarket.action+"_remove_item",{nonce:_envatoMarket.nonce,id:a})).done(function(){var e=r('.col[data-id="'+a+'"]'),t=e.find(".envato-card").hasClass("theme")?"theme":"plugin";e.remove(),0===r("#"+t+"s").find(".col").length&&(r(".nav-tab-wrapper").find('[data-id="'+t+'"]').addClass("hidden"),r("#"+t+"s").addClass("hidden")),r(n).parents("li").remove(),r("#envato-market-items li").each(function(e){r(this).find("input").each(function(){r(this).attr("name",r(this).attr("name").replace(/\[\d\]/g,"["+e+"]"))})}),0!==r(".auth-check-button").length&&0===r("#envato-market-items li").length&&r("p.submit .auth-check-button").remove(),o.dialog("close")}),e.fail(function(e){var t=wp.template("envato-market-dialog-error"),e={message:e.message||_envatoMarket.i18n.error};o.find(".notice").remove(),o.find("form").prepend(t(e)),o.find(".notice").fadeIn("fast")})}},Cancel:{text:_envatoMarket.i18n.cancel,click:function(){o.dialog("close")}}}})})},tabbedNav:function(){const e=this,t=r(".about-wrap");r("div.panel",t).hide();var a=e.getParameterByName("tab"),n=window.location.hash.substr(1);r(document,t).on("click",".nav-tab-wrapper a",function(){return r(".nav-tab-wrapper a",t).removeClass("nav-tab-active"),r("div.panel",t).hide(),r(this).addClass("nav-tab-active"),r("div"+r(this).attr("href"),t).show(),e.maybeLoadhealthcheck(),!1}),a?r('.nav-tab-wrapper a[href="#'+a+'"]',t).click():n?r('.nav-tab-wrapper a[href="#'+n+'"]',t).click():r("div.panel:not(.hidden)",t).first().show()},getParameterByName:function(e){return e=e.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]"),null===(e=new RegExp("[\\?&]"+e+"=([^&#]*)").exec(location.search))?"":decodeURIComponent(e[1].replace(/\+/g," "))},maybeLoadhealthcheck:function(){const c=r(".envato-market-healthcheck");var e;c.is(":visible")&&(c.text("Loading..."),(e=wp.ajax.post(_envatoMarket.action+"_healthcheck",{nonce:_envatoMarket.nonce})).done(function(t){if(t&&t.limits){var a=r("
    "),n=Object.keys(t.limits);for(let e=0;e"),i=t.limits[n[e]];o.addClass(i.ok?"healthcheck-ok":"healthcheck-error"),o.attr("data-limit",n[e]),o.append(''+i.title+""),o.append(''+i.message+""),a.append(o)}c.html(a)}else window.console.log(t),c.text("Health check failed to load. Please check console for errors.")}),e.fail(function(e){window.console.log(e),c.text("Health check failed to load. Please check console for errors.")}))}};r(window).on("load",function(){i.init()})}(jQuery);js/envato-market.js000064400000017736147177457130010331 0ustar00/* global _envatoMarket, tb_click */ /** * Envato Market sripts. * * @since 1.0.0 */ (function( $ ) { 'use strict'; var dialog, envatoMarket = { cache: {}, init: function () { this.bindEvents() }, bindEvents: function () { const self = this self.addItem() self.removeItem() self.tabbedNav() $(document).on('click', '.envato-card a.thickbox', function () { tb_click.call(this) $('#TB_title').css({ 'background-color': '#23282d', color: '#cfcfcf' }) return false }) }, addItem: function () { $(document).on('click', '.add-envato-market-item', function (event) { const id = 'envato-market-dialog-form' event.preventDefault() if ($('#' + id).length === 0) { $('body').append(wp.template(id)) } dialog = $('#' + id).dialog({ autoOpen: true, modal: true, width: 350, buttons: { Save: { text: _envatoMarket.i18n.save, click: function () { const form = $(this) let request; let token; let input_id form.on('submit', function (event) { event.preventDefault() }) token = form.find('input[name="token"]').val() input_id = form.find('input[name="id"]').val() request = wp.ajax.post(_envatoMarket.action + '_add_item', { nonce: _envatoMarket.nonce, token, id: input_id }) request.done(function (response) { const item = wp.template('envato-market-item') const card = wp.template('envato-market-card') const button = wp.template('envato-market-auth-check-button') $('.nav-tab-wrapper').find('[data-id="' + response.type + '"]').removeClass('hidden') response.item.type = response.type $('#' + response.type + 's').append(card(response.item)).removeClass('hidden') $('#envato-market-items').append(item({ name: response.name, token: response.token, id: response.id, key: response.key, type: response.type, authorized: response.authorized })) if ($('.auth-check-button').length === 0) { $('p.submit').append(button) } dialog.dialog('close') envatoMarket.addReadmore() }) request.fail(function (response) { const template = wp.template('envato-market-dialog-error') const data = { message: (response.message ? response.message : _envatoMarket.i18n.error) } dialog.find('.notice').remove() dialog.find('form').prepend(template(data)) dialog.find('.notice').fadeIn('fast') }) } }, Cancel: { text: _envatoMarket.i18n.cancel, click: function () { dialog.dialog('close') } } }, close: function () { dialog.find('.notice').remove() dialog.find('form')[0].reset() } }) }) }, removeItem: function () { $(document).on('click', '#envato-market-items .item-delete', function (event) { const self = this; const id = 'envato-market-dialog-remove' event.preventDefault() if ($('#' + id).length === 0) { $('body').append(wp.template(id)) } dialog = $('#' + id).dialog({ autoOpen: true, modal: true, width: 350, buttons: { Save: { text: _envatoMarket.i18n.remove, click: function () { const form = $(this) let request; let id form.on('submit', function (submit_event) { submit_event.preventDefault() }) id = $(self).parents('li').data('id') request = wp.ajax.post(_envatoMarket.action + '_remove_item', { nonce: _envatoMarket.nonce, id }) request.done(function () { const item = $('.col[data-id="' + id + '"]') const type = item.find('.envato-card').hasClass('theme') ? 'theme' : 'plugin' item.remove() if ($('#' + type + 's').find('.col').length === 0) { $('.nav-tab-wrapper').find('[data-id="' + type + '"]').addClass('hidden') $('#' + type + 's').addClass('hidden') } $(self).parents('li').remove() $('#envato-market-items li').each(function (index) { $(this).find('input').each(function () { $(this).attr('name', $(this).attr('name').replace(/\[\d\]/g, '[' + index + ']')) }) }) if ($('.auth-check-button').length !== 0 && $('#envato-market-items li').length === 0) { $('p.submit .auth-check-button').remove() } dialog.dialog('close') }) request.fail(function (response) { const template = wp.template('envato-market-dialog-error') const data = { message: response.message ? response.message : _envatoMarket.i18n.error } dialog.find('.notice').remove() dialog.find('form').prepend(template(data)) dialog.find('.notice').fadeIn('fast') }) } }, Cancel: { text: _envatoMarket.i18n.cancel, click: function () { dialog.dialog('close') } } } }) }) }, tabbedNav: function () { const self = this const $wrap = $('.about-wrap') // Hide all panels $('div.panel', $wrap).hide() const tab = self.getParameterByName('tab') const hashTab = window.location.hash.substr(1) // Listen for the click event. $(document, $wrap).on('click', '.nav-tab-wrapper a', function () { // Deactivate and hide all tabs & panels. $('.nav-tab-wrapper a', $wrap).removeClass('nav-tab-active') $('div.panel', $wrap).hide() // Activate and show the selected tab and panel. $(this).addClass('nav-tab-active') $('div' + $(this).attr('href'), $wrap).show() self.maybeLoadhealthcheck() return false }) if (tab) { $('.nav-tab-wrapper a[href="#' + tab + '"]', $wrap).click() } else if (hashTab) { $('.nav-tab-wrapper a[href="#' + hashTab + '"]', $wrap).click() } else { $('div.panel:not(.hidden)', $wrap).first().show() } }, getParameterByName: function (name) { let regex, results name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]') regex = new RegExp('[\\?&]' + name + '=([^&#]*)') results = regex.exec(location.search) return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' ')) }, maybeLoadhealthcheck: function () { // We only load the health check ajax call when the envato-market-healthcheck div is visible on the page. const $healthCheckOutput = $('.envato-market-healthcheck') if ($healthCheckOutput.is(':visible')) { $healthCheckOutput.text('Loading...') // Use our existing wp.ajax.post pattern from above to call the healthcheck API endpoint const request = wp.ajax.post(_envatoMarket.action + '_healthcheck', { nonce: _envatoMarket.nonce }) request.done(function (response) { if (response && response.limits) { const $healthCheckUL = $('
      ') const limits = Object.keys(response.limits) for (let i = 0; i < limits.length; i++) { const $healthCheckLI = $('
    • ') const healthCheckItem = response.limits[limits[i]] $healthCheckLI.addClass(healthCheckItem.ok ? 'healthcheck-ok' : 'healthcheck-error') $healthCheckLI.attr('data-limit', limits[i]) $healthCheckLI.append('' + healthCheckItem.title + '') $healthCheckLI.append('' + healthCheckItem.message + '') $healthCheckUL.append($healthCheckLI) } $healthCheckOutput.html($healthCheckUL) } else { window.console.log(response) $healthCheckOutput.text('Health check failed to load. Please check console for errors.') } }) request.fail(function (response) { window.console.log(response) $healthCheckOutput.text('Health check failed to load. Please check console for errors.') }) } } } $(window).on('load', function () { envatoMarket.init() }) })(jQuery) js/updates.min.js000064400000020675147177457130007777 0ustar00window.wp=window.wp||{},function(i,u){"use strict";u.envato={},u.envato.ajaxNonce=window._wpUpdatesSettings.ajax_nonce,u.envato.shouldRequestFilesystemCredentials=null,u.envato.filesystemCredentials={ftp:{host:null,username:null,password:null,connectionType:null},ssh:{publicKey:null,privateKey:null}},u.envato.updateLock=!1,u.envato.updateDoneSuccessfully=!1,u.envato.updateQueue=[],u.envato.$elToReturnFocusToFromCredentialsModal=null,u.envato.decrementCount=function(e){var a,t=i("#wp-admin-bar-updates .ab-label"),n=i('a[href="update-core.php"] .update-plugins'),o=i("#menu-plugins"),s=t.text();(s=parseInt(s,10)-1)<0||isNaN(s)||(i("#wp-admin-bar-updates .ab-item").removeAttr("title"),t.text(s),n.each(function(e,t){t.className=t.className.replace(/count-\d+/,"count-"+s)}),n.removeAttr("title"),n.find(".update-count").text(s),"plugin"===e&&(a=o.find(".plugin-count").eq(0).text(),(a=parseInt(a,10)-1)<0||isNaN(a)||(o.find(".plugin-count").text(a),o.find(".update-plugins").each(function(e,t){t.className=t.className.replace(/count-\d+/,"count-"+a)}),0'+e+"")},u.envato.credentialError=function(e,t){u.envato.updateQueue.push({type:t,data:{plugin:e.plugin,slug:e.slug}}),u.envato.showErrorInCredentialsForm(e.error),u.envato.requestFilesystemCredentials()},u.envato.queueChecker=function(){var e;u.envato.updateLock||u.envato.updateQueue.length<=0||(e=u.envato.updateQueue.shift(),u.envato.updatePlugin(e.data.plugin,e.data.slug))},u.envato.requestFilesystemCredentials=function(e){!1===u.envato.updateDoneSuccessfully&&(u.envato.$elToReturnFocusToFromCredentialsModal=i(e.target),u.envato.updateLock=!0,u.envato.requestForCredentialsModalOpen())},u.envato.keydown=function(e){27===e.keyCode?u.envato.requestForCredentialsModalCancel():9===e.keyCode&&("upgrade"!==e.target.id||e.shiftKey?"hostname"===e.target.id&&e.shiftKey&&(i("#upgrade").focus(),e.preventDefault()):(i("#hostname").focus(),e.preventDefault()))},u.envato.requestForCredentialsModalOpen=function(){var e=i("#request-filesystem-credentials-dialog");i("body").addClass("modal-open"),e.show(),e.find("input:enabled:first").focus(),e.keydown(u.envato.keydown)},u.envato.requestForCredentialsModalClose=function(){i("#request-filesystem-credentials-dialog").hide(),i("body").removeClass("modal-open"),u.envato.$elToReturnFocusToFromCredentialsModal.focus()},u.envato.requestForCredentialsModalCancel=function(){var e;!1===u.envato.updateLock&&0===u.envato.updateQueue.length||(e=u.envato.updateQueue[0].data.slug,u.envato.updateLock=!1,u.envato.updateQueue=[],u.envato.requestForCredentialsModalClose(),(e=i(".envato-card-"+e).find(".update-now")).removeClass("updating-message"),e.html(e.data("originaltext")))},u.envato.beforeunload=function(){if(u.envato.updateLock)return u.i18n.__("Update in progress, really leave?","envato-market")},i(document).ready(function(){u.envato.shouldRequestFilesystemCredentials=!(i("#request-filesystem-credentials-dialog").length<=0),i("#request-filesystem-credentials-dialog form").on("submit",function(){return u.envato.filesystemCredentials.ftp.hostname=i("#hostname").val(),u.envato.filesystemCredentials.ftp.username=i("#username").val(),u.envato.filesystemCredentials.ftp.password=i("#password").val(),u.envato.filesystemCredentials.ftp.connectionType=i('input[name="connection_type"]:checked').val(),u.envato.filesystemCredentials.ssh.publicKey=i("#public_key").val(),u.envato.filesystemCredentials.ssh.privateKey=i("#private_key").val(),u.envato.requestForCredentialsModalClose(),u.envato.updateLock=!1,u.envato.queueChecker(),!1}),i('#request-filesystem-credentials-dialog [data-js-action="close"], .notification-dialog-background').on("click",function(){u.envato.requestForCredentialsModalCancel()}),i('#request-filesystem-credentials-dialog input[name="connection_type"]').on("change",function(){i(this).parents("form").find("#private_key, #public_key").parents("label").toggle("ssh"===i(this).val())}).change(),i(".envato-card.plugin").on("click",".update-now",function(e){var t=i(e.target);e.preventDefault(),u.envato.shouldRequestFilesystemCredentials&&!u.envato.updateLock&&u.envato.requestFilesystemCredentials(e),u.envato.updatePlugin(t.data("plugin"),t.data("slug"))}),i(".envato-card.theme").on("click",".update-now",function(e){var t=i(e.target);e.preventDefault(),u.envato.shouldRequestFilesystemCredentials&&!u.envato.updateLock&&u.envato.requestFilesystemCredentials(e),u.envato.updateTheme(t.data("slug"))}),i("#plugin_update_from_iframe").on("click",function(e){var t=window.parent===window?null:window.parent;i.support.postMessage=!!window.postMessage,!1!==i.support.postMessage&&null!==t&&-1===window.parent.location.pathname.indexOf("update-core.php")&&(e.preventDefault(),e={action:"updatePlugin",slug:i(this).data("slug")},t.postMessage(JSON.stringify(e),window.location.origin))})}),i(window).on("message",function(t){t=t.originalEvent;let a;var e=document.location,e=e.protocol+"//"+e.hostname;if(t.origin===e&&t.data){try{a=i.parseJSON(t.data)}catch(e){a=t.data}try{if(void 0===a.action)return}catch(e){}try{switch(a.action){case"decrementUpdateCount":u.envato.decrementCount(a.upgradeType);break;case"updatePlugin":tb_remove(),i(".envato-card-"+a.slug).find("h4 a").focus(),i(".envato-card-"+a.slug).find('[data-slug="'+a.slug+'"]').trigger("click")}}catch(e){}}}),i(window).on("beforeunload",u.envato.beforeunload)}(jQuery,window.wp,window.ajaxurl);envato-market.php000064400000007567147177457130010071 0ustar00=' ) ) { add_action( 'admin_notices', 'envato_market_fail_php_version' ); } elseif ( ENVATO_MARKET_SLUG !== 'envato-market' ) { add_action( 'admin_notices', 'envato_market_fail_installation_method' ); } else { if ( ! function_exists( 'is_plugin_active_for_network' ) ) { // Makes sure the plugin functions are defined before trying to use them. require_once( ABSPATH . '/wp-admin/includes/plugin.php' ); } define( 'ENVATO_MARKET_NETWORK_ACTIVATED', is_plugin_active_for_network( ENVATO_MARKET_SLUG . '/envato-market.php' ) ); /* Envato_Market Class */ require_once ENVATO_MARKET_PATH . 'inc/class-envato-market.php'; if ( ! function_exists( 'envato_market' ) ) : /** * The main function responsible for returning the one true * Envato_Market Instance to functions everywhere. * * Use this function like you would a global variable, except * without needing to declare the global. * * Example: * * @since 1.0.0 * @return Envato_Market The one true Envato_Market Instance */ function envato_market() { return Envato_Market::instance(); } endif; /** * Loads the main instance of Envato_Market to prevent * the need to use globals. * * This doesn't fire the activation hook correctly if done in 'after_setup_theme' hook. * * @since 1.0.0 * @return object Envato_Market */ envato_market(); } if ( ! function_exists( 'envato_market_fail_php_version' ) ) { /** * Show in WP Dashboard notice about the plugin is not activated. * * @since 2.0.0 * * @return void */ function envato_market_fail_php_version() { $message = esc_html__( 'The Envato Market plugin requires PHP version 5.4+, plugin is currently NOT ACTIVE. Please contact the hosting provider to upgrade the version of PHP.', 'envato-market' ); $html_message = sprintf( '
      %s
      ', wpautop( $message ) ); echo wp_kses_post( $html_message ); } } if ( ! function_exists( 'envato_market_fail_installation_method' ) ) { /** * The plugin needs to be installed into the `envato-market/` folder otherwise it will not work correctly. * This alert will display if someone has installed it into the incorrect folder (i.e. github download zip). * * @since 2.0.0 * * @return void */ function envato_market_fail_installation_method() { $message = sprintf( esc_html__( 'Envato Market plugin is not installed correctly. Please delete this plugin and get the correct zip file from %s.', 'envato-market' ), 'https://envato.com/market-plugin/' ); $html_message = sprintf( '
      %s
      ', wpautop( $message ) ); echo wp_kses_post( $html_message ); } }