summaryrefslogtreecommitdiff
path: root/src/Taxonomy.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/Taxonomy.php')
-rw-r--r--src/Taxonomy.php376
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;
+ }
+ }
+}