Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.16% covered (success)
92.16%
47 / 51
66.67% covered (warning)
66.67%
4 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
Column
92.16% covered (success)
92.16%
47 / 51
66.67% covered (warning)
66.67%
4 / 6
16.12
0.00% covered (danger)
0.00%
0 / 1
 init
90.00% covered (success)
90.00%
9 / 10
0.00% covered (danger)
0.00%
0 / 1
4.02
 renderColumnsHead
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 renderColumnsContent
85.00% covered (success)
85.00%
17 / 20
0.00% covered (danger)
0.00%
0 / 1
6.12
 makeColumnSortable
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setSortQuery
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getSortQueryArgs
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5/**
6 * BeyondWords Posts Column.
7 *
8 * @package Beyondwords\Wordpress
9 * @author  Stuart McAlpine <stu@beyondwords.io>
10 * @since   3.0.0
11 */
12
13namespace Beyondwords\Wordpress\Component\Posts\Column;
14
15use Beyondwords\Wordpress\Component\Post\PostMetaUtils;
16use Beyondwords\Wordpress\Component\Settings\SettingsUtils;
17use Beyondwords\Wordpress\Core\CoreUtils;
18
19/**
20 * Column
21 *
22 * @since 3.0.0
23 */
24class Column
25{
26    public const OUTPUT_YES = '<span class="dashicons dashicons-yes"></span> ';
27
28    public const OUTPUT_NO = '—';
29
30    public const OUTPUT_DISABLED = ' <span class="beyondwords--disabled">Disabled</span>';
31
32    public const OUTPUT_ERROR_PREFIX = '<span class="dashicons dashicons-warning"></span> ';
33
34    /**
35     * Init.
36     *
37     * @since 4.0.0
38     * @since 4.5.0 Make BeyondWords column sortable via the pre_get_posts query.
39     */
40    public function init()
41    {
42        add_action('wp_loaded', function () {
43            $postTypes = SettingsUtils::getCompatiblePostTypes();
44
45            if (is_array($postTypes)) {
46                foreach ($postTypes as $postType) {
47                    add_filter("manage_{$postType}_posts_columns", array($this, 'renderColumnsHead'));
48                    add_action("manage_{$postType}_posts_custom_column", array($this, 'renderColumnsContent'), 10, 2);
49                    add_filter("manage_edit-{$postType}_sortable_columns", array($this, 'makeColumnSortable'));
50                }
51            }
52        });
53
54        if (CoreUtils::isEditScreen()) {
55            add_action('pre_get_posts', array($this, 'setSortQuery'));
56        }
57    }
58
59    /**
60     * Add a custom column with player status.
61     *
62     * @since 3.0.0
63     *
64     * @param array $columns Array of <td> headers
65     *
66     * @return array
67     **/
68    public function renderColumnsHead($columns)
69    {
70        return array_merge($columns, array(
71            'beyondwords' => __('BeyondWords', 'speechkit'),
72        ));
73    }
74
75    /**
76     * Render ✗|✓ in Posts list, under the BeyondWords column.
77     *
78     * @since 3.0.0
79     *
80     * @param string $columnName Column name
81     * @param int    $postId     Post ID
82     *
83     * @return void
84     **/
85    public function renderColumnsContent($columnName, $postId)
86    {
87        if ($columnName !== 'beyondwords') {
88            return;
89        }
90
91        $postTypes = SettingsUtils::getCompatiblePostTypes();
92
93        if (empty($postTypes)) {
94            return;
95        }
96
97        $errorMessage = PostMetaUtils::getErrorMessage($postId);
98        $contentId    = PostMetaUtils::getContentId($postId);
99        $disabled     = PostMetaUtils::getDisabled($postId);
100
101        $allowedTags = array(
102            'span' => array(
103                'class'   => array(),
104            ),
105        );
106
107        if (! empty($errorMessage)) {
108            echo wp_kses(self::OUTPUT_ERROR_PREFIX . $errorMessage, $allowedTags);
109        } elseif (empty($contentId)) {
110            echo wp_kses(self::OUTPUT_NO, $allowedTags);
111        } else {
112            echo wp_kses(self::OUTPUT_YES, $allowedTags);
113        }
114
115        if (! empty($disabled)) {
116            echo wp_kses(self::OUTPUT_DISABLED, $allowedTags);
117        }
118    }
119
120    /**
121     * Make the BeyondWords column sortable.
122     *
123     * @since 4.5.1
124     *
125     * @param array $sortableColumns An array of sortable columns.
126     *
127     * @return array The adjusted array of sortable columns.
128     **/
129    public function makeColumnSortable($sortableColumns)
130    {
131        // Make column 'beyondwords' sortable
132        $sortableColumns['beyondwords'] = 'beyondwords';
133
134        return $sortableColumns;
135    }
136
137    /**
138     * Set the query to sort by BeyondWords fields.
139     *
140     * @since 4.5.1
141     *
142     * @param WP_Query $query WordPress query.
143     *
144     * @return $query WP_Query
145     */
146    public function setSortQuery($query)
147    {
148        $orderBy = $query->get('orderby');
149
150        if ($orderBy === 'beyondwords' && $query->is_main_query()) {
151            $query->set('meta_query', $this->getSortQueryArgs());
152            $query->set('orderby', 'meta_value_num date');
153        }
154
155        return $query;
156    }
157
158    /**
159     * Get the sort search query args.
160     *
161     * @since 4.5.1
162     *
163     * @param array $sortableColumns An array of sortable columns.
164     *
165     * @return array
166     */
167    public function getSortQueryArgs()
168    {
169        return [
170            'relation' => 'OR',
171            [
172                'key' => 'beyondwords_generate_audio',
173                'compare' => 'NOT EXISTS',
174            ],
175            [
176                'key' => 'beyondwords_generate_audio',
177                'compare' => 'EXISTS',
178            ],
179        ];
180    }
181}