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
+
+ Available
+
+ tags->get_all() as $tag ): ?>
+ = $tag->name() ?>: = $tag->id ?>
+
+
+
+ Add new
+
+
+
+
+
'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);
+ }
+ }
+
+
+
+}