Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 74
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
ThemeInstaller
0.00% covered (danger)
0.00%
0 / 74
0.00% covered (danger)
0.00%
0 / 8
812
0.00% covered (danger)
0.00%
0 / 1
 install
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
42
 install_from_zip
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
110
 is_nfd_slug
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 get_theme_stylesheet
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 get_theme_type
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 is_theme_installed
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 is_theme_active
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 exists
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2namespace NewfoldLabs\WP\Module\Installer\Services;
3
4use NewfoldLabs\WP\Module\Installer\Data\Themes;
5
6/**
7 * Class ThemeInstaller.
8 */
9class ThemeInstaller {
10
11    /**
12     * Install a whitelisted Theme based on the activation status.
13     *
14     * @param string  $theme Theme URL from Themes.php.
15     * @param boolean $activate Whether to activate the theme after install.
16     * @return \WP_REST_Response|\WP_Error
17     */
18    public static function install( $theme, $activate ) {
19        $theme_list = Themes::get();
20
21        // Checks if the theme slug is an nfd slug.
22        if ( self::is_nfd_slug( $theme ) ) {
23            // Retrieve the theme stylesheet to determine if it has been already installed.
24            $stylesheet = $theme_list['nfd_slugs'][ $theme ]['stylesheet'];
25            // Check if the theme already exists.
26            if ( ! ( \wp_get_theme( $stylesheet ) )->exists() ) {
27                $status = self::install_from_zip(
28                    $theme_list['nfd_slugs'][ $theme ]['url'],
29                    $activate,
30                    $stylesheet
31                );
32                if ( \is_wp_error( $status ) ) {
33                    return $status;
34                }
35
36                return new \WP_REST_Response(
37                    array(),
38                    201
39                );
40            }
41
42            // If specified then activate the theme even if it already installed.
43            if ( $activate && ( ( \wp_get_theme() )->get( 'TextDomain' ) !== $stylesheet ) ) {
44                $status = \switch_theme( $stylesheet );
45            }
46        }
47
48        return new \WP_REST_Response(
49            array(),
50            201
51        );
52    }
53
54    /**
55     * Install theme from an custom zip url if not already installed. Activate and switch to the theme, if specified.
56     *
57     * @param string  $url The ZIP URL to install the theme from.
58     * @param boolean $activate Whether to activate the plugin after install.
59     * @param string  $stylesheet Theme Stylesheet Name.
60     * @return \WP_REST_Response|\WP_Error
61     */
62    public static function install_from_zip( $url, $activate, $stylesheet ) {
63        require_once ABSPATH . 'wp-admin/includes/file.php';
64        require_once ABSPATH . 'wp-admin/includes/misc.php';
65        require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
66
67        $skin     = new \WP_Ajax_Upgrader_Skin();
68        $upgrader = new \Theme_Upgrader( $skin );
69        $result   = $upgrader->install( $url );
70
71        if ( is_wp_error( $result ) ) {
72            return $result;
73        }
74
75        if ( is_wp_error( $skin->result ) ) {
76            return $skin->result;
77        }
78
79        if ( $skin->get_errors()->has_errors() ) {
80            return new \WP_Error(
81                'unable_to_install_theme',
82                $skin->get_error_messages(),
83                array( 'status' => 500 )
84            );
85        }
86
87        if ( is_null( $result ) ) {
88            // Pass through the error from WP_Filesystem if one was raised.
89            if ( $wp_filesystem instanceof \WP_Filesystem_Base
90            && \is_wp_error( $wp_filesystem->errors ) && $wp_filesystem->errors->has_errors()
91            ) {
92                return new \WP_Error(
93                    'unable_to_connect_to_filesystem',
94                    $wp_filesystem->errors->get_error_message(),
95                    array( 'status' => 500 )
96                );
97            }
98
99            return new \WP_Error(
100                'unable_to_connect_to_filesystem',
101                'Unable to connect to the filesystem.',
102                array( 'status' => 500 )
103            );
104        }
105
106        // Activate the theme if specified.
107        if ( $activate && ( ( \wp_get_theme() )->get( 'TextDomain' ) !== $stylesheet ) ) {
108            \switch_theme( $stylesheet );
109        }
110
111        return new \WP_REST_Response(
112            array(),
113            201
114        );
115    }
116
117    /**
118     * Checks if a given slug is a valid nfd_slug. Ref: includes/Data/Themes.php for nfd_slug.
119     *
120     * @param string $theme Slug of the theme.
121     * @return boolean
122     */
123    public static function is_nfd_slug( $theme ) {
124        $theme_list = Themes::get();
125        if ( isset( $theme_list['nfd_slugs'][ $theme ]['approved'] ) ) {
126            return true;
127        }
128        return false;
129    }
130
131    /**
132     * Retrieve Theme Stylesheet Name for a specified theme name and theme type.
133     *
134     * @param mixed $theme Slug of the theme present under includes/Data/Themes.php.
135     * @param mixed $theme_type Type of theme Ref: includes/Data/Themes.php for types of theme slugs.
136     * @return string|boolean
137     */
138    public static function get_theme_stylesheet( $theme, $theme_type ) {
139        $theme_list = Themes::get();
140        return isset( $theme_list[ $theme_type ][ $theme ]['stylesheet'] ) ? $theme_list[ $theme_type ][ $theme ]['stylesheet'] : false;
141    }
142
143    /**
144     * Retrieve Theme Type - approved NFD Slug/WP Slug.
145     *
146     * @param string $theme Theme name
147     * @return string Type of theme. Ref: includes/Data/Themes.php for the different types.
148     */
149    public static function get_theme_type( $theme ) {
150        if ( self::is_nfd_slug( $theme ) ) {
151            return 'nfd_slugs';
152        }
153        return 'wp_slugs';
154    }
155
156    /**
157     * Determines if a theme has already been installed.
158     *
159     * @param string $stylesheet The stylesheet of the theme.
160     * @return boolean
161     */
162    public static function is_theme_installed( $stylesheet ) {
163        return ( \wp_get_theme( $stylesheet ) )->exists();
164    }
165
166    /**
167     * Determines if a theme is already active.
168     *
169     * @param string $stylesheet The stylesheet of the theme.
170     * @return boolean
171     */
172    public static function is_theme_active( $stylesheet ) {
173        return ( ( \wp_get_theme() )->get( 'TextDomain' ) ) === $stylesheet;
174    }
175
176    /**
177     * Checks if a theme with the given slug and activation criteria already exists.
178     *
179     * @param string $theme Theme name
180     * @param string $activate Activation Criteria
181     * @return boolean
182     */
183    public static function exists( $theme, $activate ) {
184        $theme_type       = self::get_theme_type( $theme );
185        $theme_stylesheet = self::get_theme_stylesheet( $theme, $theme_type );
186        if ( ! self::is_theme_installed( $theme_stylesheet ) ) {
187            return false;
188        }
189        if ( $activate && ! self::is_theme_active( $theme_stylesheet ) ) {
190            return false;
191        }
192        return true;
193    }
194}