File manager - Edit - /home/foodcost/m4we.com/inc.tar
Back
block-patterns.php 0000644 00000026474 15231617640 0010227 0 ustar 00 <?php /** * Twenty Twenty Theme: Block Patterns * * @package WordPress * @subpackage Twenty_Seventeen * @since Twenty Seventeen 2.5 */ /** * Register Block Pattern Category. */ if ( function_exists( 'register_block_pattern_category' ) ) { register_block_pattern_category( 'twentyseventeen', array( 'label' => __( 'Twenty Seventeen', 'twentyseventeen' ) ) ); } /** * Register Block Patterns. */ if ( function_exists( 'register_block_pattern' ) ) { register_block_pattern( 'twentyseventeen/large-heading-with-button', array( 'title' => __( 'Large Heading with Button', 'twentyseventeen' ), 'categories' => array( 'twentyseventeen' ), 'content' => '<!-- wp:heading {"level":1,"textColor":"black","style":{"typography":{"fontSize":50}}} --> <h1 class="has-black-color has-text-color" style="font-size:50px">' . __( 'Attract Leads with Marketing Campaigns that Work', 'twentyseventeen' ) . '</h1> <!-- /wp:heading --> <!-- wp:buttons --> <div class="wp-block-buttons"><!-- wp:button {"borderRadius":0,"className":"is-style-fill"} --> <div class="wp-block-button is-style-fill"><a class="wp-block-button__link no-border-radius">' . __( 'Our Services', 'twentyseventeen' ) . '</a></div> <!-- /wp:button --></div> <!-- /wp:buttons -->', ) ); register_block_pattern( 'twentyseventeen/images-with-text-and-link', array( 'title' => __( 'Images with Text and Link', 'twentyseventeen' ), 'categories' => array( 'twentyseventeen' ), 'content' => '<!-- wp:spacer --> <div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div> <!-- /wp:spacer --> <!-- wp:columns --> <div class="wp-block-columns"><!-- wp:column --> <div class="wp-block-column"> <!-- wp:image {"className":"size-large"} --> <figure class="wp-block-image size-large"><img src="' . esc_url( get_template_directory_uri() ) . '/assets/images/stripes.jpg" alt="' . __( 'Black Stripes', 'twentyseventeen' ) . '"/></figure> <!-- /wp:image --> <!-- wp:heading {"textColor":"black","style":{"typography":{"fontSize":45}}} --> <h2 class="has-black-color has-text-color" style="font-size:45px">' . __( 'Branding', 'twentyseventeen' ) . '</h2> <!-- /wp:heading --> <!-- wp:paragraph {"textColor":"black","style":{"typography":{"lineHeight":"1.8"}}} --> <p class="has-black-color has-text-color" style="line-height:1.8">' . __( 'Communicate your purpose and goals with a beautiful logo that encapsulates your business.', 'twentyseventeen' ) . '</p> <!-- /wp:paragraph --> <!-- wp:paragraph {"style":{"typography":{"lineHeight":"3"}}} --> <p style="line-height:3"><a href="#"><strong>' . __( 'See Case Study', 'twentyseventeen' ) . ' →</strong></a></p> <!-- /wp:paragraph --></div> <!-- /wp:column --> <!-- wp:column --> <div class="wp-block-column"><!-- wp:spacer {"height":254} --> <div style="height:254px" aria-hidden="true" class="wp-block-spacer"></div> <!-- /wp:spacer --> <!-- wp:image {"className":"size-large"} --> <figure class="wp-block-image size-large"><img src="' . esc_url( get_template_directory_uri() ) . '/assets/images/white-border.jpg" alt="' . __( 'White border', 'twentyseventeen' ) . '"/></figure> <!-- /wp:image --> <!-- wp:heading {"textColor":"black","style":{"typography":{"fontSize":45}}} --> <h2 class="has-black-color has-text-color" style="font-size:45px">' . __( 'Web Design', 'twentyseventeen' ) . '</h2> <!-- /wp:heading --> <!-- wp:paragraph {"textColor":"black","style":{"typography":{"lineHeight":"1.8"}}} --> <p class="has-black-color has-text-color" style="line-height:1.8">' . __( 'Need a website? We've got you covered. Our design team will create a stunning design to transform your brand.', 'twentyseventeen' ) . '</p> <!-- /wp:paragraph --> <!-- wp:paragraph {"style":{"typography":{"lineHeight":"3.0"}}} --> <p style="line-height:3.0"><a href="#"><strong>' . __( 'See Case Study', 'twentyseventeen' ) . ' →</strong></a></p> <!-- /wp:paragraph --></div> <!-- /wp:column --></div> <!-- /wp:columns -->', ) ); register_block_pattern( 'twentyseventeen/images-with-link', array( 'title' => __( 'Images with Link', 'twentyseventeen' ), 'categories' => array( 'twentyseventeen' ), 'content' => '<!-- wp:spacer --> <div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div> <!-- /wp:spacer --> <!-- wp:columns {"verticalAlignment":"top"} --> <div class="wp-block-columns are-vertically-aligned-top"><!-- wp:column --> <div class="wp-block-column"><!-- wp:group --> <div class="wp-block-group"><div class="wp-block-group__inner-container"> <!-- wp:image {"align":"center","sizeSlug":"large","className":"is-style-default"} --> <div class="wp-block-image is-style-default"><figure class="aligncenter size-large"><img src="' . esc_url( get_template_directory_uri() ) . '/assets/images/stripes.jpg" alt="' . __( 'Black Stripes', 'twentyseventeen' ) . '"/></figure></div> <!-- /wp:image --> <!-- wp:heading {"align":"left","textColor":"black","style":{"typography":{"fontSize":30}}} --> <h2 class="has-text-align-left has-black-color has-text-color" style="font-size:30px">' . __( 'Branding', 'twentyseventeen' ) . '</h2> <!-- /wp:heading --> <!-- wp:paragraph {"align":"left"} --> <p class="has-text-align-left"><a href="#">' . __( 'See Case Study', 'twentyseventeen' ) . ' →</a></p> <!-- /wp:paragraph --></div></div> <!-- /wp:group --></div> <!-- /wp:column --> <!-- wp:column --> <div class="wp-block-column"><!-- wp:group --> <div class="wp-block-group"><div class="wp-block-group__inner-container"> <!-- wp:image {"align":"center","sizeSlug":"large","className":"is-style-default"} --> <div class="wp-block-image is-style-default"><figure class="aligncenter size-large"><img src="' . esc_url( get_template_directory_uri() ) . '/assets/images/white-border.jpg" alt="' . __( 'White border', 'twentyseventeen' ) . '"/></figure></div> <!-- /wp:image --> <!-- wp:heading {"align":"left","textColor":"black","style":{"typography":{"fontSize":30}}} --> <h2 class="has-text-align-left has-black-color has-text-color" style="font-size:30px">' . __( 'Design', 'twentyseventeen' ) . '</h2> <!-- /wp:heading --> <!-- wp:paragraph {"align":"left"} --> <p class="has-text-align-left"><a href="#">' . __( 'See Case Study', 'twentyseventeen' ) . ' →</a></p> <!-- /wp:paragraph --></div></div> <!-- /wp:group --></div> <!-- /wp:column --> <!-- wp:column --> <div class="wp-block-column"><!-- wp:group --> <div class="wp-block-group"><div class="wp-block-group__inner-container"> <!-- wp:image {"align":"center","sizeSlug":"large","className":"is-style-default"} --> <div class="wp-block-image is-style-default"><figure class="aligncenter size-large"><img src="' . esc_url( get_template_directory_uri() ) . '/assets/images/direct-light.jpg" alt="' . __( 'Direct Light', 'twentyseventeen' ) . '"/></figure></div> <!-- /wp:image --> <!-- wp:heading {"align":"left","textColor":"black","style":{"typography":{"fontSize":30}}} --> <h2 class="has-text-align-left has-black-color has-text-color" style="font-size:30px">' . __( 'Strategy', 'twentyseventeen' ) . '</h2> <!-- /wp:heading --> <!-- wp:paragraph {"align":"left"} --> <p class="has-text-align-left"><a href="#">' . __( 'See Case Study' ) . ' →</a></p> <!-- /wp:paragraph --></div></div> <!-- /wp:group --></div> <!-- /wp:column --></div> <!-- /wp:columns --> <!-- wp:spacer --> <div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div> <!-- /wp:spacer -->', ) ); register_block_pattern( 'twentyseventeen/services', array( 'title' => __( 'Services', 'twentyseventeen' ), 'categories' => array( 'twentyseventeen' ), 'content' => '<!-- wp:spacer --> <div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div> <!-- /wp:spacer --> <!-- wp:heading {"level":1,"style":{"typography":{"fontSize":50}}} --> <h1 style="font-size:50px">' . __( 'Our Services', 'twentyseventeen' ) . '</h1> <!-- /wp:heading --> <!-- wp:columns --> <div class="wp-block-columns"><!-- wp:column --> <div class="wp-block-column"> <!-- wp:paragraph {"style":{"typography":{"fontSize":21, "lineHeight":"2.5"}}} --> <p style="font-size:21px"><a href="#">' . __( 'Branding', 'twentyseventeen' ) . ' →</a><br><a href="#">' . __( 'Web Design', 'twentyseventeen' ) . ' →</a><br><a href="#">' . __( 'Web Development', 'twentyseventeen' ) . ' →</a></p> <!-- /wp:paragraph --> </div> <!-- /wp:column --> <!-- wp:column --> <div class="wp-block-column"> <!-- wp:paragraph {"style":{"typography":{"fontSize":21, "lineHeight":"2.5"}}} --> <p style="font-size:21px"><a href="#">' . __( 'Content Strategy', 'twentyseventeen' ) . ' →</a><br><a href="#">' . __( 'Marketing & SEO', 'twentyseventeen' ) . ' →</a><br><a href="#">' . __( 'Video Production', 'twentyseventeen' ) . ' →</a></p> <!-- /wp:paragraph --></div> <!-- /wp:column --></div> <!-- /wp:columns --> <!-- wp:spacer --> <div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div> <!-- /wp:spacer -->', ) ); register_block_pattern( 'twentyseventeen/contact-us', array( 'title' => __( 'Contact Us', 'twentyseventeen' ), 'categories' => array( 'twentyseventeen' ), 'content' => '<!-- wp:cover {"customOverlayColor":"#93aab8","minHeight":700,"align":"center"} --> <div class="wp-block-cover aligncenter has-background-dim" style="background-color:#93aab8;min-height:700px"><div class="wp-block-cover__inner-container"><!-- wp:paragraph {"align":"left","textColor":"white","style":{"typography":{"fontSize":50}}} --> <p class="has-text-align-left has-white-color has-text-color" style="font-size:50px">' . __( 'We are proud to serve outstanding clients.', 'twentyseventeen' ) . '</p> <!-- /wp:paragraph --> <!-- wp:buttons --> <div class="wp-block-buttons"><!-- wp:button {"borderRadius":0,"backgroundColor":"black","textColor":"white","className":"is-style-fill"} --> <div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-white-color has-black-background-color has-text-color has-background no-border-radius">' . __( 'Contact us', 'twentyseventeen' ) . '</a></div> <!-- /wp:button --></div> <!-- /wp:buttons --></div></div> <!-- /wp:cover -->', ) ); } custom-css.php 0000644 00000022117 15231617640 0007365 0 ustar 00 <?php /** * Twenty Twenty Custom CSS * * @package WordPress * @subpackage Twenty_Twenty * @since Twenty Twenty 1.0 */ if ( ! function_exists( 'twentytwenty_generate_css' ) ) { /** * Generate CSS. * * @since Twenty Twenty 1.0 * * @param string $selector The CSS selector. * @param string $style The CSS style. * @param string $value The CSS value. * @param string $prefix The CSS prefix. * @param string $suffix The CSS suffix. * @param bool $display Print the styles. */ function twentytwenty_generate_css( $selector, $style, $value, $prefix = '', $suffix = '', $display = true ) { $return = ''; /* * Bail early if we have no $selector elements or properties and $value. */ if ( ! $value || ! $selector ) { return; } $return = sprintf( '%s { %s: %s; }', $selector, $style, $prefix . $value . $suffix ); if ( $display ) { echo $return; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- We need to double check this, but for now, we want to pass PHPCS ;) } return $return; } } if ( ! function_exists( 'twentytwenty_get_customizer_css' ) ) { /** * Get CSS Built from Customizer Options. * Build CSS reflecting colors, fonts and other options set in the Customizer, and return them for output. * * @since Twenty Twenty 1.0 * * @param string $type Whether to return CSS for the "front-end", "block-editor", or "classic-editor". */ function twentytwenty_get_customizer_css( $type = 'front-end' ) { // Get variables. $body = sanitize_hex_color( twentytwenty_get_color_for_area( 'content', 'text' ) ); $body_default = '#000000'; $secondary = sanitize_hex_color( twentytwenty_get_color_for_area( 'content', 'secondary' ) ); $secondary_default = '#6d6d6d'; $borders = sanitize_hex_color( twentytwenty_get_color_for_area( 'content', 'borders' ) ); $borders_default = '#dcd7ca'; $accent = sanitize_hex_color( twentytwenty_get_color_for_area( 'content', 'accent' ) ); $accent_default = '#cd2653'; // Header. $header_footer_background = sanitize_hex_color( twentytwenty_get_color_for_area( 'header-footer', 'background' ) ); $header_footer_background_default = '#ffffff'; // Cover. $cover = sanitize_hex_color( get_theme_mod( 'cover_template_overlay_text_color' ) ); $cover_default = '#ffffff'; // Background. $background = sanitize_hex_color_no_hash( get_theme_mod( 'background_color' ) ); $background_default = 'f5efe0'; ob_start(); /* * Note – Styles are applied in this order: * 1. Element specific * 2. Helper classes * * This enables all helper classes to overwrite base element styles, * meaning that any color classes applied in the block editor will * have a higher priority than the base element styles. */ // Front-End Styles. if ( 'front-end' === $type ) { // Auto-calculated colors. $elements_definitions = twentytwenty_get_elements_array(); foreach ( $elements_definitions as $context => $props ) { foreach ( $props as $key => $definitions ) { foreach ( $definitions as $property => $elements ) { /* * If we don't have an elements array or it is empty * then skip this iteration early; */ if ( ! is_array( $elements ) || empty( $elements ) ) { continue; } $val = twentytwenty_get_color_for_area( $context, $key ); if ( $val ) { twentytwenty_generate_css( implode( ',', $elements ), $property, $val ); } } } } if ( $cover && $cover !== $cover_default ) { twentytwenty_generate_css( '.overlay-header .header-inner', 'color', $cover ); twentytwenty_generate_css( '.cover-header .entry-header *', 'color', $cover ); } // Block Editor Styles. } elseif ( 'block-editor' === $type ) { // Colors. // Accent color. if ( $accent && $accent !== $accent_default ) { twentytwenty_generate_css( ':root .has-accent-color, .editor-styles-wrapper a, .editor-styles-wrapper .has-drop-cap:not(:focus)::first-letter, .editor-styles-wrapper .wp-block-button.is-style-outline .wp-block-button__link, .editor-styles-wrapper .wp-block-pullquote::before, .editor-styles-wrapper .wp-block-file .wp-block-file__textlink', 'color', $accent ); twentytwenty_generate_css( '.editor-styles-wrapper .wp-block-quote', 'border-color', $accent, '' ); twentytwenty_generate_css( '.has-accent-background-color, .editor-styles-wrapper .wp-block-button__link, .editor-styles-wrapper .wp-block-file__button', 'background-color', $accent ); } // Background color. if ( $background && $background !== $background_default ) { twentytwenty_generate_css( '.editor-styles-wrapper', 'background-color', '#' . $background ); twentytwenty_generate_css( '.has-background.has-primary-background-color:not(.has-text-color),.has-background.has-primary-background-color *:not(.has-text-color),.has-background.has-accent-background-color:not(.has-text-color),.has-background.has-accent-background-color *:not(.has-text-color)', 'color', '#' . $background ); } // Borders color. if ( $borders && $borders !== $borders_default ) { twentytwenty_generate_css( '.editor-styles-wrapper .wp-block-code, .editor-styles-wrapper pre, .editor-styles-wrapper .wp-block-preformatted pre, .editor-styles-wrapper .wp-block-verse pre, .editor-styles-wrapper fieldset, .editor-styles-wrapper .wp-block-table, .editor-styles-wrapper .wp-block-table *, .editor-styles-wrapper .wp-block-table.is-style-stripes, .editor-styles-wrapper .wp-block-latest-posts.is-grid li', 'border-color', $borders ); twentytwenty_generate_css( '.editor-styles-wrapper .wp-block-table caption, .editor-styles-wrapper .wp-block-table.is-style-stripes tbody tr:nth-child(odd)', 'background-color', $borders ); } // Text color. if ( $body && $body !== $body_default ) { twentytwenty_generate_css( 'body .editor-styles-wrapper, .editor-post-title__block .editor-post-title__input, .editor-post-title__block .editor-post-title__input:focus', 'color', $body ); } // Secondary color. if ( $secondary && $secondary !== $secondary_default ) { twentytwenty_generate_css( '.editor-styles-wrapper figcaption, .editor-styles-wrapper cite, .editor-styles-wrapper .wp-block-quote__citation, .editor-styles-wrapper .wp-block-quote cite, .editor-styles-wrapper .wp-block-quote footer, .editor-styles-wrapper .wp-block-pullquote__citation, .editor-styles-wrapper .wp-block-pullquote cite, .editor-styles-wrapper .wp-block-pullquote footer, .editor-styles-wrapper ul.wp-block-archives li, .editor-styles-wrapper ul.wp-block-categories li, .editor-styles-wrapper ul.wp-block-latest-posts li, .editor-styles-wrapper ul.wp-block-categories__list li, .editor-styles-wrapper .wp-block-latest-comments time, .editor-styles-wrapper .wp-block-latest-posts time', 'color', $secondary ); } // Header Footer Background Color. if ( $header_footer_background && $header_footer_background !== $header_footer_background_default ) { twentytwenty_generate_css( '.editor-styles-wrapper .wp-block-pullquote::before', 'background-color', $header_footer_background ); } } elseif ( 'classic-editor' === $type ) { // Colors. // Accent color. if ( $accent && $accent !== $accent_default ) { twentytwenty_generate_css( 'body#tinymce.wp-editor.content a, body#tinymce.wp-editor.content a:focus, body#tinymce.wp-editor.content a:hover', 'color', $accent ); twentytwenty_generate_css( 'body#tinymce.wp-editor.content blockquote, body#tinymce.wp-editor.content .wp-block-quote', 'border-color', $accent, '', ' !important' ); twentytwenty_generate_css( 'body#tinymce.wp-editor.content button, body#tinymce.wp-editor.content .faux-button, body#tinymce.wp-editor.content .wp-block-button__link, body#tinymce.wp-editor.content .wp-block-file__button, body#tinymce.wp-editor.content input[type=\'button\'], body#tinymce.wp-editor.content input[type=\'reset\'], body#tinymce.wp-editor.content input[type=\'submit\']', 'background-color', $accent ); } // Background color. if ( $background && $background !== $background_default ) { twentytwenty_generate_css( 'body#tinymce.wp-editor.content', 'background-color', '#' . $background ); } // Text color. if ( $body && $body !== $body_default ) { twentytwenty_generate_css( 'body#tinymce.wp-editor.content', 'color', $body ); } // Secondary color. if ( $secondary && $secondary !== $secondary_default ) { twentytwenty_generate_css( 'body#tinymce.wp-editor.content hr:not(.is-style-dots), body#tinymce.wp-editor.content cite, body#tinymce.wp-editor.content figcaption, body#tinymce.wp-editor.content .wp-caption-text, body#tinymce.wp-editor.content .wp-caption-dd, body#tinymce.wp-editor.content .gallery-caption', 'color', $secondary ); } // Borders color. if ( $borders && $borders !== $borders_default ) { twentytwenty_generate_css( 'body#tinymce.wp-editor.content pre, body#tinymce.wp-editor.content hr, body#tinymce.wp-editor.content fieldset,body#tinymce.wp-editor.content input, body#tinymce.wp-editor.content textarea', 'border-color', $borders ); } } // Return the results. return ob_get_clean(); } } starter-content.php 0000644 00000027146 15231617640 0010430 0 ustar 00 <?php /** * Twenty Twenty Starter Content * * @link https://make.wordpress.org/core/2016/11/30/starter-content-for-themes-in-4-7/ * * @package WordPress * @subpackage Twenty_Twenty * @since Twenty Twenty 1.0 */ /** * Function to return the array of starter content for the theme. * * Passes it through the `twentytwenty_starter_content` filter before returning. * * @since Twenty Twenty 1.0 * * @return array A filtered array of args for the starter_content. */ function twentytwenty_get_starter_content() { // Define and register starter content to showcase the theme on new sites. $starter_content = array( 'widgets' => array( // Place one core-defined widgets in the first footer widget area. 'sidebar-1' => array( 'text_about', ), // Place one core-defined widgets in the second footer widget area. 'sidebar-2' => array( 'text_business_info', ), ), // Create the custom image attachments used as post thumbnails for pages. 'attachments' => array( 'image-opening' => array( 'post_title' => _x( 'The New UMoMA Opens its Doors', 'Theme starter content', 'twentytwenty' ), 'file' => 'assets/images/2020-landscape-1.png', // URL relative to the template directory. ), ), // Specify the core-defined pages to create and add custom thumbnails to some of them. 'posts' => array( 'front' => array( 'post_type' => 'page', 'post_title' => __( 'The New UMoMA Opens its Doors', 'twentytwenty' ), // Use the above featured image with the predefined about page. 'thumbnail' => '{{image-opening}}', 'post_content' => implode( '', array( '<!-- wp:group {"align":"wide"} -->', '<div class="wp-block-group alignwide"><div class="wp-block-group__inner-container"><!-- wp:heading {"align":"center"} -->', '<h2 class="has-text-align-center">' . __( 'The premier destination for modern art in Northern Sweden. Open from 10 AM to 6 PM every day during the summer months.', 'twentytwenty' ) . '</h2>', '<!-- /wp:heading --></div></div>', '<!-- /wp:group -->', '<!-- wp:columns {"align":"wide"} -->', '<div class="wp-block-columns alignwide"><!-- wp:column -->', '<div class="wp-block-column"><!-- wp:group -->', '<div class="wp-block-group"><div class="wp-block-group__inner-container">', '<!-- wp:image {"align":"full","id":37,"sizeSlug":"full"} -->', '<figure class="wp-block-image alignfull size-full"><img src="' . get_theme_file_uri() . '/assets/images/2020-three-quarters-1.png" alt="" class="wp-image-37"/></figure>', '<!-- /wp:image -->', '<!-- wp:heading {"level":3} -->', '<h3>' . __( 'Works and Days', 'twentytwenty' ) . '</h3>', '<!-- /wp:heading -->', '<!-- wp:paragraph -->', '<p>' . __( 'August 1 -- December 1', 'twentytwenty' ) . '</p>', '<!-- /wp:paragraph -->', '<!-- wp:button {"className":"is-style-outline"} -->', '<div class="wp-block-button is-style-outline"><a class="wp-block-button__link" href="https://make.wordpress.org/core/2019/09/27/block-editor-theme-related-updates-in-wordpress-5-3/">' . __( 'Read More', 'twentytwenty' ) . '</a></div>', '<!-- /wp:button --></div></div>', '<!-- /wp:group -->', '<!-- wp:group -->', '<div class="wp-block-group"><div class="wp-block-group__inner-container">', '<!-- wp:image {"align":"full","id":37,"sizeSlug":"full"} -->', '<figure class="wp-block-image alignfull size-full"><img src="' . get_theme_file_uri() . '/assets/images/2020-three-quarters-3.png" alt="" class="wp-image-37"/></figure>', '<!-- /wp:image -->', '<!-- wp:heading {"level":3} -->', '<h3>' . __( 'Theatre of Operations', 'twentytwenty' ) . '</h3>', '<!-- /wp:heading -->', '<!-- wp:paragraph -->', '<p>' . __( 'October 1 -- December 1', 'twentytwenty' ) . '</p>', '<!-- /wp:paragraph -->', '<!-- wp:button {"className":"is-style-outline"} -->', '<div class="wp-block-button is-style-outline"><a class="wp-block-button__link" href="https://make.wordpress.org/core/2019/09/27/block-editor-theme-related-updates-in-wordpress-5-3/">' . __( 'Read More', 'twentytwenty' ) . '</a></div>', '<!-- /wp:button --></div></div>', '<!-- /wp:group --></div>', '<!-- /wp:column -->', '<!-- wp:column -->', '<div class="wp-block-column"><!-- wp:group -->', '<div class="wp-block-group"><div class="wp-block-group__inner-container">', '<!-- wp:image {"align":"full","id":37,"sizeSlug":"full"} -->', '<figure class="wp-block-image alignfull size-full"><img src="' . get_theme_file_uri() . '/assets/images/2020-three-quarters-2.png" alt="" class="wp-image-37"/></figure>', '<!-- /wp:image -->', '<!-- wp:heading {"level":3} -->', '<h3>' . __( 'The Life I Deserve', 'twentytwenty' ) . '</h3>', '<!-- /wp:heading -->', '<!-- wp:paragraph -->', '<p>' . __( 'August 1 -- December 1', 'twentytwenty' ) . '</p>', '<!-- /wp:paragraph -->', '<!-- wp:button {"className":"is-style-outline"} -->', '<div class="wp-block-button is-style-outline"><a class="wp-block-button__link" href="https://make.wordpress.org/core/2019/09/27/block-editor-theme-related-updates-in-wordpress-5-3/">' . __( 'Read More', 'twentytwenty' ) . '</a></div>', '<!-- /wp:button --></div></div>', '<!-- /wp:group -->', '<!-- wp:group -->', '<div class="wp-block-group"><div class="wp-block-group__inner-container">', '<!-- wp:image {"align":"full","id":37,"sizeSlug":"full"} -->', '<figure class="wp-block-image alignfull size-full"><img src="' . get_theme_file_uri() . '/assets/images/2020-three-quarters-4.png" alt="" class="wp-image-37"/></figure>', '<!-- /wp:image -->', '<!-- wp:heading {"level":3} -->', '<h3>' . __( 'From Signac to Matisse', 'twentytwenty' ) . '</h3>', '<!-- /wp:heading -->', '<!-- wp:paragraph -->', '<p>' . __( 'October 1 -- December 1', 'twentytwenty' ) . '</p>', '<!-- /wp:paragraph -->', '<!-- wp:button {"className":"is-style-outline"} -->', '<div class="wp-block-button is-style-outline"><a class="wp-block-button__link" href="https://make.wordpress.org/core/2019/09/27/block-editor-theme-related-updates-in-wordpress-5-3/">' . __( 'Read More', 'twentytwenty' ) . '</a></div>', '<!-- /wp:button --></div></div>', '<!-- /wp:group --></div>', '<!-- /wp:column --></div>', '<!-- /wp:columns -->', '<!-- wp:image {"align":"full","id":37,"sizeSlug":"full"} -->', '<figure class="wp-block-image alignfull size-full"><img src="' . get_theme_file_uri() . '/assets/images/2020-landscape-2.png" alt="" class="wp-image-37"/></figure>', '<!-- /wp:image -->', '<!-- wp:group {"align":"wide"} -->', '<div class="wp-block-group alignwide"><div class="wp-block-group__inner-container"><!-- wp:heading {"align":"center","textColor":"accent"} -->', '<h2 class="has-accent-color has-text-align-center">' . __( '“Cyborgs, as the philosopher Donna Haraway established, are not reverent. They do not remember the cosmos.”', 'twentytwenty' ) . '</h2>', '<!-- /wp:heading --></div></div>', '<!-- /wp:group -->', '<!-- wp:paragraph {"dropCap":true} -->', '<p class="has-drop-cap">' . __( 'With seven floors of striking architecture, UMoMA shows exhibitions of international contemporary art, sometimes along with art historical retrospectives. Existential, political and philosophical issues are intrinsic to our programme. As visitor you are invited to guided tours artist talks, lectures, film screenings and other events with free admission', 'twentytwenty' ) . '</p>', '<!-- /wp:paragraph -->', '<!-- wp:paragraph -->', '<p>' . __( 'The exhibitions are produced by UMoMA in collaboration with artists and museums around the world and they often attract international attention. UMoMA has received a Special Commendation from the European Museum of the Year, and was among the top candidates for the Swedish Museum of the Year Award as well as for the Council of Europe Museum Prize.', 'twentytwenty' ) . '</p>', '<!-- /wp:paragraph -->', '<!-- wp:paragraph -->', '<p></p>', '<!-- /wp:paragraph -->', '<!-- wp:group {"customBackgroundColor":"#ffffff","align":"wide"} -->', '<div class="wp-block-group alignwide has-background" style="background-color:#ffffff"><div class="wp-block-group__inner-container"><!-- wp:group -->', '<div class="wp-block-group"><div class="wp-block-group__inner-container"><!-- wp:heading {"align":"center"} -->', '<h2 class="has-text-align-center">' . __( 'Become a Member and Get Exclusive Offers!', 'twentytwenty' ) . '</h2>', '<!-- /wp:heading -->', '<!-- wp:paragraph {"align":"center"} -->', '<p class="has-text-align-center">' . __( 'Members get access to exclusive exhibits and sales. Our memberships cost $99.99 and are billed annually.', 'twentytwenty' ) . '</p>', '<!-- /wp:paragraph -->', '<!-- wp:button {"align":"center"} -->', '<div class="wp-block-button aligncenter"><a class="wp-block-button__link" href="https://make.wordpress.org/core/2019/09/27/block-editor-theme-related-updates-in-wordpress-5-3/">' . __( 'Join the Club', 'twentytwenty' ) . '</a></div>', '<!-- /wp:button --></div></div>', '<!-- /wp:group --></div></div>', '<!-- /wp:group -->', '<!-- wp:gallery {"ids":[39,38],"align":"wide"} -->', '<figure class="wp-block-gallery alignwide columns-2 is-cropped"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><img src="' . get_theme_file_uri() . '/assets/images/2020-square-2.png" alt="" data-id="39" data-full-url="' . get_theme_file_uri() . '/assets/images/2020-square-2.png" data-link="assets/images/2020-square-2/" class="wp-image-39"/></figure></li><li class="blocks-gallery-item"><figure><img src="' . get_theme_file_uri() . '/assets/images/2020-square-1.png" alt="" data-id="38" data-full-url="' . get_theme_file_uri() . '/assets/images/2020-square-1.png" data-link="' . get_theme_file_uri() . '/assets/images/2020-square-1/" class="wp-image-38"/></figure></li></ul></figure>', '<!-- /wp:gallery -->', ) ), ), 'about', 'contact', 'blog', ), // Default to a static front page and assign the front and posts pages. 'options' => array( 'show_on_front' => 'page', 'page_on_front' => '{{front}}', 'page_for_posts' => '{{blog}}', ), // Set up nav menus for each of the two areas registered in the theme. 'nav_menus' => array( // Assign a menu to the "primary" location. 'primary' => array( 'name' => __( 'Primary', 'twentytwenty' ), 'items' => array( 'link_home', // Note that the core "home" page is actually a link in case a static front page is not used. 'page_about', 'page_blog', 'page_contact', ), ), // This replicates primary just to demonstrate the expanded menu. 'expanded' => array( 'name' => __( 'Primary', 'twentytwenty' ), 'items' => array( 'link_home', // Note that the core "home" page is actually a link in case a static front page is not used. 'page_about', 'page_blog', 'page_contact', ), ), // Assign a menu to the "social" location. 'social' => array( 'name' => __( 'Social Links Menu', 'twentytwenty' ), 'items' => array( 'link_yelp', 'link_facebook', 'link_twitter', 'link_instagram', 'link_email', ), ), ), ); /** * Filters Twenty Twenty array of starter content. * * @since Twenty Twenty 1.0 * * @param array $starter_content Array of starter content. */ return apply_filters( 'twentytwenty_starter_content', $starter_content ); } svg-icons.php 0000644 00000003611 15231617640 0007173 0 ustar 00 <?php /** * Twenty Twenty SVG Icon helper functions * * @package WordPress * @subpackage Twenty_Twenty * @since Twenty Twenty 1.0 */ if ( ! function_exists( 'twentytwenty_the_theme_svg' ) ) { /** * Output and Get Theme SVG. * Output and get the SVG markup for an icon in the TwentyTwenty_SVG_Icons class. * * @since Twenty Twenty 1.0 * * @param string $svg_name The name of the icon. * @param string $group The group the icon belongs to. * @param string $color Color code. */ function twentytwenty_the_theme_svg( $svg_name, $group = 'ui', $color = '' ) { echo twentytwenty_get_theme_svg( $svg_name, $group, $color ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped in twentytwenty_get_theme_svg(). } } if ( ! function_exists( 'twentytwenty_get_theme_svg' ) ) { /** * Get information about the SVG icon. * * @since Twenty Twenty 1.0 * * @param string $svg_name The name of the icon. * @param string $group The group the icon belongs to. * @param string $color Color code. */ function twentytwenty_get_theme_svg( $svg_name, $group = 'ui', $color = '' ) { // Make sure that only our allowed tags and attributes are included. $svg = wp_kses( TwentyTwenty_SVG_Icons::get_svg( $svg_name, $group, $color ), array( 'svg' => array( 'class' => true, 'xmlns' => true, 'width' => true, 'height' => true, 'viewbox' => true, 'aria-hidden' => true, 'role' => true, 'focusable' => true, ), 'path' => array( 'fill' => true, 'fill-rule' => true, 'd' => true, 'transform' => true, ), 'polygon' => array( 'fill' => true, 'fill-rule' => true, 'points' => true, 'transform' => true, 'focusable' => true, ), ) ); if ( ! $svg ) { return false; } return $svg; } } template-tags.php 0000644 00000015611 15231617640 0010035 0 ustar 00 <?php /** * Custom template tags for this theme * * Eventually, some of the functionality here could be replaced by core features. * * @package WordPress * @subpackage Twenty_Seventeen * @since Twenty Seventeen 1.0 */ if ( ! function_exists( 'twentyseventeen_posted_on' ) ) : /** * Prints HTML with meta information for the current post-date/time and author. */ function twentyseventeen_posted_on() { // Get the author name; wrap it in a link. $byline = sprintf( /* translators: %s: Post author. */ __( 'by %s', 'twentyseventeen' ), '<span class="author vcard"><a class="url fn n" href="' . esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ) . '">' . get_the_author() . '</a></span>' ); // Finally, let's write all of this to the page. echo '<span class="posted-on">' . twentyseventeen_time_link() . '</span><span class="byline"> ' . $byline . '</span>'; } endif; if ( ! function_exists( 'twentyseventeen_time_link' ) ) : /** * Gets a nicely formatted string for the published date. */ function twentyseventeen_time_link() { $time_string = '<time class="entry-date published updated" datetime="%1$s">%2$s</time>'; if ( get_the_time( 'U' ) !== get_the_modified_time( 'U' ) ) { $time_string = '<time class="entry-date published" datetime="%1$s">%2$s</time><time class="updated" datetime="%3$s">%4$s</time>'; } $time_string = sprintf( $time_string, get_the_date( DATE_W3C ), get_the_date(), get_the_modified_date( DATE_W3C ), get_the_modified_date() ); // Wrap the time string in a link, and preface it with 'Posted on'. return sprintf( /* translators: %s: Post date. */ __( '<span class="screen-reader-text">Posted on</span> %s', 'twentyseventeen' ), '<a href="' . esc_url( get_permalink() ) . '" rel="bookmark">' . $time_string . '</a>' ); } endif; if ( ! function_exists( 'twentyseventeen_entry_footer' ) ) : /** * Prints HTML with meta information for the categories, tags and comments. */ function twentyseventeen_entry_footer() { $separate_meta = wp_get_list_item_separator(); // Get Categories for posts. $categories_list = get_the_category_list( $separate_meta ); // Get Tags for posts. $tags_list = get_the_tag_list( '', $separate_meta ); // We don't want to output .entry-footer if it will be empty, so make sure its not. if ( ( ( twentyseventeen_categorized_blog() && $categories_list ) || $tags_list ) || get_edit_post_link() ) { echo '<footer class="entry-footer">'; if ( 'post' === get_post_type() ) { if ( ( $categories_list && twentyseventeen_categorized_blog() ) || $tags_list ) { echo '<span class="cat-tags-links">'; // Make sure there's more than one category before displaying. if ( $categories_list && twentyseventeen_categorized_blog() ) { echo '<span class="cat-links">' . twentyseventeen_get_svg( array( 'icon' => 'folder-open' ) ) . '<span class="screen-reader-text">' . __( 'Categories', 'twentyseventeen' ) . '</span>' . $categories_list . '</span>'; } if ( $tags_list && ! is_wp_error( $tags_list ) ) { echo '<span class="tags-links">' . twentyseventeen_get_svg( array( 'icon' => 'hashtag' ) ) . '<span class="screen-reader-text">' . __( 'Tags', 'twentyseventeen' ) . '</span>' . $tags_list . '</span>'; } echo '</span>'; } } twentyseventeen_edit_link(); echo '</footer> <!-- .entry-footer -->'; } } endif; if ( ! function_exists( 'twentyseventeen_edit_link' ) ) : /** * Returns an accessibility-friendly link to edit a post or page. * * This also gives us a little context about what exactly we're editing * (post or page?) so that users understand a bit more where they are in terms * of the template hierarchy and their content. Helpful when/if the single-page * layout with multiple posts/pages shown gets confusing. */ function twentyseventeen_edit_link() { edit_post_link( sprintf( /* translators: %s: Post title. Only visible to screen readers. */ __( 'Edit<span class="screen-reader-text"> "%s"</span>', 'twentyseventeen' ), get_the_title() ), '<span class="edit-link">', '</span>' ); } endif; /** * Display a front page section. * * @param WP_Customize_Partial $partial Partial associated with a selective refresh request. * @param int $id Front page section to display. */ function twentyseventeen_front_page_section( $partial = null, $id = 0 ) { if ( is_a( $partial, 'WP_Customize_Partial' ) ) { // Find out the ID and set it up during a selective refresh. global $twentyseventeencounter; $id = str_replace( 'panel_', '', $partial->id ); $twentyseventeencounter = $id; } global $post; // Modify the global post object before setting up post data. if ( get_theme_mod( 'panel_' . $id ) ) { $post = get_post( get_theme_mod( 'panel_' . $id ) ); setup_postdata( $post ); set_query_var( 'panel', $id ); get_template_part( 'template-parts/page/content', 'front-page-panels' ); wp_reset_postdata(); } elseif ( is_customize_preview() ) { // The output placeholder anchor. printf( '<article class="panel-placeholder panel twentyseventeen-panel twentyseventeen-panel%1$s" id="panel%1$s">' . '<span class="twentyseventeen-panel-title">%2$s</span></article>', $id, /* translators: %s: The section ID. */ sprintf( __( 'Front Page Section %s Placeholder', 'twentyseventeen' ), $id ) ); } } /** * Returns true if a blog has more than 1 category. * * @return bool */ function twentyseventeen_categorized_blog() { $category_count = get_transient( 'twentyseventeen_categories' ); if ( false === $category_count ) { // Create an array of all the categories that are attached to posts. $categories = get_categories( array( 'fields' => 'ids', 'hide_empty' => 1, // We only need to know if there is more than one category. 'number' => 2, ) ); // Count the number of categories that are attached to the posts. $category_count = count( $categories ); set_transient( 'twentyseventeen_categories', $category_count ); } // Allow viewing case of 0 or 1 categories in post preview. if ( is_preview() ) { return true; } return $category_count > 1; } /** * Flush out the transients used in twentyseventeen_categorized_blog. */ function twentyseventeen_category_transient_flusher() { if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; } // Like, beat it. Dig? delete_transient( 'twentyseventeen_categories' ); } add_action( 'edit_category', 'twentyseventeen_category_transient_flusher' ); add_action( 'save_post', 'twentyseventeen_category_transient_flusher' ); if ( ! function_exists( 'wp_body_open' ) ) : /** * Fire the wp_body_open action. * * Added for backward compatibility to support pre-5.2.0 WordPress versions. * * @since Twenty Seventeen 2.2 */ function wp_body_open() { /** * Triggered after the opening <body> tag. * * @since Twenty Seventeen 2.2 */ do_action( 'wp_body_open' ); } endif; back-compat.php 0000644 00000004770 15231636277 0007462 0 ustar 00 <?php /** * Twenty Seventeen back compat functionality * * Prevents Twenty Seventeen from running on WordPress versions prior to 4.7, * since this theme is not meant to be backward compatible beyond that and * relies on many newer functions and markup changes introduced in 4.7. * * @package WordPress * @subpackage Twenty_Seventeen * @since Twenty Seventeen 1.0 */ /** * Prevent switching to Twenty Seventeen on old versions of WordPress. * * Switches to the default theme. * * @since Twenty Seventeen 1.0 */ function twentyseventeen_switch_theme() { switch_theme( WP_DEFAULT_THEME ); unset( $_GET['activated'] ); add_action( 'admin_notices', 'twentyseventeen_upgrade_notice' ); } add_action( 'after_switch_theme', 'twentyseventeen_switch_theme' ); /** * Adds a message for unsuccessful theme switch. * * Prints an update nag after an unsuccessful attempt to switch to * Twenty Seventeen on WordPress versions prior to 4.7. * * @since Twenty Seventeen 1.0 * * @global string $wp_version WordPress version. */ function twentyseventeen_upgrade_notice() { printf( '<div class="error"><p>%s</p></div>', sprintf( /* translators: %s: The current WordPress version. */ __( 'Twenty Seventeen requires at least WordPress version 4.7. You are running version %s. Please upgrade and try again.', 'twentyseventeen' ), $GLOBALS['wp_version'] ) ); } /** * Prevents the Customizer from being loaded on WordPress versions prior to 4.7. * * @since Twenty Seventeen 1.0 * * @global string $wp_version WordPress version. */ function twentyseventeen_customize() { wp_die( sprintf( /* translators: %s: The current WordPress version. */ __( 'Twenty Seventeen requires at least WordPress version 4.7. You are running version %s. Please upgrade and try again.', 'twentyseventeen' ), $GLOBALS['wp_version'] ), '', array( 'back_link' => true, ) ); } add_action( 'load-customize.php', 'twentyseventeen_customize' ); /** * Prevents the Theme Preview from being loaded on WordPress versions prior to 4.7. * * @since Twenty Seventeen 1.0 * * @global string $wp_version WordPress version. */ function twentyseventeen_preview() { if ( isset( $_GET['preview'] ) ) { wp_die( sprintf( /* translators: %s: The current WordPress version. */ __( 'Twenty Seventeen requires at least WordPress version 4.7. You are running version %s. Please upgrade and try again.', 'twentyseventeen' ), $GLOBALS['wp_version'] ) ); } } add_action( 'template_redirect', 'twentyseventeen_preview' ); color-patterns.php 0000644 00000053774 15231636277 0010265 0 ustar 00 <?php /** * Twenty Seventeen: Color Patterns * * @package WordPress * @subpackage Twenty_Seventeen * @since Twenty Seventeen 1.0 */ /** * Generate the CSS for the current custom color scheme. */ function twentyseventeen_custom_colors_css() { $hue = absint( get_theme_mod( 'colorscheme_hue', 250 ) ); /** * Filters Twenty Seventeen default saturation level. * * @since Twenty Seventeen 1.0 * * @param int $saturation Color saturation level. */ $saturation = absint( apply_filters( 'twentyseventeen_custom_colors_saturation', 50 ) ); $reduced_saturation = ( .8 * $saturation ) . '%'; $saturation = $saturation . '%'; $css = ' /** * Twenty Seventeen: Color Patterns * * Colors are ordered from dark to light. */ .colors-custom a:hover, .colors-custom a:active, .colors-custom .entry-content a:focus, .colors-custom .entry-content a:hover, .colors-custom .entry-summary a:focus, .colors-custom .entry-summary a:hover, .colors-custom .comment-content a:focus, .colors-custom .comment-content a:hover, .colors-custom .widget a:focus, .colors-custom .widget a:hover, .colors-custom .site-footer .widget-area a:focus, .colors-custom .site-footer .widget-area a:hover, .colors-custom .posts-navigation a:focus, .colors-custom .posts-navigation a:hover, .colors-custom .comment-metadata a:focus, .colors-custom .comment-metadata a:hover, .colors-custom .comment-metadata a.comment-edit-link:focus, .colors-custom .comment-metadata a.comment-edit-link:hover, .colors-custom .comment-reply-link:focus, .colors-custom .comment-reply-link:hover, .colors-custom .widget_authors a:focus strong, .colors-custom .widget_authors a:hover strong, .colors-custom .entry-title a:focus, .colors-custom .entry-title a:hover, .colors-custom .entry-meta a:focus, .colors-custom .entry-meta a:hover, .colors-custom.blog .entry-meta a.post-edit-link:focus, .colors-custom.blog .entry-meta a.post-edit-link:hover, .colors-custom.archive .entry-meta a.post-edit-link:focus, .colors-custom.archive .entry-meta a.post-edit-link:hover, .colors-custom.search .entry-meta a.post-edit-link:focus, .colors-custom.search .entry-meta a.post-edit-link:hover, .colors-custom .page-links a:focus .page-number, .colors-custom .page-links a:hover .page-number, .colors-custom .entry-footer a:focus, .colors-custom .entry-footer a:hover, .colors-custom .entry-footer .cat-links a:focus, .colors-custom .entry-footer .cat-links a:hover, .colors-custom .entry-footer .tags-links a:focus, .colors-custom .entry-footer .tags-links a:hover, .colors-custom .post-navigation a:focus, .colors-custom .post-navigation a:hover, .colors-custom .pagination a:not(.prev):not(.next):focus, .colors-custom .pagination a:not(.prev):not(.next):hover, .colors-custom .comments-pagination a:not(.prev):not(.next):focus, .colors-custom .comments-pagination a:not(.prev):not(.next):hover, .colors-custom .logged-in-as a:focus, .colors-custom .logged-in-as a:hover, .colors-custom a:focus .nav-title, .colors-custom a:hover .nav-title, .colors-custom .edit-link a:focus, .colors-custom .edit-link a:hover, .colors-custom .site-info a:focus, .colors-custom .site-info a:hover, .colors-custom .widget .widget-title a:focus, .colors-custom .widget .widget-title a:hover, .colors-custom .widget ul li a:focus, .colors-custom .widget ul li a:hover { color: hsl( ' . $hue . ', ' . $saturation . ', 0% ); /* base: #000; */ } .colors-custom .entry-content a, .colors-custom .entry-summary a, .colors-custom .comment-content a, .colors-custom .widget a, .colors-custom .site-footer .widget-area a, .colors-custom .posts-navigation a, .colors-custom .widget_authors a strong { -webkit-box-shadow: inset 0 -1px 0 hsl( ' . $hue . ', ' . $saturation . ', 6% ); /* base: rgba(15, 15, 15, 1); */ box-shadow: inset 0 -1px 0 hsl( ' . $hue . ', ' . $saturation . ', 6% ); /* base: rgba(15, 15, 15, 1); */ } .colors-custom button, .colors-custom input[type="button"], .colors-custom input[type="submit"], .colors-custom .entry-footer .edit-link a.post-edit-link { background-color: hsl( ' . $hue . ', ' . $saturation . ', 13% ); /* base: #222; */ } .colors-custom input[type="text"]:focus, .colors-custom input[type="email"]:focus, .colors-custom input[type="url"]:focus, .colors-custom input[type="password"]:focus, .colors-custom input[type="search"]:focus, .colors-custom input[type="number"]:focus, .colors-custom input[type="tel"]:focus, .colors-custom input[type="range"]:focus, .colors-custom input[type="date"]:focus, .colors-custom input[type="month"]:focus, .colors-custom input[type="week"]:focus, .colors-custom input[type="time"]:focus, .colors-custom input[type="datetime"]:focus, .colors-custom .colors-custom input[type="datetime-local"]:focus, .colors-custom input[type="color"]:focus, .colors-custom textarea:focus, .colors-custom button.secondary, .colors-custom input[type="reset"], .colors-custom input[type="button"].secondary, .colors-custom input[type="reset"].secondary, .colors-custom input[type="submit"].secondary, .colors-custom a, .colors-custom .site-title, .colors-custom .site-title a, .colors-custom .navigation-top a, .colors-custom .dropdown-toggle, .colors-custom .menu-toggle, .colors-custom .page .panel-content .entry-title, .colors-custom .page-title, .colors-custom.page:not(.twentyseventeen-front-page) .entry-title, .colors-custom .page-links a .page-number, .colors-custom .comment-metadata a.comment-edit-link, .colors-custom .comment-reply-link .icon, .colors-custom h2.widget-title, .colors-custom mark, .colors-custom .post-navigation a:focus .icon, .colors-custom .post-navigation a:hover .icon, .colors-custom .site-content .site-content-light, .colors-custom .twentyseventeen-panel .recent-posts .entry-header .edit-link { color: hsl( ' . $hue . ', ' . $saturation . ', 13% ); /* base: #222; */ } .colors-custom .entry-content a:focus, .colors-custom .entry-content a:hover, .colors-custom .entry-summary a:focus, .colors-custom .entry-summary a:hover, .colors-custom .comment-content a:focus, .colors-custom .comment-content a:hover, .colors-custom .widget a:focus, .colors-custom .widget a:hover, .colors-custom .site-footer .widget-area a:focus, .colors-custom .site-footer .widget-area a:hover, .colors-custom .posts-navigation a:focus, .colors-custom .posts-navigation a:hover, .colors-custom .comment-metadata a:focus, .colors-custom .comment-metadata a:hover, .colors-custom .comment-metadata a.comment-edit-link:focus, .colors-custom .comment-metadata a.comment-edit-link:hover, .colors-custom .comment-reply-link:focus, .colors-custom .comment-reply-link:hover, .colors-custom .widget_authors a:focus strong, .colors-custom .widget_authors a:hover strong, .colors-custom .entry-title a:focus, .colors-custom .entry-title a:hover, .colors-custom .entry-meta a:focus, .colors-custom .entry-meta a:hover, .colors-custom.blog .entry-meta a.post-edit-link:focus, .colors-custom.blog .entry-meta a.post-edit-link:hover, .colors-custom.archive .entry-meta a.post-edit-link:focus, .colors-custom.archive .entry-meta a.post-edit-link:hover, .colors-custom.search .entry-meta a.post-edit-link:focus, .colors-custom.search .entry-meta a.post-edit-link:hover, .colors-custom .page-links a:focus .page-number, .colors-custom .page-links a:hover .page-number, .colors-custom .entry-footer .cat-links a:focus, .colors-custom .entry-footer .cat-links a:hover, .colors-custom .entry-footer .tags-links a:focus, .colors-custom .entry-footer .tags-links a:hover, .colors-custom .post-navigation a:focus, .colors-custom .post-navigation a:hover, .colors-custom .pagination a:not(.prev):not(.next):focus, .colors-custom .pagination a:not(.prev):not(.next):hover, .colors-custom .comments-pagination a:not(.prev):not(.next):focus, .colors-custom .comments-pagination a:not(.prev):not(.next):hover, .colors-custom .logged-in-as a:focus, .colors-custom .logged-in-as a:hover, .colors-custom a:focus .nav-title, .colors-custom a:hover .nav-title, .colors-custom .edit-link a:focus, .colors-custom .edit-link a:hover, .colors-custom .site-info a:focus, .colors-custom .site-info a:hover, .colors-custom .widget .widget-title a:focus, .colors-custom .widget .widget-title a:hover, .colors-custom .widget ul li a:focus, .colors-custom .widget ul li a:hover { -webkit-box-shadow: inset 0 0 0 hsl( ' . $hue . ', ' . $saturation . ', 13% ), 0 3px 0 hsl( ' . $hue . ', ' . $saturation . ', 13% ); box-shadow: inset 0 0 0 hsl( ' . $hue . ', ' . $saturation . ' , 13% ), 0 3px 0 hsl( ' . $hue . ', ' . $saturation . ', 13% ); } body.colors-custom, .colors-custom button, .colors-custom input, .colors-custom select, .colors-custom textarea, .colors-custom h3, .colors-custom h4, .colors-custom h6, .colors-custom label, .colors-custom .entry-title a, .colors-custom.twentyseventeen-front-page .panel-content .recent-posts article, .colors-custom .entry-footer .cat-links a, .colors-custom .entry-footer .tags-links a, .colors-custom .format-quote blockquote, .colors-custom .nav-title, .colors-custom .comment-body, .colors-custom .site-content .wp-playlist-light .wp-playlist-current-item .wp-playlist-item-album { color: hsl( ' . $hue . ', ' . $reduced_saturation . ', 20% ); /* base: #333; */ } .colors-custom .social-navigation a:hover, .colors-custom .social-navigation a:focus { background: hsl( ' . $hue . ', ' . $reduced_saturation . ', 20% ); /* base: #333; */ } .colors-custom input[type="text"]:focus, .colors-custom input[type="email"]:focus, .colors-custom input[type="url"]:focus, .colors-custom input[type="password"]:focus, .colors-custom input[type="search"]:focus, .colors-custom input[type="number"]:focus, .colors-custom input[type="tel"]:focus, .colors-custom input[type="range"]:focus, .colors-custom input[type="date"]:focus, .colors-custom input[type="month"]:focus, .colors-custom input[type="week"]:focus, .colors-custom input[type="time"]:focus, .colors-custom input[type="datetime"]:focus, .colors-custom input[type="datetime-local"]:focus, .colors-custom input[type="color"]:focus, .colors-custom textarea:focus, .bypostauthor > .comment-body > .comment-meta > .comment-author .avatar { border-color: hsl( ' . $hue . ', ' . $reduced_saturation . ', 20% ); /* base: #333; */ } .colors-custom h2, .colors-custom blockquote, .colors-custom input[type="text"], .colors-custom input[type="email"], .colors-custom input[type="url"], .colors-custom input[type="password"], .colors-custom input[type="search"], .colors-custom input[type="number"], .colors-custom input[type="tel"], .colors-custom input[type="range"], .colors-custom input[type="date"], .colors-custom input[type="month"], .colors-custom input[type="week"], .colors-custom input[type="time"], .colors-custom input[type="datetime"], .colors-custom input[type="datetime-local"], .colors-custom input[type="color"], .colors-custom textarea, .colors-custom .site-description, .colors-custom .entry-content blockquote.alignleft, .colors-custom .entry-content blockquote.alignright, .colors-custom .colors-custom .taxonomy-description, .colors-custom .site-info a, .colors-custom .wp-caption, .colors-custom .gallery-caption { color: hsl( ' . $hue . ', ' . $saturation . ', 40% ); /* base: #666; */ } .colors-custom abbr, .colors-custom acronym { border-bottom-color: hsl( ' . $hue . ', ' . $saturation . ', 40% ); /* base: #666; */ } .colors-custom h5, .colors-custom .entry-meta, .colors-custom .entry-meta a, .colors-custom.blog .entry-meta a.post-edit-link, .colors-custom.archive .entry-meta a.post-edit-link, .colors-custom.search .entry-meta a.post-edit-link, .colors-custom .nav-subtitle, .colors-custom .comment-metadata, .colors-custom .comment-metadata a, .colors-custom .no-comments, .colors-custom .comment-awaiting-moderation, .colors-custom .page-numbers.current, .colors-custom .page-links .page-number, .colors-custom .navigation-top .current-menu-item > a, .colors-custom .navigation-top .current_page_item > a, .colors-custom .main-navigation a:hover, .colors-custom .site-content .wp-playlist-light .wp-playlist-current-item .wp-playlist-item-artist { color: hsl( ' . $hue . ', ' . $saturation . ', 46% ); /* base: #767676; */ } .colors-custom :not( .mejs-button ) > button:hover, .colors-custom :not( .mejs-button ) > button:focus, .colors-custom input[type="button"]:hover, .colors-custom input[type="button"]:focus, .colors-custom input[type="submit"]:hover, .colors-custom input[type="submit"]:focus, .colors-custom .entry-footer .edit-link a.post-edit-link:hover, .colors-custom .entry-footer .edit-link a.post-edit-link:focus, .colors-custom .social-navigation a, .colors-custom .prev.page-numbers:focus, .colors-custom .prev.page-numbers:hover, .colors-custom .next.page-numbers:focus, .colors-custom .next.page-numbers:hover, .colors-custom .site-content .wp-playlist-light .wp-playlist-item:hover, .colors-custom .site-content .wp-playlist-light .wp-playlist-item:focus { background: hsl( ' . esc_attr( $hue ) . ', ' . esc_attr( $saturation ) . ', 46% ); /* base: #767676; */ } .colors-custom button.secondary:hover, .colors-custom button.secondary:focus, .colors-custom input[type="reset"]:hover, .colors-custom input[type="reset"]:focus, .colors-custom input[type="button"].secondary:hover, .colors-custom input[type="button"].secondary:focus, .colors-custom input[type="reset"].secondary:hover, .colors-custom input[type="reset"].secondary:focus, .colors-custom input[type="submit"].secondary:hover, .colors-custom input[type="submit"].secondary:focus, .colors-custom hr { background: hsl( ' . $hue . ', ' . $saturation . ', 73% ); /* base: #bbb; */ } .colors-custom input[type="text"], .colors-custom input[type="email"], .colors-custom input[type="url"], .colors-custom input[type="password"], .colors-custom input[type="search"], .colors-custom input[type="number"], .colors-custom input[type="tel"], .colors-custom input[type="range"], .colors-custom input[type="date"], .colors-custom input[type="month"], .colors-custom input[type="week"], .colors-custom input[type="time"], .colors-custom input[type="datetime"], .colors-custom input[type="datetime-local"], .colors-custom input[type="color"], .colors-custom textarea, .colors-custom select, .colors-custom fieldset, .colors-custom .widget .tagcloud a:hover, .colors-custom .widget .tagcloud a:focus, .colors-custom .widget.widget_tag_cloud a:hover, .colors-custom .widget.widget_tag_cloud a:focus, .colors-custom .wp_widget_tag_cloud a:hover, .colors-custom .wp_widget_tag_cloud a:focus { border-color: hsl( ' . $hue . ', ' . $saturation . ', 73% ); /* base: #bbb; */ } .colors-custom thead th { border-bottom-color: hsl( ' . $hue . ', ' . $saturation . ', 73% ); /* base: #bbb; */ } .colors-custom .entry-footer .cat-links .icon, .colors-custom .entry-footer .tags-links .icon { color: hsl( ' . $hue . ', ' . $saturation . ', 73% ); /* base: #bbb; */ } .colors-custom button.secondary, .colors-custom input[type="reset"], .colors-custom input[type="button"].secondary, .colors-custom input[type="reset"].secondary, .colors-custom input[type="submit"].secondary, .colors-custom .prev.page-numbers, .colors-custom .next.page-numbers { background-color: hsl( ' . $hue . ', ' . $saturation . ', 87% ); /* base: #ddd; */ } .colors-custom .widget .tagcloud a, .colors-custom .widget.widget_tag_cloud a, .colors-custom .wp_widget_tag_cloud a { border-color: hsl( ' . $hue . ', ' . $saturation . ', 87% ); /* base: #ddd; */ } .colors-custom.twentyseventeen-front-page article:not(.has-post-thumbnail):not(:first-child), .colors-custom .widget ul li { border-top-color: hsl( ' . $hue . ', ' . $saturation . ', 87% ); /* base: #ddd; */ } .colors-custom .widget ul li { border-bottom-color: hsl( ' . $hue . ', ' . $saturation . ', 87% ); /* base: #ddd; */ } .colors-custom pre, .colors-custom mark, .colors-custom ins { background: hsl( ' . $hue . ', ' . $saturation . ', 93% ); /* base: #eee; */ } .colors-custom .navigation-top, .colors-custom .main-navigation > div > ul, .colors-custom .pagination, .colors-custom .comments-pagination, .colors-custom .entry-footer, .colors-custom .site-footer { border-top-color: hsl( ' . $hue . ', ' . $saturation . ', 93% ); /* base: #eee; */ } .colors-custom .navigation-top, .colors-custom .main-navigation li, .colors-custom .entry-footer, .colors-custom .single-featured-image-header, .colors-custom .site-content .wp-playlist-light .wp-playlist-item, .colors-custom tr { border-bottom-color: hsl( ' . $hue . ', ' . $saturation . ', 93% ); /* base: #eee; */ } .colors-custom .site-content .wp-playlist-light { border-color: hsl( ' . $hue . ', ' . $saturation . ', 93% ); /* base: #eee; */ } .colors-custom .site-header, .colors-custom .single-featured-image-header { background-color: hsl( ' . $hue . ', ' . $saturation . ', 98% ); /* base: #fafafa; */ } .colors-custom button, .colors-custom input[type="button"], .colors-custom input[type="submit"], .colors-custom .entry-footer .edit-link a.post-edit-link, .colors-custom .social-navigation a, .colors-custom .site-content .wp-playlist-light a.wp-playlist-caption:hover, .colors-custom .site-content .wp-playlist-light .wp-playlist-item:hover a, .colors-custom .site-content .wp-playlist-light .wp-playlist-item:focus a, .colors-custom .site-content .wp-playlist-light .wp-playlist-item:hover, .colors-custom .site-content .wp-playlist-light .wp-playlist-item:focus, .colors-custom .prev.page-numbers:focus, .colors-custom .prev.page-numbers:hover, .colors-custom .next.page-numbers:focus, .colors-custom .next.page-numbers:hover, .colors-custom.has-header-image .site-title, .colors-custom.has-header-video .site-title, .colors-custom.has-header-image .site-title a, .colors-custom.has-header-video .site-title a, .colors-custom.has-header-image .site-description, .colors-custom.has-header-video .site-description { color: hsl( ' . $hue . ', ' . $saturation . ', 100% ); /* base: #fff; */ } body.colors-custom, .colors-custom .navigation-top, .colors-custom .main-navigation ul { background: hsl( ' . $hue . ', ' . $saturation . ', 100% ); /* base: #fff; */ } .colors-custom .widget ul li a, .colors-custom .site-footer .widget-area ul li a { -webkit-box-shadow: inset 0 -1px 0 hsl( ' . $hue . ', ' . $saturation . ', 100% ); /* base: rgba(255, 255, 255, 1); */ box-shadow: inset 0 -1px 0 hsl( ' . $hue . ', ' . $saturation . ', 100% ); /* base: rgba(255, 255, 255, 1); */ } .colors-custom .menu-toggle, .colors-custom .menu-toggle:hover, .colors-custom .menu-toggle:focus, .colors-custom .menu .dropdown-toggle, .colors-custom .menu-scroll-down, .colors-custom .menu-scroll-down:hover, .colors-custom .menu-scroll-down:focus { background-color: transparent; } .colors-custom .widget .tagcloud a, .colors-custom .widget .tagcloud a:focus, .colors-custom .widget .tagcloud a:hover, .colors-custom .widget.widget_tag_cloud a, .colors-custom .widget.widget_tag_cloud a:focus, .colors-custom .widget.widget_tag_cloud a:hover, .colors-custom .wp_widget_tag_cloud a, .colors-custom .wp_widget_tag_cloud a:focus, .colors-custom .wp_widget_tag_cloud a:hover, .colors-custom .entry-footer .edit-link a.post-edit-link:focus, .colors-custom .entry-footer .edit-link a.post-edit-link:hover { -webkit-box-shadow: none !important; box-shadow: none !important; } /* Reset non-customizable hover styling for links */ .colors-custom .entry-content a:hover, .colors-custom .entry-content a:focus, .colors-custom .entry-summary a:hover, .colors-custom .entry-summary a:focus, .colors-custom .comment-content a:focus, .colors-custom .comment-content a:hover, .colors-custom .widget a:hover, .colors-custom .widget a:focus, .colors-custom .site-footer .widget-area a:hover, .colors-custom .site-footer .widget-area a:focus, .colors-custom .posts-navigation a:hover, .colors-custom .posts-navigation a:focus, .colors-custom .widget_authors a:hover strong, .colors-custom .widget_authors a:focus strong { -webkit-box-shadow: inset 0 0 0 rgba(0, 0, 0, 0), 0 3px 0 rgba(0, 0, 0, 1); box-shadow: inset 0 0 0 rgba(0, 0, 0, 0), 0 3px 0 rgba(0, 0, 0, 1); } .colors-custom .gallery-item a, .colors-custom .gallery-item a:hover, .colors-custom .gallery-item a:focus { -webkit-box-shadow: none; box-shadow: none; } @media screen and (min-width: 48em) { .colors-custom .nav-links .nav-previous .nav-title .icon, .colors-custom .nav-links .nav-next .nav-title .icon { color: hsl( ' . $hue . ', ' . $saturation . ', 20% ); /* base: #222; */ } .colors-custom .main-navigation li li:hover, .colors-custom .main-navigation li li.focus { background: hsl( ' . $hue . ', ' . $saturation . ', 46% ); /* base: #767676; */ } .colors-custom .navigation-top .menu-scroll-down { color: hsl( ' . $hue . ', ' . $saturation . ', 46% ); /* base: #767676; */; } .colors-custom abbr[title] { border-bottom-color: hsl( ' . $hue . ', ' . $saturation . ', 46% ); /* base: #767676; */; } .colors-custom .main-navigation ul ul { border-color: hsl( ' . $hue . ', ' . $saturation . ', 73% ); /* base: #bbb; */ background: hsl( ' . $hue . ', ' . $saturation . ', 100% ); /* base: #fff; */ } .colors-custom .main-navigation ul li.menu-item-has-children:before, .colors-custom .main-navigation ul li.page_item_has_children:before { border-bottom-color: hsl( ' . $hue . ', ' . $saturation . ', 73% ); /* base: #bbb; */ } .colors-custom .main-navigation ul li.menu-item-has-children:after, .colors-custom .main-navigation ul li.page_item_has_children:after { border-bottom-color: hsl( ' . $hue . ', ' . $saturation . ', 100% ); /* base: #fff; */ } .colors-custom .main-navigation li li.focus > a, .colors-custom .main-navigation li li:focus > a, .colors-custom .main-navigation li li:hover > a, .colors-custom .main-navigation li li a:hover, .colors-custom .main-navigation li li a:focus, .colors-custom .main-navigation li li.current_page_item a:hover, .colors-custom .main-navigation li li.current-menu-item a:hover, .colors-custom .main-navigation li li.current_page_item a:focus, .colors-custom .main-navigation li li.current-menu-item a:focus { color: hsl( ' . $hue . ', ' . $saturation . ', 100% ); /* base: #fff; */ } }'; /** * Filters Twenty Seventeen custom colors CSS. * * @since Twenty Seventeen 1.0 * * @param string $css Base theme colors CSS. * @param int $hue The user's selected color hue. * @param string $saturation Filtered theme color saturation level. */ return apply_filters( 'twentyseventeen_custom_colors_css', $css, $hue, $saturation ); } customizer.php 0000644 00000015352 15231636277 0007503 0 ustar 00 <?php /** * Twenty Seventeen: Customizer * * @package WordPress * @subpackage Twenty_Seventeen * @since Twenty Seventeen 1.0 */ /** * Add postMessage support for site title and description for the Theme Customizer. * * @param WP_Customize_Manager $wp_customize Theme Customizer object. */ function twentyseventeen_customize_register( $wp_customize ) { $wp_customize->get_setting( 'blogname' )->transport = 'postMessage'; $wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage'; $wp_customize->get_setting( 'header_textcolor' )->transport = 'postMessage'; $wp_customize->selective_refresh->add_partial( 'blogname', array( 'selector' => '.site-title a', 'render_callback' => 'twentyseventeen_customize_partial_blogname', ) ); $wp_customize->selective_refresh->add_partial( 'blogdescription', array( 'selector' => '.site-description', 'render_callback' => 'twentyseventeen_customize_partial_blogdescription', ) ); /** * Custom colors. */ $wp_customize->add_setting( 'colorscheme', array( 'default' => 'light', 'transport' => 'postMessage', 'sanitize_callback' => 'twentyseventeen_sanitize_colorscheme', ) ); $wp_customize->add_setting( 'colorscheme_hue', array( 'default' => 250, 'transport' => 'postMessage', 'sanitize_callback' => 'absint', // The hue is stored as a positive integer. ) ); $wp_customize->add_control( 'colorscheme', array( 'type' => 'radio', 'label' => __( 'Color Scheme', 'twentyseventeen' ), 'choices' => array( 'light' => __( 'Light', 'twentyseventeen' ), 'dark' => __( 'Dark', 'twentyseventeen' ), 'custom' => __( 'Custom', 'twentyseventeen' ), ), 'section' => 'colors', 'priority' => 5, ) ); $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'colorscheme_hue', array( 'mode' => 'hue', 'section' => 'colors', 'priority' => 6, ) ) ); /** * Theme options. */ $wp_customize->add_section( 'theme_options', array( 'title' => __( 'Theme Options', 'twentyseventeen' ), 'priority' => 130, // Before Additional CSS. ) ); $wp_customize->add_setting( 'page_layout', array( 'default' => 'two-column', 'sanitize_callback' => 'twentyseventeen_sanitize_page_layout', 'transport' => 'postMessage', ) ); $wp_customize->add_control( 'page_layout', array( 'label' => __( 'Page Layout', 'twentyseventeen' ), 'section' => 'theme_options', 'type' => 'radio', 'description' => __( 'When the two-column layout is assigned, the page title is in one column and content is in the other.', 'twentyseventeen' ), 'choices' => array( 'one-column' => __( 'One Column', 'twentyseventeen' ), 'two-column' => __( 'Two Column', 'twentyseventeen' ), ), 'active_callback' => 'twentyseventeen_is_view_with_layout_option', ) ); /** * Filters the number of front page sections in Twenty Seventeen. * * @since Twenty Seventeen 1.0 * * @param int $num_sections Number of front page sections. */ $num_sections = apply_filters( 'twentyseventeen_front_page_sections', 4 ); // Create a setting and control for each of the sections available in the theme. for ( $i = 1; $i < ( 1 + $num_sections ); $i++ ) { $wp_customize->add_setting( 'panel_' . $i, array( 'default' => false, 'sanitize_callback' => 'absint', 'transport' => 'postMessage', ) ); $wp_customize->add_control( 'panel_' . $i, array( /* translators: %d: The front page section number. */ 'label' => sprintf( __( 'Front Page Section %d Content', 'twentyseventeen' ), $i ), 'description' => ( 1 !== $i ? '' : __( 'Select pages to feature in each area from the dropdowns. Add an image to a section by setting a featured image in the page editor. Empty sections will not be displayed.', 'twentyseventeen' ) ), 'section' => 'theme_options', 'type' => 'dropdown-pages', 'allow_addition' => true, 'active_callback' => 'twentyseventeen_is_static_front_page', ) ); $wp_customize->selective_refresh->add_partial( 'panel_' . $i, array( 'selector' => '#panel' . $i, 'render_callback' => 'twentyseventeen_front_page_section', 'container_inclusive' => true, ) ); } } add_action( 'customize_register', 'twentyseventeen_customize_register' ); /** * Sanitize the page layout options. * * @param string $input Page layout. */ function twentyseventeen_sanitize_page_layout( $input ) { $valid = array( 'one-column' => __( 'One Column', 'twentyseventeen' ), 'two-column' => __( 'Two Column', 'twentyseventeen' ), ); if ( array_key_exists( $input, $valid ) ) { return $input; } return ''; } /** * Sanitize the colorscheme. * * @param string $input Color scheme. */ function twentyseventeen_sanitize_colorscheme( $input ) { $valid = array( 'light', 'dark', 'custom' ); if ( in_array( $input, $valid, true ) ) { return $input; } return 'light'; } /** * Render the site title for the selective refresh partial. * * @since Twenty Seventeen 1.0 * * @see twentyseventeen_customize_register() * * @return void */ function twentyseventeen_customize_partial_blogname() { bloginfo( 'name' ); } /** * Render the site tagline for the selective refresh partial. * * @since Twenty Seventeen 1.0 * * @see twentyseventeen_customize_register() * * @return void */ function twentyseventeen_customize_partial_blogdescription() { bloginfo( 'description' ); } /** * Return whether we're previewing the front page and it's a static page. */ function twentyseventeen_is_static_front_page() { return ( is_front_page() && ! is_home() ); } /** * Return whether we're on a view that supports a one or two column layout. */ function twentyseventeen_is_view_with_layout_option() { // This option is available on all pages. It's also available on archives when there isn't a sidebar. return ( is_page() || ( is_archive() && ! is_active_sidebar( 'sidebar-1' ) ) ); } /** * Bind JS handlers to instantly live-preview changes. */ function twentyseventeen_customize_preview_js() { wp_enqueue_script( 'twentyseventeen-customize-preview', get_theme_file_uri( '/assets/js/customize-preview.js' ), array( 'customize-preview' ), '20161002', true ); } add_action( 'customize_preview_init', 'twentyseventeen_customize_preview_js' ); /** * Load dynamic logic for the customizer controls area. */ function twentyseventeen_panels_js() { wp_enqueue_script( 'twentyseventeen-customize-controls', get_theme_file_uri( '/assets/js/customize-controls.js' ), array(), '20161020', true ); } add_action( 'customize_controls_enqueue_scripts', 'twentyseventeen_panels_js' ); helper-functions.php 0000644 00000006710 15231636277 0010562 0 ustar 00 <?php /** * Common theme functions * * @package WordPress * @subpackage Twenty_Nineteen * @since Twenty Nineteen 1.5 */ /** * Determines if post thumbnail can be displayed. */ function twentynineteen_can_show_post_thumbnail() { return apply_filters( 'twentynineteen_can_show_post_thumbnail', ! post_password_required() && ! is_attachment() && has_post_thumbnail() ); } /** * Returns true if image filters are enabled on the theme options. */ function twentynineteen_image_filters_enabled() { return 0 !== get_theme_mod( 'image_filter', 1 ); } /** * Returns the size for avatars used in the theme. */ function twentynineteen_get_avatar_size() { return 60; } /** * Returns true if comment is by author of the post. * * @see get_comment_class() */ function twentynineteen_is_comment_by_post_author( $comment = null ) { if ( is_object( $comment ) && $comment->user_id > 0 ) { $user = get_userdata( $comment->user_id ); $post = get_post( $comment->comment_post_ID ); if ( ! empty( $user ) && ! empty( $post ) ) { return $comment->user_id === $post->post_author; } } return false; } /** * Returns information about the current post's discussion, with cache support. */ function twentynineteen_get_discussion_data() { static $discussion, $post_id; $current_post_id = get_the_ID(); if ( $current_post_id === $post_id ) { return $discussion; /* If we have discussion information for post ID, return cached object */ } else { $post_id = $current_post_id; } $comments = get_comments( array( 'post_id' => $current_post_id, 'orderby' => 'comment_date_gmt', 'order' => get_option( 'comment_order', 'asc' ), /* Respect comment order from Settings » Discussion. */ 'status' => 'approve', 'number' => 20, /* Only retrieve the last 20 comments, as the end goal is just 6 unique authors */ ) ); $authors = array(); foreach ( $comments as $comment ) { $authors[] = ( (int) $comment->user_id > 0 ) ? (int) $comment->user_id : $comment->comment_author_email; } $authors = array_unique( $authors ); $discussion = (object) array( 'authors' => array_slice( $authors, 0, 6 ), /* Six unique authors commenting on the post. */ 'responses' => get_comments_number( $current_post_id ), /* Number of responses. */ ); return $discussion; } /** * Converts HSL to HEX colors. */ function twentynineteen_hsl_hex( $h, $s, $l, $to_hex = true ) { $h /= 360; $s /= 100; $l /= 100; $r = $l; $g = $l; $b = $l; $v = ( $l <= 0.5 ) ? ( $l * ( 1.0 + $s ) ) : ( $l + $s - $l * $s ); if ( $v > 0 ) { $m = $l + $l - $v; $sv = ( $v - $m ) / $v; $h *= 6.0; $sextant = floor( $h ); $fract = $h - $sextant; $vsf = $v * $sv * $fract; $mid1 = $m + $vsf; $mid2 = $v - $vsf; switch ( $sextant ) { case 0: $r = $v; $g = $mid1; $b = $m; break; case 1: $r = $mid2; $g = $v; $b = $m; break; case 2: $r = $m; $g = $v; $b = $mid1; break; case 3: $r = $m; $g = $mid2; $b = $v; break; case 4: $r = $mid1; $g = $m; $b = $v; break; case 5: $r = $v; $g = $m; $b = $mid2; break; } } $r = round( $r * 255, 0 ); $g = round( $g * 255, 0 ); $b = round( $b * 255, 0 ); if ( $to_hex ) { $r = ( $r < 15 ) ? '0' . dechex( $r ) : dechex( $r ); $g = ( $g < 15 ) ? '0' . dechex( $g ) : dechex( $g ); $b = ( $b < 15 ) ? '0' . dechex( $b ) : dechex( $b ); return "#$r$g$b"; } return "rgb($r, $g, $b)"; } icon-functions.php 0000644 00000016221 15231636277 0010231 0 ustar 00 <?php /** * SVG icons related functions and filters * * @package WordPress * @subpackage Twenty_Seventeen * @since Twenty Seventeen 1.0 */ /** * Add SVG definitions to the footer. */ function twentyseventeen_include_svg_icons() { // Define SVG sprite file. $svg_icons = get_parent_theme_file_path( '/assets/images/svg-icons.svg' ); // If it exists, include it. if ( file_exists( $svg_icons ) ) { require_once $svg_icons; } } add_action( 'wp_footer', 'twentyseventeen_include_svg_icons', 9999 ); /** * Return SVG markup. * * @param array $args { * Parameters needed to display an SVG. * * @type string $icon Required SVG icon filename. * @type string $title Optional SVG title. * @type string $desc Optional SVG description. * } * @return string SVG markup. */ function twentyseventeen_get_svg( $args = array() ) { // Make sure $args are an array. if ( empty( $args ) ) { return __( 'Please define default parameters in the form of an array.', 'twentyseventeen' ); } // Define an icon. if ( false === array_key_exists( 'icon', $args ) ) { return __( 'Please define an SVG icon filename.', 'twentyseventeen' ); } // Set defaults. $defaults = array( 'icon' => '', 'title' => '', 'desc' => '', 'fallback' => false, ); // Parse args. $args = wp_parse_args( $args, $defaults ); // Set aria hidden. $aria_hidden = ' aria-hidden="true"'; // Set ARIA. $aria_labelledby = ''; /* * Twenty Seventeen doesn't use the SVG title or description attributes; non-decorative icons are described with .screen-reader-text. * * However, child themes can use the title and description to add information to non-decorative SVG icons to improve accessibility. * * Example 1 with title: <?php echo twentyseventeen_get_svg( array( 'icon' => 'arrow-right', 'title' => __( 'This is the title', 'textdomain' ) ) ); ?> * * Example 2 with title and description: <?php echo twentyseventeen_get_svg( array( 'icon' => 'arrow-right', 'title' => __( 'This is the title', 'textdomain' ), 'desc' => __( 'This is the description', 'textdomain' ) ) ); ?> * * See https://www.paciellogroup.com/blog/2013/12/using-aria-enhance-svg-accessibility/. */ if ( $args['title'] ) { $aria_hidden = ''; $unique_id = twentyseventeen_unique_id(); $aria_labelledby = ' aria-labelledby="title-' . $unique_id . '"'; if ( $args['desc'] ) { $aria_labelledby = ' aria-labelledby="title-' . $unique_id . ' desc-' . $unique_id . '"'; } } // Begin SVG markup. $svg = '<svg class="icon icon-' . esc_attr( $args['icon'] ) . '"' . $aria_hidden . $aria_labelledby . ' role="img">'; // Display the title. if ( $args['title'] ) { $svg .= '<title id="title-' . $unique_id . '">' . esc_html( $args['title'] ) . '</title>'; // Display the desc only if the title is already set. if ( $args['desc'] ) { $svg .= '<desc id="desc-' . $unique_id . '">' . esc_html( $args['desc'] ) . '</desc>'; } } /* * Display the icon. * * The whitespace around `<use>` is intentional - it is a work around to a keyboard navigation bug in Safari 10. * * See https://core.trac.wordpress.org/ticket/38387. */ $svg .= ' <use href="#icon-' . esc_html( $args['icon'] ) . '" xlink:href="#icon-' . esc_html( $args['icon'] ) . '"></use> '; // Add some markup to use as a fallback for browsers that do not support SVGs. if ( $args['fallback'] ) { $svg .= '<span class="svg-fallback icon-' . esc_attr( $args['icon'] ) . '"></span>'; } $svg .= '</svg>'; return $svg; } /** * Display SVG icons in social links menu. * * @param string $item_output The menu item's starting HTML output. * @param WP_Post $item Menu item data object. * @param int $depth Depth of the menu. Used for padding. * @param stdClass $args An object of wp_nav_menu() arguments. * @return string The menu item output with social icon. */ function twentyseventeen_nav_menu_social_icons( $item_output, $item, $depth, $args ) { // Get supported social icons. $social_icons = twentyseventeen_social_links_icons(); // Change SVG icon inside social links menu if there is supported URL. if ( 'social' === $args->theme_location ) { foreach ( $social_icons as $attr => $value ) { if ( false !== strpos( $item_output, $attr ) ) { $item_output = str_replace( $args->link_after, '</span>' . twentyseventeen_get_svg( array( 'icon' => esc_attr( $value ) ) ), $item_output ); } } } return $item_output; } add_filter( 'walker_nav_menu_start_el', 'twentyseventeen_nav_menu_social_icons', 10, 4 ); /** * Add dropdown icon if menu item has children. * * @param string $title The menu item's title. * @param WP_Post $item The current menu item. * @param stdClass $args An object of wp_nav_menu() arguments. * @param int $depth Depth of menu item. Used for padding. * @return string The menu item's title with dropdown icon. */ function twentyseventeen_dropdown_icon_to_menu_link( $title, $item, $args, $depth ) { if ( 'top' === $args->theme_location ) { foreach ( $item->classes as $value ) { if ( 'menu-item-has-children' === $value || 'page_item_has_children' === $value ) { $title = $title . twentyseventeen_get_svg( array( 'icon' => 'angle-down' ) ); } } } return $title; } add_filter( 'nav_menu_item_title', 'twentyseventeen_dropdown_icon_to_menu_link', 10, 4 ); /** * Returns an array of supported social links (URL and icon name). * * @return array Array of social links icons. */ function twentyseventeen_social_links_icons() { // Supported social links icons. $social_links_icons = array( 'behance.net' => 'behance', 'codepen.io' => 'codepen', 'deviantart.com' => 'deviantart', 'digg.com' => 'digg', 'docker.com' => 'dockerhub', 'dribbble.com' => 'dribbble', 'dropbox.com' => 'dropbox', 'facebook.com' => 'facebook', 'flickr.com' => 'flickr', 'foursquare.com' => 'foursquare', 'plus.google.com' => 'google-plus', 'github.com' => 'github', 'instagram.com' => 'instagram', 'linkedin.com' => 'linkedin', 'mailto:' => 'envelope-o', 'medium.com' => 'medium', 'pinterest.com' => 'pinterest-p', 'pscp.tv' => 'periscope', 'getpocket.com' => 'get-pocket', 'reddit.com' => 'reddit-alien', 'skype.com' => 'skype', 'skype:' => 'skype', 'slideshare.net' => 'slideshare', 'snapchat.com' => 'snapchat-ghost', 'soundcloud.com' => 'soundcloud', 'spotify.com' => 'spotify', 'stumbleupon.com' => 'stumbleupon', 't.me' => 'telegram', 'telegram.me' => 'telegram', 'tumblr.com' => 'tumblr', 'twitch.tv' => 'twitch', 'twitter.com' => 'twitter', 'vimeo.com' => 'vimeo', 'vine.co' => 'vine', 'vk.com' => 'vk', 'wa.me' => 'whatsapp', 'whatsapp.com' => 'whatsapp', 'wordpress.org' => 'wordpress', 'wordpress.com' => 'wordpress', 'yelp.com' => 'yelp', 'youtube.com' => 'youtube', ); /** * Filters Twenty Seventeen social links icons. * * @since Twenty Seventeen 1.0 * * @param array $social_links_icons Array of social links icons. */ return apply_filters( 'twentyseventeen_social_links_icons', $social_links_icons ); } template-functions.php 0000644 00000005027 15231636277 0011116 0 ustar 00 <?php /** * Additional features to allow styling of the templates * * @package WordPress * @subpackage Twenty_Seventeen * @since Twenty Seventeen 1.0 */ /** * Adds custom classes to the array of body classes. * * @param array $classes Classes for the body element. * @return array */ function twentyseventeen_body_classes( $classes ) { // Add class of group-blog to blogs with more than 1 published author. if ( is_multi_author() ) { $classes[] = 'group-blog'; } // Add class of hfeed to non-singular pages. if ( ! is_singular() ) { $classes[] = 'hfeed'; } // Add class if we're viewing the Customizer for easier styling of theme options. if ( is_customize_preview() ) { $classes[] = 'twentyseventeen-customizer'; } // Add class on front page. if ( is_front_page() && 'posts' !== get_option( 'show_on_front' ) ) { $classes[] = 'twentyseventeen-front-page'; } // Add a class if there is a custom header. if ( has_header_image() ) { $classes[] = 'has-header-image'; } // Add class if sidebar is used. if ( is_active_sidebar( 'sidebar-1' ) && ! is_page() ) { $classes[] = 'has-sidebar'; } // Add class for one or two column page layouts. if ( is_page() || is_archive() ) { if ( 'one-column' === get_theme_mod( 'page_layout' ) ) { $classes[] = 'page-one-column'; } else { $classes[] = 'page-two-column'; } } // Add class if the site title and tagline is hidden. if ( 'blank' === get_header_textcolor() ) { $classes[] = 'title-tagline-hidden'; } // Get the colorscheme or the default if there isn't one. $colors = twentyseventeen_sanitize_colorscheme( get_theme_mod( 'colorscheme', 'light' ) ); $classes[] = 'colors-' . $colors; return $classes; } add_filter( 'body_class', 'twentyseventeen_body_classes' ); /** * Count our number of active panels. * * Primarily used to see if we have any panels active, duh. */ function twentyseventeen_panel_count() { $panel_count = 0; /** * Filters the number of front page sections in Twenty Seventeen. * * @since Twenty Seventeen 1.0 * * @param int $num_sections Number of front page sections. */ $num_sections = apply_filters( 'twentyseventeen_front_page_sections', 4 ); // Create a setting and control for each of the sections available in the theme. for ( $i = 1; $i < ( 1 + $num_sections ); $i++ ) { if ( get_theme_mod( 'panel_' . $i ) ) { $panel_count++; } } return $panel_count; } /** * Checks to see if we're on the front page or not. */ function twentyseventeen_is_frontpage() { return ( is_front_page() && ! is_home() ); } custom-header.php 0000644 00000010511 15231755375 0010030 0 ustar 00 <?php /** * Custom header implementation * * @link https://codex.wordpress.org/Custom_Headers * * @package WordPress * @subpackage Twenty_Seventeen * @since Twenty Seventeen 1.0 */ /** * Set up the WordPress core custom header feature. * * @uses twentyseventeen_header_style() */ function twentyseventeen_custom_header_setup() { add_theme_support( 'custom-header', /** * Filters Twenty Seventeen custom-header support arguments. * * @since Twenty Seventeen 1.0 * * @param array $args { * An array of custom-header support arguments. * * @type string $default-image Default image of the header. * @type int $width Width in pixels of the custom header image. Default 954. * @type int $height Height in pixels of the custom header image. Default 1300. * @type string $flex-height Flex support for height of header. * @type string $video Video support for header. * @type string $wp-head-callback Callback function used to styles the header image and text * displayed on the blog. * } */ apply_filters( 'twentyseventeen_custom_header_args', array( 'default-image' => get_parent_theme_file_uri( '/assets/images/header.jpg' ), 'width' => 2000, 'height' => 1200, 'flex-height' => true, 'video' => true, 'wp-head-callback' => 'twentyseventeen_header_style', ) ) ); register_default_headers( array( 'default-image' => array( 'url' => '%s/assets/images/header.jpg', 'thumbnail_url' => '%s/assets/images/header.jpg', 'description' => __( 'Default Header Image', 'twentyseventeen' ), ), ) ); } add_action( 'after_setup_theme', 'twentyseventeen_custom_header_setup' ); if ( ! function_exists( 'twentyseventeen_header_style' ) ) : /** * Styles the header image and text displayed on the blog. * * @see twentyseventeen_custom_header_setup(). */ function twentyseventeen_header_style() { $header_text_color = get_header_textcolor(); // If no custom options for text are set, let's bail. // get_header_textcolor() options: add_theme_support( 'custom-header' ) is default, hide text (returns 'blank') or any hex value. if ( get_theme_support( 'custom-header', 'default-text-color' ) === $header_text_color ) { return; } // If we get this far, we have custom styles. Let's do this. ?> <style id="twentyseventeen-custom-header-styles" type="text/css"> <?php // Has the text been hidden? if ( 'blank' === $header_text_color ) : ?> .site-title, .site-description { position: absolute; clip: rect(1px, 1px, 1px, 1px); } <?php // If the user has set a custom color for the text use that. else : ?> .site-title a, .colors-dark .site-title a, .colors-custom .site-title a, body.has-header-image .site-title a, body.has-header-video .site-title a, body.has-header-image.colors-dark .site-title a, body.has-header-video.colors-dark .site-title a, body.has-header-image.colors-custom .site-title a, body.has-header-video.colors-custom .site-title a, .site-description, .colors-dark .site-description, .colors-custom .site-description, body.has-header-image .site-description, body.has-header-video .site-description, body.has-header-image.colors-dark .site-description, body.has-header-video.colors-dark .site-description, body.has-header-image.colors-custom .site-description, body.has-header-video.colors-custom .site-description { color: #<?php echo esc_attr( $header_text_color ); ?>; } <?php endif; ?> </style> <?php } endif; // End of twentyseventeen_header_style(). /** * Customize video play/pause button in the custom header. * * @param array $settings Video settings. * @return array The filtered video settings. */ function twentyseventeen_video_controls( $settings ) { $settings['l10n']['play'] = '<span class="screen-reader-text">' . __( 'Play background video', 'twentyseventeen' ) . '</span>' . twentyseventeen_get_svg( array( 'icon' => 'play' ) ); $settings['l10n']['pause'] = '<span class="screen-reader-text">' . __( 'Pause background video', 'twentyseventeen' ) . '</span>' . twentyseventeen_get_svg( array( 'icon' => 'pause' ) ); return $settings; } add_filter( 'header_video_settings', 'twentyseventeen_video_controls' ); admin/view/callback/section/items.php 0000644 00000001032 15231770040 0013633 0 ustar 00 <?php /** * Items section * * @package Envato_Market * @since 1.0.0 */ ?> <p><?php esc_html_e( '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.', 'envato-market' ); ?></p> <p><?php esc_html_e( 'Warning: These tokens can be revoked by the account holder at any time.', 'envato-market' ); ?></p> admin/view/callback/section/oauth.php 0000644 00000002737 15231770040 0013647 0 ustar 00 <?php /** * OAuth section * * @package Envato_Market * @since 1.0.0 */ ?> <p> <?php printf( esc_html__( 'This area enables WordPress Theme & Plugin updates from Envato Market. Read more about how this process works at %s.', 'envato-market' ), '<a href="https://envato.com/market-plugin/" target="_blank">' . esc_html__( 'envato.com', 'envato-market' ) . '</a>' ); ?> </p> <p> <?php esc_html_e( 'Please follow the steps below:', 'envato-market' ); ?> </p> <ol> <li><?php printf( esc_html__( 'Generate an Envato API Personal Token by %s.', 'envato-market' ), '<a href="' . envato_market()->admin()->get_generate_token_url() . '" target="_blank">' . esc_html__( 'clicking this link', 'envato-market' ) . '</a>' ); ?></li> <li><?php esc_html_e( 'Name the token eg “My WordPress site”.', 'envato-market' ); ?></li> <li><?php esc_html_e( 'Ensure the following permissions are enabled:', 'envato-market' ); ?> <ul> <li><?php esc_html_e( 'View and search Envato sites', 'envato-market' ); ?></li> <li><?php esc_html_e( 'Download your purchased items', 'envato-market' ); ?></li> <li><?php esc_html_e( 'List purchases you\'ve made', 'envato-market' ); ?></li> </ul> </li> <li><?php esc_html_e( 'Copy the token into the box below.', 'envato-market' ); ?></li> <li><?php esc_html_e( 'Click the "Save Changes" button.', 'envato-market' ); ?></li> <li><?php esc_html_e( 'A list of purchased Themes & Plugins from Envato Market will appear.', 'envato-market' ); ?></li> </ol> admin/view/callback/setting/items.php 0000644 00000003531 15231770040 0013652 0 ustar 00 <?php /** * Items setting * * @package Envato_Market * @since 1.0.0 */ $items = envato_market()->get_option( 'items', array() ); ?> <ul id="envato-market-items"> <?php if ( ! empty( $items ) ) { foreach ( $items as $key => $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 ' <li data-id="' . esc_attr( $item['id'] ) . '" class="' . esc_attr( $class ) . '"> <span class="item-name">' . esc_html__( 'ID', 'envato-market' ) . ': ' . esc_html( $item['id'] ) . ' - ' . esc_html( $item['name'] ) . '</span> <button class="item-delete dashicons dashicons-dismiss"> <span class="screen-reader-text">' . esc_html__( 'Delete', 'envato-market' ) . '</span> </button> <input type="hidden" name="' . esc_attr( envato_market()->get_option_name() ) . '[items][' . esc_attr( $key ) . '][name]" value="' . esc_html( $item['name'] ) . '" /> <input type="hidden" name="' . esc_attr( envato_market()->get_option_name() ) . '[items][' . esc_attr( $key ) . '][token]" value="' . esc_html( $item['token'] ) . '" /> <input type="hidden" name="' . esc_attr( envato_market()->get_option_name() ) . '[items][' . esc_attr( $key ) . '][id]" value="' . esc_html( $item['id'] ) . '" /> <input type="hidden" name="' . esc_attr( envato_market()->get_option_name() ) . '[items][' . esc_attr( $key ) . '][type]" value="' . esc_html( $item['type'] ) . '" /> <input type="hidden" name="' . esc_attr( envato_market()->get_option_name() ) . '[items][' . esc_attr( $key ) . '][authorized]" value="' . esc_html( $item['authorized'] ) . '" /> </li>'; } } ?> </ul> <button class="button add-envato-market-item"><?php esc_html_e( 'Add Item', 'envato-market' ); ?></button> admin/view/callback/setting/token.php 0000644 00000000612 15231770040 0013646 0 ustar 00 <?php /** * Token setting * * @package Envato_Market * @since 1.0.0 */ ?> <input type="text" name="<?php echo esc_attr( envato_market()->get_option_name() ); ?>[token]" class="widefat" value="<?php echo esc_html( envato_market()->get_option( 'token' ) ); ?>" autocomplete="off"> <p class="description"><?php esc_html_e( 'Enter your Envato API Personal Token.', 'envato-market' ); ?></p> admin/view/callback/admin.php 0000644 00000002011 15231770040 0012134 0 ustar 00 <?php /** * Admin UI * * @package Envato_Market * @since 1.0.0 */ if ( isset( $_GET['action'] ) ) { $id = ! empty( $_GET['id'] ) ? absint( trim( $_GET['id'] ) ) : ''; if ( 'install-plugin' === $_GET['action'] ) { Envato_Market_Admin::install_plugin( $id ); } elseif ( 'install-theme' === $_GET['action'] ) { Envato_Market_Admin::install_theme( $id ); } } else { add_thickbox(); ?> <div class="wrap about-wrap full-width-layout"> <?php Envato_Market_Admin::render_intro_partial(); ?> <?php Envato_Market_Admin::render_tabs_partial(); ?> <form method="POST" action="<?php echo esc_url( ENVATO_MARKET_NETWORK_ACTIVATED ? network_admin_url( 'edit.php?action=envato_market_network_settings' ) : admin_url( 'options.php' ) ); ?>"> <?php Envato_Market_Admin::render_themes_panel_partial(); ?> <?php Envato_Market_Admin::render_plugins_panel_partial(); ?> <?php Envato_Market_Admin::render_settings_panel_partial(); ?> <?php Envato_Market_Admin::render_help_panel_partial(); ?> </form> </div> <?php } admin/view/notice/error-details.php 0000644 00000000466 15231770040 0013361 0 ustar 00 <?php /** * Error details * * @package Envato_Market * @since 2.0.2 */ ?> <div class="notice notice-error is-dismissible"> <p><?php printf( '<strong>Additional Error Details:</strong><br/>%s.<br/> %s <br/> %s', esc_html( $title ), esc_html( $message ), esc_html( json_encode( $data ) ) ); ?></p> </div> admin/view/notice/error-http.php 0000644 00000000741 15231770040 0012707 0 ustar 00 <?php /** * Error notice * * @package Envato_Market * @since 2.0.1 */ ?> <div class="notice notice-error is-dismissible"> <p><?php esc_html_e( '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".', 'envato-market' ); ?></p> </div> admin/view/notice/error-missing-zip.php 0000644 00000000645 15231770040 0014204 0 ustar 00 <?php /** * Error notice * * @package Envato_Market * @since 2.0.1 */ ?> <div class="notice notice-error is-dismissible"> <p><?php printf( esc_html__( '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.', 'envato-market' ), '<a href="https://themeforest.net/downloads" target="_blank">downloads page</a>' ); ?></p> </div> admin/view/notice/error-permissions.php 0000644 00000001054 15231770040 0014301 0 ustar 00 <?php /** * Error notice * * @package Envato_Market * @since 2.0.1 */ ?> <div class="notice notice-error is-dismissible"> <p><?php printf( esc_html__( 'Incorrect token permissions, please generate another token or fix the permissions on the existing token.' ) ); ?></p> <p><?php printf( esc_html__( 'Please ensure only the following permissions are enabled: ', 'envato-market' ) ); ?></p> <ol> <?php foreach ( $this->get_required_permissions() as $permission ) { ?> <li><?php echo esc_html( $permission ); ?></li> <?php } ?> </ol> </div> admin/view/notice/error-single-use.php 0000644 00000000424 15231770040 0014001 0 ustar 00 <?php /** * Error notice * * @package Envato_Market * @since 1.0.0 */ ?> <div class="notice notice-error is-dismissible"> <p><?php esc_html_e( 'One or more Single Use OAuth Personal Tokens could not be verified and should be removed.', 'envato-market' ); ?></p> </div> admin/view/notice/error.php 0000644 00000000513 15231770040 0011727 0 ustar 00 <?php /** * Error notice * * @package Envato_Market * @since 1.0.0 */ ?> <div class="notice notice-error is-dismissible"> <p><?php esc_html_e( 'The OAuth Personal Token could not be verified. Please check that the Token has been entered correctly and has the minimum required permissions.', 'envato-market' ); ?></p> </div> admin/view/notice/success-no-items.php 0000644 00000000457 15231770040 0014006 0 ustar 00 <?php /** * Success notice * * @package Envato_Market * @since 1.0.0 */ ?> <div class="notice notice-success is-dismissible"> <p><?php esc_html_e( 'Your OAuth Personal Token has been verified. However, there are no WordPress downloadable items in your account.', 'envato-market' ); ?></p> </div> admin/view/notice/success-single-use.php 0000644 00000000367 15231770040 0014326 0 ustar 00 <?php /** * Success notice * * @package Envato_Market * @since 1.0.0 */ ?> <div class="notice notice-success is-dismissible"> <p><?php esc_html_e( 'All Single Use OAuth Personal Tokens have been verified.', 'envato-market' ); ?></p> </div> admin/view/notice/success.php 0000644 00000000353 15231770040 0012250 0 ustar 00 <?php /** * Success notice * * @package Envato_Market * @since 1.0.0 */ ?> <div class="notice notice-success is-dismissible"> <p><?php esc_html_e( 'Your OAuth Personal Token has been verified.', 'envato-market' ); ?></p> </div> admin/view/partials/help.php 0000644 00000005201 15231770040 0012063 0 ustar 00 <?php /** * Help panel partial * * @package Envato_Market * @since 2.0.1 */ ?> <div id="help" class="panel"> <div class="envato-market-blocks"> <div class="envato-market-block"> <h3>Troubleshooting:</h3> <p>If you’re having trouble with the plugin, please</p> <ol> <li>Confirm the old <code>Envato Toolkit</code> plugin is not installed.</li> <li>Confirm the latest version of WordPress is installed.</li> <li>Confirm the latest version of the <a href="https://envato.com/market-plugin/" target="_blank">Envato Market</a> plugin is installed.</li> <li>Try creating a new API token has from the <a href="<?php echo envato_market()->admin()->get_generate_token_url(); ?>" target="_blank">build.envato.com</a> website - ensure only the following permissions have been granted <ul> <li>View and search Envato sites</li> <li>Download your purchased items</li> <li>List purchases you've made</li> </ul> </li> <li>Check with the hosting provider to ensure the API connection to <code>api.envato.com</code> is not blocked.</li> <li>Check with the hosting provider that the minimum TLS version is 1.2 or above on the server.</li> <li>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.</li> <li>Confirm your Envato account is still active and the items are still visible from <a href="https://themeforest.net/downloads" target="_blank">your downloads page</a>.</li> <li>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.</li> </ol> </div> <div class="envato-market-block"> <h3>Health Check:</h3> <div class="envato-market-healthcheck"> Problem starting healthcheck. Please check javascript console for errors. </div> <h3>Support:</h3> <p>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.</p> <p>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.</p> <p>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. </p> </div> </div> </div> admin/view/partials/intro.php 0000644 00000001671 15231770040 0012275 0 ustar 00 <?php /** * Intro partial * * @package Envato_Market * @since 1.0.0 */ ?> <div class="col"> <h1 class="about-title"><img class="about-logo" src="<?php echo envato_market()->get_plugin_url(); ?>images/envato-market-logo.svg" alt="Envato Market"><sup><?php echo esc_html( envato_market()->get_version() ); ?></sup></h1> <p><?php esc_html_e( 'Welcome!', 'envato-market' ); ?></p> <p><?php esc_html_e( '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.', 'envato-market' ); ?></p> <p><strong><?php printf( esc_html__( 'Find out more at %1$senvato.com%2$s.', 'envato-market' ), '<a href="https://envato.com/market-plugin/" target="_blank">', '</a>' ); ?></strong></p> </div> admin/view/partials/plugins.php 0000644 00000000726 15231770040 0012623 0 ustar 00 <?php /** * Plugins panel partial * * @package Envato_Market * @since 1.0.0 */ $plugins = envato_market()->items()->plugins( 'purchased' ); ?> <div id="plugins" class="panel <?php echo empty( $plugins ) ? 'hidden' : ''; ?>"> <div class="envato-market-blocks"> <?php if ( ! empty( $plugins ) ) { envato_market_plugins_column( 'active' ); envato_market_plugins_column( 'installed' ); envato_market_plugins_column( 'install' ); } ?> </div> </div> admin/view/partials/settings.php 0000644 00000001760 15231770040 0013001 0 ustar 00 <?php /** * Settings panel partial * * @package Envato_Market * @since 1.0.0 */ $token = envato_market()->get_option( 'token' ); $items = envato_market()->get_option( 'items', array() ); ?> <div id="settings" class="panel"> <div class="envato-market-blocks"> <?php settings_fields( envato_market()->get_slug() ); ?> <?php Envato_Market_Admin::do_settings_sections( envato_market()->get_slug(), 2 ); ?> </div> <p class="submit"> <input type="submit" name="submit" id="submit" class="button button-primary" value="<?php esc_html_e( 'Save Changes', 'envato-market' ); ?>" /> <?php if ( ( '' !== $token || ! empty( $items ) ) && 10 !== has_action( 'admin_notices', array( $this, 'error_notice' ) ) ) { ?> <a href="<?php echo esc_url( add_query_arg( array( 'authorization' => 'check' ), envato_market()->get_page_url() ) ); ?>" class="button button-secondary auth-check-button" style="margin:0 5px"><?php esc_html_e( 'Test API Connection', 'envato-market' ); ?></a> <?php } ?> </p> </div> admin/view/partials/tabs.php 0000644 00000002724 15231770040 0012073 0 ustar 00 <?php /** * Tabs partial * * @package Envato_Market * @since 1.0.0 */ $tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : ''; $themes = envato_market()->items()->themes( 'purchased' ); $plugins = envato_market()->items()->plugins( 'purchased' ); ?> <h2 class="nav-tab-wrapper"> <?php // Themes tab. $theme_class = array(); if ( ! empty( $themes ) ) { if ( empty( $tab ) ) { $tab = 'themes'; } if ( 'themes' === $tab ) { $theme_class[] = 'nav-tab-active'; } } else { $theme_class[] = 'hidden'; } echo '<a href="#themes" data-id="theme" class="nav-tab ' . esc_attr( implode( ' ', $theme_class ) ) . '">' . esc_html__( 'Themes', 'envato-market' ) . '</a>'; // Plugins tab. $plugin_class = array(); if ( ! empty( $plugins ) ) { if ( empty( $tab ) ) { $tab = 'plugins'; } if ( 'plugins' === $tab ) { $plugin_class[] = 'nav-tab-active'; } } else { $plugin_class[] = 'hidden'; } echo '<a href="#plugins" data-id="plugin" class="nav-tab ' . esc_attr( implode( ' ', $plugin_class ) ) . '">' . esc_html__( 'Plugins', 'envato-market' ) . '</a>'; // Settings tab. echo '<a href="#settings" class="nav-tab ' . esc_attr( 'settings' === $tab || empty( $tab ) ? 'nav-tab-active' : '' ) . '">' . esc_html__( 'Settings', 'envato-market' ) . '</a>'; // Help tab. echo '<a href="#help" class="nav-tab ' . esc_attr( 'help' === $tab ? 'nav-tab-active' : '' ) . '">' . esc_html__( 'Help', 'envato-market' ) . '</a>'; ?> </h2> admin/view/partials/themes.php 0000644 00000000715 15231770040 0012425 0 ustar 00 <?php /** * Themes panel partial * * @package Envato_Market * @since 1.0.0 */ $themes = envato_market()->items()->themes( 'purchased' ); ?> <div id="themes" class="panel <?php echo empty( $themes ) ? 'hidden' : ''; ?>"> <div class="envato-market-blocks"> <?php if ( ! empty( $themes ) ) { envato_market_themes_column( 'active' ); envato_market_themes_column( 'installed' ); envato_market_themes_column( 'install' ); } ?> </div> </div> admin/class-envato-market-admin.php 0000644 00000161130 15231770040 0013314 0 ustar 00 <?php /** * Admin UI class. * * @package Envato_Market */ if ( ! class_exists( 'Envato_Market_Admin' ) && class_exists( 'Envato_Market' ) ) : /** * Creates an admin page to save the Envato API OAuth token. * * @class Envato_Market_Admin * @version 1.0.0 * @since 1.0.0 */ class Envato_Market_Admin { /** * Action nonce. * * @type string */ const AJAX_ACTION = 'envato_market'; /** * The single class instance. * * @since 1.0.0 * @access private * * @var object */ private static $_instance = null; /** * Main Envato_Market_Admin Instance * * Ensures only one instance of this class exists in memory at any one time. * * @return object The one true Envato_Market_Admin. * @codeCoverageIgnore * @uses Envato_Market_Admin::init_actions() Setup hooks and actions. * * @since 1.0.0 * @static * @see Envato_Market_Admin() */ public static function instance() { if ( is_null( self::$_instance ) ) { self::$_instance = new self(); self::$_instance->init_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 icon. add_action( 'admin_head', array( $this, 'add_menu_icon' ) ); // 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'; ?> <div class="<?php echo esc_attr( $class ); ?>"> <?php if ( ! empty( $section['title'] ) ) { echo '<h3>' . esc_html( $section['title'] ) . '</h3>' . "\n"; } if ( ! empty( $section['callback'] ) ) { call_user_func( $section['callback'], $section ); } ?> <table class="form-table"> <?php do_settings_fields( $page, $section['id'] ); ?> </table> </div> <?php } } /** * Add a font based menu icon * * @since 1.0.0 */ public function add_menu_icon() { // Fonts directory URL. $fonts_dir_url = envato_market()->get_plugin_url() . 'fonts/'; // Create font styles. $style = '<style type="text/css"> /*<![CDATA[*/ @font-face { font-family: "envato-market"; src:url("' . $fonts_dir_url . 'envato-market.eot?20150626"); src:url("' . $fonts_dir_url . 'envato-market.eot?#iefix20150626") format("embedded-opentype"), url("' . $fonts_dir_url . 'envato-market.woff?20150626") format("woff"), url("' . $fonts_dir_url . 'envato-market.ttf?20150626") format("truetype"), url("' . $fonts_dir_url . 'envato-market.svg?20150626#envato") format("svg"); font-weight: normal; font-style: normal; } #adminmenu .toplevel_page_' . envato_market()->get_slug() . ' .menu-icon-generic div.wp-menu-image:before { font: normal 20px/1 "envato-market" !important; content: "\e600"; speak: none; padding: 6px 0; height: 34px; width: 20px; display: inline-block; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-transition: all .1s ease-in-out; -moz-transition: all .1s ease-in-out; transition: all .1s ease-in-out; } /*]]>*/ </style>'; // Remove space after colons. $style = str_replace( ': ', ':', $style ); // Remove whitespace. echo str_replace( array( "\r\n", "\r", "\n", "\t", ' ', ' ', ' ', ' ', ' ' ), '', $style ); } /** * Adds the menu. * * @since 1.0.0 */ public function add_menu_page() { if ( ENVATO_MARKET_NETWORK_ACTIVATED && ! is_super_admin() ) { // we do not want to show a menu item for people who do not have permission. return; } $page = add_menu_page( __( 'Envato Market', 'envato-market' ), __( 'Envato Market', 'envato-market' ), 'manage_options', envato_market()->get_slug(), array( $this, 'render_admin_callback', ) ); // 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() { ?> <script type="text/html" id="tmpl-envato-market-auth-check-button"> <a href="<?php echo esc_url( add_query_arg( array( 'authorization' => 'check' ), envato_market()->get_page_url() ) ); ?>" class="button button-secondary auth-check-button" style="margin:0 5px"><?php esc_html_e( 'Test API Connection', 'envato-market' ); ?></a> </script> <script type="text/html" id="tmpl-envato-market-item"> <li data-id="{{ data.id }}"> <span class="item-name"><?php esc_html_e( 'ID', 'envato-market' ); ?> : {{ data.id }} - {{ data.name }}</span> <button class="item-delete dashicons dashicons-dismiss"> <span class="screen-reader-text"><?php esc_html_e( 'Delete', 'envato-market' ); ?></span> </button> <input type="hidden" name="<?php echo esc_attr( envato_market()->get_option_name() ); ?>[items][{{ data.key }}][name]" value="{{ data.name }}"/> <input type="hidden" name="<?php echo esc_attr( envato_market()->get_option_name() ); ?>[items][{{ data.key }}][token]" value="{{ data.token }}"/> <input type="hidden" name="<?php echo esc_attr( envato_market()->get_option_name() ); ?>[items][{{ data.key }}][id]" value="{{ data.id }}"/> <input type="hidden" name="<?php echo esc_attr( envato_market()->get_option_name() ); ?>[items][{{ data.key }}][type]" value="{{ data.type }}"/> <input type="hidden" name="<?php echo esc_attr( envato_market()->get_option_name() ); ?>[items][{{ data.key }}][authorized]" value="{{ data.authorized }}"/> </li> </script> <script type="text/html" id="tmpl-envato-market-dialog-remove"> <div id="envato-market-dialog-remove" title="<?php esc_html_e( 'Remove Item', 'envato-market' ); ?>"> <p><?php esc_html_e( 'You are about to remove the connection between the Envato Market API and this item. You cannot undo this action.', 'envato-market' ); ?></p> </div> </script> <script type="text/html" id="tmpl-envato-market-dialog-form"> <div id="envato-market-dialog-form" title="<?php esc_html_e( 'Add Item', 'envato-market' ); ?>"> <form> <fieldset> <label for="token"><?php esc_html_e( 'Token', 'envato-market' ); ?></label> <input type="text" name="token" class="widefat" value=""/> <p class="description"><?php esc_html_e( 'Enter the Envato API Personal Token.', 'envato-market' ); ?></p> <label for="id"><?php esc_html_e( 'Item ID', 'envato-market' ); ?></label> <input type="text" name="id" class="widefat" value=""/> <p class="description"><?php esc_html_e( 'Enter the Envato Item ID.', 'envato-market' ); ?></p> <input type="submit" tabindex="-1" style="position:absolute; top:-5000px"/> </fieldset> </form> </div> </script> <script type="text/html" id="tmpl-envato-market-dialog-error"> <div class="notice notice-error"> <p>{{ data.message }}</p> </div> </script> <script type="text/html" id="tmpl-envato-market-card"> <div class="envato-market-block" data-id="{{ data.id }}"> <div class="envato-card {{ data.type }}"> <div class="envato-card-top"> <a href="{{ data.url }}" class="column-icon"> <img src="{{ data.thumbnail_url }}"/> </a> <div class="column-name"> <h4> <a href="{{ data.url }}">{{ data.name }}</a> <span class="version" aria-label="<?php esc_attr_e( 'Version %s', 'envato-market' ); ?>"><?php esc_html_e( 'Version', 'envato-market' ); ?> {{ data.version }}</span> </h4> </div> <div class="column-description"> <div class="description"> <p>{{ data.description }}</p> </div> <p class="author"> <cite><?php esc_html_e( 'By', 'envato-market' ); ?> {{ data.author }}</cite> </p> </div> </div> <div class="envato-card-bottom"> <div class="column-actions"> <a href="{{{ data.install }}}" class="button button-primary"> <span aria-hidden="true"><?php esc_html_e( 'Install', 'envato-market' ); ?></span> <span class="screen-reader-text"><?php esc_html_e( 'Install', 'envato-market' ); ?> {{ data.name }}</span> </a> </div> </div> </div> </div> </script> <?php } /** * Registers the settings. * * @since 1.0.0 */ public function register_settings() { // Setting. register_setting( envato_market()->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() { $response = envato_market()->api()->request( 'https://api.envato.com/v1/market/total-items.json' ); $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() { $response = envato_market()->api()->request( 'https://api.envato.com/whoami' ); $notice = 'success'; 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' ) { $api_url = 'https://api.envato.com/v2/market/buyer/list-purchases?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 = ' <div class="wrap"> <h1>' . __( 'Installing Plugin...', 'envato-market' ) . '</h1> <p>' . __( 'You do not have sufficient permissions to install plugins on this site.', 'envato-market' ) . '</p> <a href="' . esc_url( 'admin.php?page=' . envato_market()->get_slug() . '&tab=plugins' ) . '">' . __( 'Return to Plugin Installer', 'envato-market' ) . '</a> </div>'; 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 = ' <div class="wrap"> <h1>' . __( 'Installing Plugin...', 'envato-market' ) . '</h1> <p>' . __( 'An error occurred, please check that the item ID is correct.', 'envato-market' ) . '</p> <a href="' . esc_url( 'admin.php?page=' . envato_market()->get_slug() . '&tab=plugins' ) . '">' . __( 'Return to Plugin Installer', 'envato-market' ) . '</a> </div>'; 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 = ' <div class="wrap"> <h1>' . __( 'Installing Theme...', 'envato-market' ) . '</h1> <p>' . __( 'You do not have sufficient permissions to install themes on this site.', 'envato-market' ) . '</p> <a href="' . esc_url( 'admin.php?page=' . envato_market()->get_slug() . '&tab=themes' ) . '">' . __( 'Return to Theme Installer', 'envato-market' ) . '</a> </div>'; 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 = ' <div class="wrap"> <h1>' . __( 'Installing Theme...', 'envato-market' ) . '</h1> <p>' . __( 'An error occurred, please check that the item ID is correct.', 'envato-market' ) . '</p> <a href="' . esc_url( 'admin.php?page=' . envato_market()->get_slug() . '&tab=themes' ) . '">' . __( 'Return to Plugin Installer', 'envato-market' ) . '</a> </div>'; 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' ) ) ); } $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' ) ) ); } $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' ); } $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 $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; admin/class-envato-market-theme-installer-skin.php 0000644 00000011106 15231770040 0016260 0 ustar 00 <?php /** * Upgrader skin classes. * * @package Envato_Market */ // Include the WP_Upgrader_Skin class. if ( ! class_exists( 'WP_Upgrader_Skin', false ) ) : include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader-skins.php'; endif; if ( ! class_exists( 'Envato_Market_Theme_Installer_Skin' ) ) : /** * Theme Installer Skin. * * @class Envato_Market_Theme_Installer_Skin * @version 1.0.0 * @since 1.0.0 */ class Envato_Market_Theme_Installer_Skin extends Theme_Installer_Skin { /** * Modify the install actions. * * @since 1.0.0 */ public function after() { if ( empty( $this->upgrader->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'] = '<a href="' . wp_customize_url( $stylesheet ) . '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview', 'envato-market' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview “%s”', 'envato-market' ), $name ) . '</span></a>'; } if ( is_multisite() ) { if ( current_user_can( 'manage_network_themes' ) ) { $install_actions['network_enable'] = '<a href="' . esc_url( network_admin_url( wp_nonce_url( 'themes.php?action=enable&theme=' . urlencode( $stylesheet ) . '&paged=1&s', 'enable-theme_' . $stylesheet ) ) ) . '" target="_parent">' . __( 'Network Enable', 'envato-market' ) . '</a>'; } } $install_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate', 'envato-market' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate “%s”', 'envato-market' ), $name ) . '</span></a>'; $install_actions['themes_page'] = '<a href="' . esc_url( admin_url( 'admin.php?page=' . envato_market()->get_slug() . '&tab=themes' ) ) . '" target="_parent">' . __( 'Return to Theme Installer', 'envato-market' ) . '</a>'; 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'] = '<a href="' . esc_url( wp_nonce_url( 'plugins.php?action=activate&plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) ) . '" target="_parent">' . __( 'Activate Plugin', 'envato-market' ) . '</a>'; } if ( is_multisite() ) { unset( $install_actions['activate_plugin'] ); if ( current_user_can( 'manage_network_plugins' ) ) { $install_actions['network_activate'] = '<a href="' . esc_url( network_admin_url( wp_nonce_url( 'plugins.php?action=activate&plugin=' . urlencode( $plugin_file ), 'activate-plugin_' . $plugin_file ) ) ) . '" target="_parent">' . __( 'Network Activate', 'envato-market' ) . '</a>'; } } $install_actions['plugins_page'] = '<a href="' . esc_url( admin_url( 'admin.php?page=' . envato_market()->get_slug() . '&tab=plugins' ) ) . '" target="_parent">' . __( 'Return to Plugin Installer', 'envato-market' ) . '</a>'; 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; admin/class-envato-market-theme-upgrader.php 0000644 00000003723 15231770040 0015140 0 ustar 00 <?php /** * Theme Upgrader class. * * @package Envato_Market */ // Include the WP_Upgrader class. if ( ! class_exists( 'WP_Upgrader', false ) ) : include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; endif; if ( ! class_exists( 'Envato_Market_Theme_Upgrader' ) ) : /** * Extends the WordPress Theme_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_Theme_Upgrader extends Theme_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; 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; admin/functions.php 0000644 00000037743 15231770040 0010372 0 ustar 00 <?php /** * Functions * * @package Envato_Market */ /** * Interate over the themes array and displays each theme. * * @since 1.0.0 * * @param string $group The theme group. Options are 'purchased', 'active', 'installed', or 'install'. */ function envato_market_themes_column( $group = 'install' ) { $premium = envato_market()->items()->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( '<a class="update-now" href="%1$s" aria-label="%2$s" data-name="%3$s %5$s" data-slug="%4$s" data-version="%5$s">%6$s</a>', 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( '<a href="%1$s" class="details" title="%2$s" target="_blank">%3$s</a>', 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'] = '<a href="' . esc_url( $customize_url ) . '" class="button button-primary load-customize hide-if-no-customize"><span aria-hidden="true">' . __( 'Customize', 'envato-market' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Customize “%s”', 'envato-market' ), $name ) . '</span></a>'; } 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'] = '<a href="' . esc_url( network_admin_url( wp_nonce_url( 'themes.php?action=enable&theme=' . urlencode( $slug ) . '&paged=1&s', 'enable-theme_' . $slug ) ) ) . '" class="button"><span aria-hidden="true">' . __( 'Network Enable', 'envato-market' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Network Enable “%s”', 'envato-market' ), $name ) . '</span></a>'; } } // @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'] = '<a href="' . esc_url( $activate_link ) . '" class="button"><span aria-hidden="true">' . __( 'Activate', 'envato-market' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate “%s”', 'envato-market' ), $name ) . '</span></a>'; // 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'] = '<a href="' . esc_url( $preview_url ) . '" class="button button-primary load-customize hide-if-no-customize"><span aria-hidden="true">' . __( 'Live Preview', 'envato-market' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview “%s”', 'envato-market' ), $name ) . '</span></a>'; } } } 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'] = ' <a href="' . wp_nonce_url( $install_link, 'install-theme_' . $theme['id'] ) . '" class="button button-primary"> <span aria-hidden="true">' . __( 'Install', 'envato-market' ) . '</span> <span class="screen-reader-text">' . sprintf( __( 'Install %s', 'envato-market' ), $name ) . '</span> </a>'; } if ( 0 === strrpos( html_entity_decode( $author ), '<a ' ) ) { $author_link = $author; } else { $author_link = '<a href="' . esc_url( $author_url ) . '">' . esc_html( $author ) . '</a>'; } ?> <div class="envato-market-block" data-id="<?php echo esc_attr( $theme['id'] ); ?>"> <div class="<?php echo esc_attr( implode( ' ', $classes ) ); ?>"> <div class="envato-card-top"> <a href="<?php echo esc_url( $url ); ?>" class="column-icon"> <img src="<?php echo esc_url( $theme['thumbnail_url'] ); ?>"/> </a> <div class="column-name"> <h4> <a href="<?php echo esc_url( $url ); ?>"><?php echo esc_html( $name ); ?></a> <span class="version" aria-label="<?php esc_attr_e( 'Version %s', 'envato-market' ); ?>"> <?php echo esc_html( sprintf( __( 'Version %s', 'envato-market' ), $version ) ); ?> </span> </h4> </div> <div class="column-description"> <div class="description"> <?php echo wp_kses_post( wpautop( strip_tags( $description ) ) ); ?> </div> <p class="author"> <cite> <?php esc_html_e( 'By', 'envato-market' ); ?> <?php echo wp_kses_post( $author_link ); ?> </cite> </p> </div> <?php if ( ! empty( $update_actions ) ) { ?> <div class="column-update"> <?php echo implode( "\n", $update_actions ); ?> </div> <?php } ?> </div> <div class="envato-card-bottom"> <div class="column-rating"> <?php if ( ! empty( $theme['rating'] ) ) { if ( is_array( $theme['rating'] ) ) { $count = ! empty( $theme['rating']['count'] ) ? $theme['rating']['count'] : 0; $rating = ! empty( $theme['rating']['rating'] ) ? (int) $theme['rating']['rating'] : 0; wp_star_rating( array( 'rating' => $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', ) ); } } ?> </div> <div class="column-actions"> <?php echo implode( "\n", $actions ); ?> </div> </div> </div> </div> <?php endforeach; } /** * Interate over the plugins array and displays each plugin. * * @since 1.0.0 * * @param string $group The plugin group. Options are 'purchased', 'active', 'installed', or 'install'. */ function envato_market_plugins_column( $group = 'install' ) { $premium = envato_market()->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( '<a class="update-now" href="%1$s" aria-label="%2$s" data-name="%3$s %6$s" data-plugin="%4$s" data-slug="%5$s" data-version="%6$s">%7$s</a>', 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( '<a href="%1$s" class="thickbox details" title="%2$s">%3$s</a>', 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'] = ' <a href="' . wp_nonce_url( $deactivate_link, 'deactivate-plugin_' . $slug ) . '" class="button"> <span aria-hidden="true">' . __( 'Deactivate', 'envato-market' ) . '</span> <span class="screen-reader-text">' . sprintf( __( 'Deactivate %s', 'envato-market' ), $name ) . '</span> </a>'; } 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'] = ' <a href="' . wp_nonce_url( $delete_link, 'bulk-plugins' ) . '" class="button-delete"> <span aria-hidden="true">' . __( 'Delete', 'envato-market' ) . '</span> <span class="screen-reader-text">' . sprintf( __( 'Delete %s', 'envato-market' ), $name ) . '</span> </a>'; } 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'] = ' <a href="' . wp_nonce_url( $activate_link, 'activate-plugin_' . $slug ) . '" class="button"> <span aria-hidden="true">' . __( 'Activate', 'envato-market' ) . '</span> <span class="screen-reader-text">' . sprintf( __( 'Activate %s', 'envato-market' ), $name ) . '</span> </a>'; } // @codeCoverageIgnoreStart // Multisite needs special attention. if ( is_multisite() ) { if ( current_user_can( 'manage_network_plugins' ) ) { $actions['network_activate'] = ' <a href="' . esc_url( network_admin_url( wp_nonce_url( 'plugins.php?action=activate&plugin=' . urlencode( $slug ), 'activate-plugin_' . $slug ) ) ) . '" class="button"> <span aria-hidden="true">' . __( 'Network Activate', 'envato-market' ) . '</span> <span class="screen-reader-text">' . sprintf( __( 'Network Activate %s', 'envato-market' ), $name ) . '</span> </a>'; } } // @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'] = ' <a href="' . wp_nonce_url( $install_link, 'install-plugin_' . $plugin['id'] ) . '" class="button button-primary"> <span aria-hidden="true">' . __( 'Install', 'envato-market' ) . '</span> <span class="screen-reader-text">' . sprintf( __( 'Install %s', 'envato-market' ), $name ) . '</span> </a>'; } if ( 0 === strrpos( html_entity_decode( $author ), '<a ' ) ) { $author_link = $author; } else { $author_link = '<a href="' . esc_url( $author_url ) . '">' . esc_html( $author ) . '</a>'; } ?> <div class="envato-market-block" data-id="<?php echo esc_attr( $plugin['id'] ); ?>"> <div class="<?php echo esc_attr( implode( ' ', $classes ) ); ?>"> <div class="envato-card-top"> <a href="<?php echo esc_url( $url ); ?>" class="column-icon"> <img src="<?php echo esc_url( $plugin['thumbnail_url'] ); ?>"/> </a> <div class="column-name"> <h4> <a href="<?php echo esc_url( $url ); ?>"><?php echo esc_html( $name ); ?></a> <span class="version" aria-label="<?php esc_attr_e( 'Version %s', 'envato-market' ); ?>"> <?php echo esc_html( sprintf( __( 'Version %s', 'envato-market' ), ( isset( $plugins[ $slug ] ) ? $plugins[ $slug ]['Version'] : $version ) ) ); ?> </span> </h4> </div> <div class="column-description"> <div class="description"> <?php echo wp_kses_post( wpautop( strip_tags( $description ) ) ); ?> </div> <p class="author"> <cite> <?php esc_html_e( 'By', 'envato-market' ); ?> <?php echo wp_kses_post( $author_link ); ?> </cite> </p> </div> <?php if ( ! empty( $update_actions ) ) { ?> <div class="column-update"> <?php echo implode( "\n", $update_actions ); ?> </div> <?php } ?> </div> <div class="envato-card-bottom"> <div class="column-rating"> <?php if ( ! empty( $plugin['rating'] ) ) { if ( is_array( $plugin['rating'] ) && ! empty( $plugin['rating']['count'] ) ) { wp_star_rating( array( 'rating' => $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', ) ); } } ?> </div> <div class="column-actions"> <?php echo implode( "\n", $actions ); ?> </div> </div> </div> </div> <?php endforeach; } class-envato-market-api.php 0000644 00000032563 15231770040 0011714 0 ustar 00 <?php /** * Envato API class. * * @package Envato_Market */ if ( ! class_exists( 'Envato_Market_API' ) && class_exists( 'Envato_Market' ) ) : /** * Creates the Envato API connection. * * @class Envato_Market_API * @version 1.0.0 * @since 1.0.0 */ class Envato_Market_API { /** * The single class instance. * * @since 1.0.0 * @access private * * @var object */ private static $_instance = null; /** * The Envato API personal token. * * @since 1.0.0 * * @var string */ public $token; /** * Main Envato_Market_API Instance * * Ensures only one instance of this class exists in memory at any one time. * * @see Envato_Market_API() * @uses Envato_Market_API::init_globals() Setup class globals. * @uses Envato_Market_API::init_actions() Setup hooks and actions. * * @since 1.0.0 * @static * @return object The one true Envato_Market_API. * @codeCoverageIgnore */ public static function instance() { if ( is_null( self::$_instance ) ) { self::$_instance = new self(); self::$_instance->init_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( 'headers' => array( 'Authorization' => 'Bearer ' . $this->token, 'User-Agent' => 'WordPress - Envato Market ' . envato_market()->get_version(), ), 'timeout' => 14, ); $args = wp_parse_args( $args, $defaults ); $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; } $url = 'https://api.envato.com/v2/market/buyer/download?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() ) { $url = 'https://api.envato.com/v2/market/catalog/item?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(); $url = 'https://api.envato.com/v2/market/buyer/list-purchases?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(); $url = 'https://api.envato.com/v2/market/buyer/list-purchases?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; } /** * 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 ); } } endif; class-envato-market-github.php 0000644 00000023041 15231770040 0012414 0 ustar 00 <?php /** * Envato Market Github class. * * @package Envato_Market */ if ( ! class_exists( 'Envato_Market_Github' ) ) : /** * Creates the connection between Github to install & update the Envato Market plugin. * * @class Envato_Market_Github * @version 1.0.0 * @since 1.0.0 */ class Envato_Market_Github { /** * Action nonce. * * @type string */ const AJAX_ACTION = 'envato_market_dismiss_notice'; /** * The single class instance. * * @since 1.0.0 * @access private * * @var object */ private static $_instance = null; /** * The API URL. * * @since 1.0.0 * @access private * * @var string */ private static $api_url = 'https://envato.github.io/wp-envato-market/dist/update-check.json'; /** * The Envato_Market_Items Instance * * Ensures only one instance of this class exists in memory at any one time. * * @see Envato_Market_Github() * @uses Envato_Market_Github::init_actions() Setup hooks and actions. * * @since 1.0.0 * @static * @return object The one true Envato_Market_Github. * @codeCoverageIgnore */ public static function instance() { if ( is_null( self::$_instance ) ) { self::$_instance = new self(); self::$_instance->init_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' ), '<a href="' . esc_url( $activate_url ) . '">', '</a>' ); } 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' ), '<a href="' . esc_url( wp_nonce_url( $install_url, 'install-plugin_' . $slug ) ) . '">', '</a>' ); } if ( isset( $message ) ) { ?> <div class="updated envato-market-notice notice is-dismissible"> <p><?php echo wp_kses_post( $message ); ?></p> </div> <script> jQuery( document ).ready( function( $ ) { $( document ).on( 'click', '.envato-market-notice .notice-dismiss', function() { $.ajax( { url: ajaxurl, data: { action: '<?php echo self::AJAX_ACTION; ?>', nonce: '<?php echo wp_create_nonce( self::AJAX_ACTION ); ?>' } } ); } ); } ); </script> <?php } } /** * Dismiss admin notice. * * @since 1.0.0 */ public function dismiss_notice() { check_ajax_referer( self::AJAX_ACTION, 'nonce' ); 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; class-envato-market-items.php 0000644 00000041417 15231770040 0012262 0 ustar 00 <?php /** * Items class. * * @package Envato_Market */ if ( ! class_exists( 'Envato_Market_Items' ) ) : /** * Creates the theme & plugin arrays & injects API results. * * @class Envato_Market_Items * @version 1.0.0 * @since 1.0.0 */ class Envato_Market_Items { /** * The single class instance. * * @since 1.0.0 * @access private * * @var object */ private static $_instance = null; /** * Premium themes. * * @since 1.0.0 * @access private * * @var array */ private static $themes = array(); /** * Premium plugins. * * @since 1.0.0 * @access private * * @var array */ private static $plugins = array(); /** * WordPress plugins. * * @since 1.0.0 * @access private * * @var array */ private static $wp_plugins = array(); /** * The Envato_Market_Items Instance * * Ensures only one instance of this class exists in memory at any one time. * * @see Envato_Market_Items() * @uses Envato_Market_Items::init_actions() Setup hooks and actions. * * @since 1.0.0 * @static * @return object The one true Envato_Market_Items. * @codeCoverageIgnore */ public static function instance() { if ( is_null( self::$_instance ) ) { self::$_instance = new self(); self::$_instance->init_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 ) { self::$themes = get_site_transient( envato_market()->get_option_name() . '_themes' ); if ( false === 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() ) { self::$plugins = get_site_transient( envato_market()->get_option_name() . '_plugins' ); if ( false === 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; class-envato-market.php 0000644 00000023164 15231770040 0011142 0 ustar 00 <?php /** * Envato Market class. * * @package Envato_Market */ if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } if ( ! class_exists( 'Envato_Market' ) ) : /** * It's the main class that does all the things. * * @class Envato_Market * @version 1.0.0 * @since 1.0.0 */ final class Envato_Market { /** * The single class instance. * * @since 1.0.0 * @access private * * @var object */ private static $_instance = null; /** * Plugin data. * * @since 1.0.0 * @access private * * @var object */ private $data; /** * The slug. * * @since 1.0.0 * @access private * * @var string */ private $slug; /** * The version number. * * @since 1.0.0 * @access private * * @var string */ private $version; /** * The web URL to the plugin directory. * * @since 1.0.0 * @access private * * @var string */ private $plugin_url; /** * The server path to the plugin directory. * * @since 1.0.0 * @access private * * @var string */ private $plugin_path; /** * The web URL to the plugin admin page. * * @since 1.0.0 * @access private * * @var string */ private $page_url; /** * The setting option name. * * @since 1.0.0 * @access private * * @var string */ private $option_name; /** * Main Envato_Market Instance * * Ensures only one instance of this class exists in memory at any one time. * * @see Envato_Market() * @uses Envato_Market::init_globals() Setup class globals. * @uses Envato_Market::init_includes() Include required files. * @uses Envato_Market::init_actions() Setup hooks and actions. * * @since 1.0.0 * @static * @return Envato_Market. * @codeCoverageIgnore */ public static function instance() { if ( is_null( self::$_instance ) ) { self::$_instance = new self(); self::$_instance->init_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; } /** * 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(); } } endif;
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.01 |
proxy
|
phpinfo
|
Settings