Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
56.25% covered (warning)
56.25%
45 / 80
33.33% covered (danger)
33.33%
6 / 18
CRAP
0.00% covered (danger)
0.00%
0 / 1
Jetpack_Social
57.69% covered (warning)
57.69%
45 / 78
33.33% covered (danger)
33.33%
6 / 18
103.77
0.00% covered (danger)
0.00%
0 / 1
 __construct
86.05% covered (warning)
86.05%
37 / 43
0.00% covered (danger)
0.00%
0 / 1
3.02
 do_init
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 is_publicize_active
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_plugin_version
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 refresh_plan_data
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 has_paid_plan
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 is_supported_post
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 should_enqueue_block_editor_scripts
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
20
 plugin_settings_page
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 plugin_activation
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 is_connected
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 do_plugin_activation_activities
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
3
 redirect_after_activation
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 activate_module
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 social_filter_available_modules
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 can_use_analytics
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 add_settings_link
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 add_shares_shortcode
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Primary class file for the Jetpack Social plugin.
4 *
5 * @package automattic/jetpack-social-plugin
6 */
7
8if ( ! defined( 'ABSPATH' ) ) {
9    exit( 0 );
10}
11
12use Automattic\Jetpack\Connection\Manager as Connection_Manager;
13use Automattic\Jetpack\Connection\Rest_Authentication as Connection_Rest_Authentication;
14use Automattic\Jetpack\Current_Plan;
15use Automattic\Jetpack\Modules;
16use Automattic\Jetpack\My_Jetpack\Initializer as My_Jetpack_Initializer;
17use Automattic\Jetpack\Publicize\Social_Admin_Page;
18use Automattic\Jetpack\Status;
19use Automattic\Jetpack\Terms_Of_Service;
20use Automattic\Jetpack\Tracking;
21
22/**
23 * Class Jetpack_Social
24 *
25 * @phan-constructor-used-for-side-effects
26 */
27class Jetpack_Social {
28    const JETPACK_PUBLICIZE_MODULE_SLUG    = 'publicize';
29    const JETPACK_SOCIAL_ACTIVATION_OPTION = JETPACK_SOCIAL_PLUGIN_SLUG . '_activated';
30
31    /**
32     * The connection manager used to check if we have a Jetpack connection.
33     *
34     * @var Connection_Manager
35     */
36    private $manager = null;
37
38    /**
39     * Constructor.
40     *
41     * @param Connection_Manager $connection_manager The Jetpack connection manager to use.
42     */
43    public function __construct( $connection_manager = null ) {
44        // Set up the REST authentication hooks.
45        Connection_Rest_Authentication::init();
46
47        // Init Jetpack packages.
48        add_action(
49            'plugins_loaded',
50            function () {
51                $config = new Automattic\Jetpack\Config();
52                // Connection package.
53                $config->ensure(
54                    'connection',
55                    array(
56                        'slug'     => JETPACK_SOCIAL_PLUGIN_SLUG,
57                        'name'     => JETPACK_SOCIAL_PLUGIN_NAME,
58                        'url_info' => JETPACK_SOCIAL_PLUGIN_URI,
59                    )
60                );
61                // Sync package.
62                $config->ensure( 'sync' );
63
64                // Identity crisis package.
65                $config->ensure( 'identity_crisis' );
66
67                if ( ! $this->is_connected() ) {
68                    return;
69                }
70
71                // Publicize package.
72                $config->ensure(
73                    'publicize',
74                    array(
75                        'force_refresh' => true,
76                    )
77                );
78            },
79            1
80        );
81
82        Social_Admin_Page::init();
83
84        add_action( 'init', array( $this, 'do_init' ) );
85
86        // Activate the module as the plugin is activated.
87        add_action( 'admin_init', array( $this, 'do_plugin_activation_activities' ) );
88        add_action( 'activated_plugin', array( $this, 'redirect_after_activation' ) );
89
90        add_action( 'jetpack_heartbeat', array( $this, 'refresh_plan_data' ) );
91
92        add_action(
93            'plugins_loaded',
94            function () {
95                My_Jetpack_Initializer::init();
96            }
97        );
98
99        $this->manager = $connection_manager ? $connection_manager : new Connection_Manager();
100
101        // Add REST routes.
102        add_action( 'rest_api_init', array( new Automattic\Jetpack\Social\REST_Settings_Controller(), 'register_rest_routes' ) );
103
104        // Add meta tags.
105        add_action( 'wp_head', array( new Automattic\Jetpack\Social\Meta_Tags(), 'render_tags' ) );
106
107        add_filter( 'jetpack_get_available_standalone_modules', array( $this, 'social_filter_available_modules' ), 10, 1 );
108
109        add_filter( 'plugin_action_links_' . JETPACK_SOCIAL_PLUGIN_FOLDER . '/jetpack-social.php', array( $this, 'add_settings_link' ) );
110
111        add_shortcode( 'jp_shares_shortcode', array( $this, 'add_shares_shortcode' ) );
112    }
113
114    /**
115     * Initialize the parts of the plugin that have to be initialized later than
116     * plugins_loaded is firing. This includes translated strings.
117     */
118    public function do_init() {
119        ( new Automattic\Jetpack\Social\Note() )->init();
120    }
121
122    /**
123     * Check if we have a paid Jetpack Social plan.
124     */
125    /**
126     * Check if the Publicize module is active.
127     *
128     * @return bool
129     */
130    public static function is_publicize_active() {
131        return ( new Modules() )->is_active( self::JETPACK_PUBLICIZE_MODULE_SLUG );
132    }
133
134    /**
135     * Get the version number of the plugin.
136     *
137     * @return string
138     */
139    public function get_plugin_version() {
140        $plugin_data    = get_plugin_data( JETPACK_SOCIAL_PLUGIN_ROOT_FILE );
141        $plugin_version = $plugin_data['Version'];
142
143        return ! empty( $plugin_version ) ? $plugin_version : '';
144    }
145
146    /**
147     * Refresh plan data.
148     */
149    public function refresh_plan_data() {
150        Current_Plan::refresh_from_wpcom();
151    }
152
153    /**
154     * Returns a boolean as to whether we have a plan that supports
155     * sharing beyond the free limit.
156     *
157     * It also caches the result to make sure that we don't call the API
158     * more than once a request.
159     *
160     * @return boolean True if the site has a plan that supports a higher share limit.
161     */
162    public function has_paid_plan() {
163        static $has_plan = null;
164        if ( null === $has_plan ) {
165            $has_plan = Current_Plan::supports( 'social-shares-1000', true );
166        }
167        return $has_plan;
168    }
169
170    /**
171     * Checks to see if the current post supports Publicize
172     *
173     * @return boolean True if Publicize is supported
174     */
175    public function is_supported_post() {
176        $post_type = get_post_type();
177        return ! empty( $post_type ) && post_type_supports( $post_type, 'publicize' );
178    }
179
180    /**
181     * Checks that we're connected, Publicize is active and that we're editing a post that supports it.
182     *
183     * @return boolean True if the criteria are met.
184     */
185    public function should_enqueue_block_editor_scripts() {
186        return is_admin() && $this->is_connected() && self::is_publicize_active() && $this->is_supported_post();
187    }
188
189    /**
190     * Main plugin settings page.
191     */
192    public function plugin_settings_page() {
193        ?>
194            <div id="jetpack-social-root"></div>
195        <?php
196    }
197
198    /**
199     * Activate the Publicize module on plugin activation.
200     *
201     * @static
202     */
203    public static function plugin_activation() {
204        add_option( self::JETPACK_SOCIAL_ACTIVATION_OPTION, true );
205    }
206
207    /**
208     * Helper to check that we have a Jetpack connection.
209     */
210    private function is_connected() {
211        return $this->manager->is_connected() && $this->manager->has_connected_user();
212    }
213
214    /**
215     * Runs on admin_init, and does actions required on plugin activation, based on
216     * the activation option.
217     *
218     * This needs to be run after the activation hook, as that results in a redirect,
219     * and we need the sync module's actions and filters to be registered.
220     */
221    public function do_plugin_activation_activities() {
222        if ( get_option( self::JETPACK_SOCIAL_ACTIVATION_OPTION ) && $this->is_connected() ) {
223            $this->activate_module();
224        }
225    }
226
227    /**
228     * Redirect to the plugin settings page after activation.
229     *
230     * @param string $plugin Path to the plugin file relative to the plugins directory.
231     */
232    public function redirect_after_activation( $plugin ) {
233        if (
234            JETPACK_SOCIAL_PLUGIN_ROOT_FILE_RELATIVE_PATH === $plugin &&
235            ( new \Automattic\Jetpack\Paths() )->is_current_request_activating_plugin_from_plugins_screen( JETPACK_SOCIAL_PLUGIN_ROOT_FILE_RELATIVE_PATH )
236        ) {
237            wp_safe_redirect( esc_url( admin_url( 'admin.php?page=' . JETPACK_SOCIAL_PLUGIN_SLUG ) ) );
238            exit( 0 );
239        }
240    }
241
242    /**
243     * Activates the Publicize module and disables the activation option
244     */
245    public function activate_module() {
246        delete_option( self::JETPACK_SOCIAL_ACTIVATION_OPTION );
247        ( new Modules() )->activate( self::JETPACK_PUBLICIZE_MODULE_SLUG, false, false );
248    }
249
250    /**
251     * Adds module to the list of available modules
252     *
253     * @param array $modules The available modules.
254     * @return array
255     */
256    public function social_filter_available_modules( $modules ) {
257        return array_merge( array( self::JETPACK_PUBLICIZE_MODULE_SLUG ), $modules );
258    }
259
260    /**
261     * Returns whether we are in condition to track to use
262     * Analytics functionality like Tracks, MC, or GA.
263     */
264    public static function can_use_analytics() {
265        $status     = new Status();
266        $connection = new Connection_Manager();
267        $tracking   = new Tracking( 'jetpack', $connection );
268
269        return $tracking->should_enable_tracking( new Terms_Of_Service(), $status );
270    }
271
272    /**
273     * Add a link to the admin page from the plugins page.
274     *
275     * @param array $actions The plugin actions.
276     * @return array
277     */
278    public function add_settings_link( $actions ) {
279        return array_merge(
280            array( '<a href="' . esc_url( admin_url( 'admin.php?page=' . JETPACK_SOCIAL_PLUGIN_SLUG ) ) . '">' . __( 'Settings', 'jetpack-social' ) . '</a>' ),
281            $actions
282        );
283    }
284
285    /**
286     * Adds the shares shortcode.
287     */
288    public function add_shares_shortcode() {
289        return Social_Shares::get_the_social_shares( get_the_ID() );
290    }
291}