diff --git a/src/media.php b/src/media.php index 3fab685..e6af199 100644 --- a/src/media.php +++ b/src/media.php @@ -2,7 +2,11 @@ namespace TheaterGF\Core; -require_once __DIR__ . "/media-meta-box-html.php"; +require_once __DIR__ . "/tag.php"; + +function array_contains( $array, $element ) { + return null != array_find($array, function ( $e ) use ($element) { return $e == $element; }); +} function build_tag_name( $term ) { @@ -33,12 +37,15 @@ function build_tag_name( $term ) { class MediaManager { + public $tags; + public function __construct() { add_action('init', [ $this, 'register_structure' ]); add_filter('attachment_fields_to_edit', [ $this, 'create_edit_media_control' ], 10, 2); add_action('add_meta_boxes', [ $this, 'create_tag_management_box' ]); + add_action('save_post', [ $this, 'save_tags' ]); // Dont know what it does add_filter( 'update_post_term_count_statuses', function( $statuses, $taxonomy ) { @@ -56,26 +63,7 @@ class MediaManager { } public function register_structure() { - register_taxonomy('ttgf_media_tags', 'attachment', [ - 'labels' => [ - 'name' => 'Tags', - 'singular_name' => 'Tag', - 'search_items' => 'Search tags', - 'all_items' => 'All tags', - 'parent_item' => 'Parent tag', - 'edit_item' => 'Edit tags', - 'update_item' => 'Update tags', - 'add_new_item' => 'Add new tag', - 'new_item_name' => 'New tag name', - 'menu_name' => 'Tags', - ], - 'hierarchical' => true, - 'public' => false, - 'show_ui' => false, - 'show_admin_column' => true, - 'rewrite' => false, - 'update_count_callback' => '_update_generic_term_count' - ]); + $this->tags = TagTree::create('ttgf_media_tags'); } public function create_tag_management_box() { @@ -89,25 +77,79 @@ class MediaManager { } public function tag_management_meta_box_html( $post ) { - $all_terms = get_terms([ - 'taxonomy' => 'ttgf_media_tags', - 'hide_empty' => false, - ]); - $all_tags = build_tag_name($all_terms); - $terms = get_the_terms($post, 'ttgf_media_tags'); - $tags = build_tag_name($terms); + $tags = $this->tags->get_multiple($terms ? $terms : []); ?>

Assigned

-
+
name() ?>
+ +

Available

+
+ tags->get_all() as $tag ): ?> + name() ?>: id ?>
+ +
+ +

Add new

+
+ + + + tags->get_all() as $tag ): ?> + +
'ttgf_media_tags', + 'hide_empty' => false, + ]); + $all_tags = build_tag_name($all_terms); + + $terms = get_the_terms($post, 'ttgf_media_tags'); + $tags = build_tag_name($terms); + + if ( array_find($tags, function ( $tag ) { return $tag == $new_tag; }) ) { + return; + } + + if ( ! array_find($all_tags, function ( $tag ) { return $tag == $new_tag; }) ) { + + $parts = explode("/", $new_tag); + + $index = count($parts); + for ( ; $index > 0; --$index ) { + if ( array_contains($all_tags, implode("/", array_slice($parts, 0, $index))) ) { + break; + } + } + + + + } + } + } + public function create_edit_media_control( $fields, $post ) { $terms = get_terms([ 'taxonomy' => 'ttgf_media_tags', 'hide_empty' => false ]); diff --git a/src/tag.php b/src/tag.php new file mode 100644 index 0000000..f8d5f36 --- /dev/null +++ b/src/tag.php @@ -0,0 +1,235 @@ +term = $term; + $this->id = $term->term_id; + $this->parent = null; + $this->children = []; + } + + public function name() { + return implode('/', array_map(function ($segment) { return $segment->term->name; }, $this->path())); + } + + public function path() { + $path = [ $this ]; + + $parent = $this->parent; + while ( $parent ) { + $path[] = $parent; + $parent = $parent->parent; + } + + return array_reverse($path); + } + + public function get_all_children() { + $child_list = $this->children; + + foreach ( $this->children as $child ) { + $child_list = array_merge($child_list, $child->get_all_children()); + } + + return $child_list; + } + + public function move( $new_term, $new_parent ) { + $this->term = $new_term; + $this->id = $new_term->term_id; + + if ( $this->parent == $new_parent ) { + return; + } + + $this->parent->remove_child($this); + $this->parent->add_child($this); + } + + public function update_term( $new_term ) { + $this->term = $new_term; + $this->id = $new_term->term_id; + } + + + public function add_child( $child ) { + $this->children[] = $child; + $child->parent = $this; + } + + public function remove() { + $this->parent->remove_child($this); + } + + protected function remove_child( $child ) { + $index = array_find($this->children, function ($c) use ($child) { return $c == $child; }); + if ( $index ) { + $this->children = array_splice($this->children, $index, 1); + } + } + +} + +class TagTree { + + static public function create( $taxonomy_id ) { + $taxonomy = register_taxonomy($taxonomy_id, 'attachment', [ + 'labels' => [ + 'name' => 'Tags', + 'singular_name' => 'Tag', + 'search_items' => 'Search tags', + 'all_items' => 'All tags', + 'parent_item' => 'Parent tag', + 'edit_item' => 'Edit tags', + 'update_item' => 'Update tags', + 'add_new_item' => 'Add new tag', + 'new_item_name' => 'New tag name', + 'menu_name' => 'Tags', + ], + 'hierarchical' => true, + 'public' => false, + 'show_ui' => false, + 'show_admin_column' => true, + 'rewrite' => false, + 'update_count_callback' => '_update_generic_term_count' + ]); + + return new TagTree($taxonomy_id); + } + + public $taxonomy; + public $root_tags; + + public function __construct ( $taxonomy ) { + $this->taxonomy = $taxonomy; + $this->root_tags = []; + + $this->rebuild(); + } + + public function get_all() { + $all = $this->root_tags; + + foreach ( $this->root_tags as $tag ) { + $all = array_merge($all, $tag->get_all_children()); + } + + return $all; + } + + public function get_multiple( $terms ) { + + $num_terms = count($terms); + if ( $num_terms == 0 ) { + return []; + } + + $term_ids = array_map(function ($term) { return $term->term_id; }, $terms); + $term_ids_set = array_flip($term_ids); + + foreach ( $this->root_tags as $rt ) { + foreach ( $rt->get_all_children() as $child ) { + if ( isset($term_ids_set[$child->id]) ) { + $tags[] = $child; + } + if ( count($tags) == $num_terms ) { + return $tags; + } + } + } + + return $tags; + } + + public function get( $term ) { + + foreach ( $this->root_tags as $rt ) { + $found = array_find($rt->get_all_children(), function ($child) use ($term) { return $child->id == $term->term_id; }); + if ( $found ) { + return $found; + } + } + + return null; + } + + public function create_tag( $parent, $tag_name, $description = '') { + $new_term = wp_insert_term( $tag_name, $this->taxonomy, [ + 'description' => $description, + 'parent' => $parent->id + ]); + + if ( is_wp_error($new_term) ) { + return $new_term; + } + + return new Tag($new_term, $parent); + } + + public function move_tag( $tag, $new_parent ) { + + $result = wp_update_term($tag->id, $this->taxonomy, [ 'parent' => $new_parent->id ]); + + if ( is_wp_error($result) ) { + return $result; + } + + $new_term = get_term($result->term_id, $this->taxonomy); + + $tag->update_term( $new_term, $new_parent ); + } + + public function update_tag( $tag, $new_description ) { + + $result = wp_update_term($tag->id, $this->taxonomy, [ 'parent' => $tag->parent->id, 'description' => $new_description ]); + + if ( is_wp_error($result) ) { + return $result; + } + + $new_term = get_term($result->term_id, $this->taxonomy); + + $tag->update_term($new_term); + } + + public function delete_tag( $tag ) { + // TODO + } + + public function rebuild() { + $root_terms = get_terms([ 'taxonomy' => $this->taxonomy, 'hide_empty' => false, 'parent' => 0 ]); + + foreach ( $root_terms as $term ) { + $this->root_tags[] = new Tag($term); + } + + foreach ( $this->root_tags as $tag ) { + $this->rebuild_children($tag); + } + } + + private function rebuild_children( $child ) { + $child_terms = get_terms([ 'taxonomy' => $this->taxonomy, 'hide_empty' => false, 'parent' => $child->term->term_id ]); + + foreach ( $child_terms as $child_term ) { + $child->add_child(new Tag($child_term)); + } + + foreach ( $child->children as $grandchild ) { + $this->rebuild_children($grandchild); + } + } + + + +}