diff options
Diffstat (limited to 'src/Taxonomy.php')
-rw-r--r-- | src/Taxonomy.php | 376 |
1 files changed, 376 insertions, 0 deletions
diff --git a/src/Taxonomy.php b/src/Taxonomy.php new file mode 100644 index 0000000..a7aca5b --- /dev/null +++ b/src/Taxonomy.php @@ -0,0 +1,376 @@ +<?php + +namespace PostTypes; + +use PostTypes\Columns; + +/** + * Taxonomy + */ +class Taxonomy +{ + /** + * The names passed to the Taxonomy + * @var mixed + */ + public $names; + + /** + * The Taxonomy name + * @var string + */ + public $name; + + /** + * The singular label for the Taxonomy + * @var string + */ + public $singular; + + /** + * The plural label for the Taxonomy + * @var string + */ + public $plural; + + /** + * The Taxonomy slug + * @var string + */ + public $slug; + + /** + * Custom options for the Taxonomy + * @var array + */ + public $options; + + /** + * Custom labels for the Taxonomy + * @var array + */ + public $labels; + + /** + * PostTypes to register the Taxonomy to + * @var array + */ + public $posttypes = []; + + /** + * The column manager for the Taxonomy + * @var mixed + */ + public $columns; + + /** + * Create a Taxonomy + * @param mixed $names The name(s) for the Taxonomy + */ + public function __construct($names, $options = [], $labels = []) + { + $this->names($names); + + $this->options($options); + + $this->labels($labels); + } + + /** + * Set the names for the Taxonomy + * @param mixed $names The name(s) for the Taxonomy + * @return $this + */ + public function names($names) + { + if (is_string($names)) { + $names = ['name' => $names]; + } + + $this->names = $names; + + // create names for the Taxonomy + $this->createNames(); + + return $this; + } + + /** + * Set options for the Taxonomy + * @param array $options + * @return $this + */ + public function options(array $options = []) + { + $this->options = $options; + + return $this; + } + + /** + * Set the Taxonomy labels + * @param array $labels + * @return $this + */ + public function labels(array $labels = []) + { + $this->labels = $labels; + + return $this; + } + + /** + * Assign a PostType to register the Taxonomy to + * @param mixed $posttypes + * @return $this + */ + public function posttype($posttypes) + { + $posttypes = is_string($posttypes) ? [$posttypes] : $posttypes; + + foreach ($posttypes as $posttype) { + $this->posttypes[] = $posttype; + } + + return $this; + } + + /** + * Get the Column Manager for the Taxonomy + * @return Columns + */ + public function columns() + { + if (!isset($this->columns)) { + $this->columns = new Columns; + } + + return $this->columns; + } + + /** + * Register the Taxonomy to WordPress + * @return void + */ + public function register() + { + // register the taxonomy, set priority to 9 + // so taxonomies are registered before PostTypes + add_action('init', [$this, 'registerTaxonomy'], 9); + + // assign taxonomy to post type objects + add_action('init', [$this, 'registerTaxonomyToObjects']); + + if (isset($this->columns)) { + // modify the columns for the Taxonomy + add_filter("manage_edit-{$this->name}_columns", [$this, 'modifyColumns']); + + // populate the columns for the Taxonomy + add_filter("manage_{$this->name}_custom_column", [$this, 'populateColumns'], 10, 3); + + // set custom sortable columns + add_filter("manage_edit-{$this->name}_sortable_columns", [$this, 'setSortableColumns']); + + // run action that sorts columns on request + add_action('parse_term_query', [$this, 'sortSortableColumns']); + } + } + + /** + * Register the Taxonomy to WordPress + * @return void + */ + public function registerTaxonomy() + { + // Get the existing taxonomy options if it exists. + $options = (taxonomy_exists($this->name)) ? (array) get_taxonomy($this->name) : []; + + // create options for the Taxonomy. + $options = array_replace_recursive($options, $this->createOptions()); + + // register the Taxonomy with WordPress. + register_taxonomy($this->name, null, $options); + } + + /** + * Register the Taxonomy to PostTypes + * @return void + */ + public function registerTaxonomyToObjects() + { + // register Taxonomy to each of the PostTypes assigned + if (!empty($this->posttypes)) { + foreach ($this->posttypes as $posttype) { + register_taxonomy_for_object_type($this->name, $posttype); + } + } + } + + /** + * Create names for the Taxonomy + * @return void + */ + public function createNames() + { + $required = [ + 'name', + 'singular', + 'plural', + 'slug', + ]; + + foreach ($required as $key) { + // if the name is set, assign it + if (isset($this->names[$key])) { + $this->$key = $this->names[$key]; + continue; + } + + // if the key is not set and is singular or plural + if (in_array($key, ['singular', 'plural'])) { + // create a human friendly name + $name = ucwords(strtolower(str_replace(['-', '_'], ' ', $this->names['name']))); + } + + if ($key === 'slug') { + // create a slug friendly name + $name = strtolower(str_replace([' ', '_'], '-', $this->names['name'])); + } + + // if is plural or slug, append an 's' + if (in_array($key, ['plural', 'slug'])) { + $name .= 's'; + } + + // asign the name to the PostType property + $this->$key = $name; + } + } + + /** + * Create options for Taxonomy + * @return array Options to pass to register_taxonomy + */ + public function createOptions() + { + // default options + $options = [ + 'hierarchical' => true, + 'show_admin_column' => true, + 'rewrite' => [ + 'slug' => $this->slug, + ], + ]; + + // replace defaults with the options passed + $options = array_replace_recursive($options, $this->options); + + // create and set labels + if (!isset($options['labels'])) { + $options['labels'] = $this->createLabels(); + } + + return $options; + } + + /** + * Create labels for the Taxonomy + * @return array + */ + public function createLabels() + { + // default labels + $labels = [ + 'name' => $this->plural, + 'singular_name' => $this->singular, + 'menu_name' => $this->plural, + 'all_items' => "Alle {$this->plural}", + 'edit_item' => "{$this->singular} bearbeiten", + 'view_item' => "{$this->singular} anschauen", + 'update_item' => "{$this->singular} aktualisieren", + 'add_new_item' => "{$this->singular} hinzufügen", + 'new_item_name' => "Neuer {$this->singular} Name", + 'parent_item' => "Übergeordnete {$this->plural}", + 'parent_item_colon' => "Übergeordnete {$this->plural}:", + 'search_items' => "{$this->plural} suchen", + 'popular_items' => "Häufig genutzte {$this->plural}", + 'separate_items_with_commas' => "Trenne {$this->plural} mit Komma", + 'add_or_remove_items' => "{$this->plural} hinzufügen oder entfernen", + 'choose_from_most_used' => "Wählen aus den meistgenutzten {$this->plural}", + 'not_found' => "Keine {$this->plural} gefunden", + ]; + + return array_replace($labels, $this->labels); + } + + /** + * Modify the columns for the Taxonomy + * @param array $columns The WordPress default columns + * @return array + */ + public function modifyColumns($columns) + { + $columns = $this->columns->modifyColumns($columns); + + return $columns; + } + + /** + * Populate custom columns for the Taxonomy + * @param string $content + * @param string $column + * @param int $term_id + */ + public function populateColumns($content, $column, $term_id) + { + if (isset($this->columns->populate[$column])) { + $content = call_user_func_array($this->columns()->populate[$column], [$content, $column, $term_id]); + } + + return $content; + } + + /** + * Make custom columns sortable + * @param array $columns Default WordPress sortable columns + */ + public function setSortableColumns($columns) + { + if (!empty($this->columns()->sortable)) { + $columns = array_merge($columns, $this->columns()->sortable); + } + + return $columns; + } + + /** + * Set query to sort custom columns + * @param WP_Term_Query $query + */ + public function sortSortableColumns($query) + { + // don't modify the query if we're not in the post type admin + if (!is_admin() || !in_array($this->name, $query->query_vars['taxonomy'] ?? [])) { + return; + } + + // check the orderby is a custom ordering + if (isset($_GET['orderby']) && array_key_exists($_GET['orderby'], $this->columns()->sortable)) { + // get the custom sorting options + $meta = $this->columns()->sortable[$_GET['orderby']]; + + // check ordering is not numeric + if (is_string($meta)) { + $meta_key = $meta; + $orderby = 'meta_value'; + } else { + $meta_key = $meta[0]; + $orderby = 'meta_value_num'; + } + + // set the sort order + $query->query_vars['orderby'] = $orderby; + $query->query_vars['meta_key'] = $meta_key; + } + } +} |