|
| 1 | +<?php |
| 2 | +/** |
| 3 | + * Generate taxonomy terms. |
| 4 | + * |
| 5 | + * @package SmoothGenerator\Classes |
| 6 | + */ |
| 7 | + |
| 8 | +namespace WC\SmoothGenerator\Generator; |
| 9 | + |
| 10 | +/** |
| 11 | + * Customer data generator. |
| 12 | + */ |
| 13 | +class Term extends Generator { |
| 14 | + /** |
| 15 | + * Init faker library. |
| 16 | + */ |
| 17 | + protected static function init_faker() { |
| 18 | + parent::init_faker(); |
| 19 | + self::$faker->addProvider( new \Bezhanov\Faker\Provider\Commerce( self::$faker ) ); |
| 20 | + } |
| 21 | + |
| 22 | + /** |
| 23 | + * Create a new taxonomy term. |
| 24 | + * |
| 25 | + * @param bool $save Whether to save the new term to the database. |
| 26 | + * @param string $taxonomy The taxonomy slug. |
| 27 | + * @param int $parent ID of parent term. |
| 28 | + * |
| 29 | + * @return \WP_Error|\WP_Term |
| 30 | + */ |
| 31 | + public static function generate( $save = true, string $taxonomy = 'product_cat', int $parent = 0 ) { |
| 32 | + $taxonomy_obj = get_taxonomy( $taxonomy ); |
| 33 | + if ( ! $taxonomy_obj ) { |
| 34 | + return new \WP_Error( |
| 35 | + 'smoothgenerator_invalid_taxonomy', |
| 36 | + 'The specified taxonomy is invalid.' |
| 37 | + ); |
| 38 | + } |
| 39 | + |
| 40 | + if ( 0 !== $parent && true !== $taxonomy_obj->hierarchical ) { |
| 41 | + return new \WP_Error( |
| 42 | + 'smoothgenerator_invalid_term_hierarchy', |
| 43 | + 'The specified taxonomy does not support parent terms.' |
| 44 | + ); |
| 45 | + } |
| 46 | + |
| 47 | + self::init_faker(); |
| 48 | + |
| 49 | + if ( $taxonomy_obj->hierarchical ) { |
| 50 | + $term_name = ucwords( self::$faker->department( 3 ) ); |
| 51 | + } else { |
| 52 | + $term_name = self::random_weighted_element( array( |
| 53 | + self::$faker->lastName() => 45, |
| 54 | + self::$faker->colorName() => 35, |
| 55 | + self::$faker->words( 3, true ) => 20, |
| 56 | + ) ); |
| 57 | + $term_name = strtolower( $term_name ); |
| 58 | + } |
| 59 | + |
| 60 | + $term_args = array( |
| 61 | + 'description' => self::$faker->realTextBetween( 20, wp_rand( 20, 300 ), 4 ), |
| 62 | + ); |
| 63 | + if ( 0 !== $parent ) { |
| 64 | + $term_args['parent'] = $parent; |
| 65 | + } |
| 66 | + |
| 67 | + $result = wp_insert_term( $term_name, $taxonomy, $term_args ); |
| 68 | + |
| 69 | + if ( is_wp_error( $result ) ) { |
| 70 | + return $result; |
| 71 | + } |
| 72 | + |
| 73 | + $term = get_term( $result['term_id'] ); |
| 74 | + |
| 75 | + /** |
| 76 | + * Action: Term generator returned a new term. |
| 77 | + * |
| 78 | + * @since TBD |
| 79 | + * |
| 80 | + * @param \WP_Term $term |
| 81 | + */ |
| 82 | + do_action( 'smoothgenerator_term_generated', $term ); |
| 83 | + |
| 84 | + return $term; |
| 85 | + } |
| 86 | + |
| 87 | + /** |
| 88 | + * Create multiple terms for a taxonomy. |
| 89 | + * |
| 90 | + * @param int $amount The number of terms to create. |
| 91 | + * @param string $taxonomy The taxonomy to assign the terms to. |
| 92 | + * @param array $args Additional args for term creation. |
| 93 | + * |
| 94 | + * @return int[]|\WP_Error |
| 95 | + */ |
| 96 | + public static function batch( $amount, $taxonomy, array $args = array() ) { |
| 97 | + $amount = filter_var( |
| 98 | + $amount, |
| 99 | + FILTER_VALIDATE_INT, |
| 100 | + array( |
| 101 | + 'min_range' => 1, |
| 102 | + 'max_range' => 100, |
| 103 | + ) |
| 104 | + ); |
| 105 | + |
| 106 | + if ( false === $amount ) { |
| 107 | + return new \WP_Error( |
| 108 | + 'smoothgenerator_term_batch_invalid_amount', |
| 109 | + 'Amount must be a number between 1 and 100.' |
| 110 | + ); |
| 111 | + } |
| 112 | + |
| 113 | + $taxonomy_obj = get_taxonomy( $taxonomy ); |
| 114 | + if ( ! $taxonomy_obj ) { |
| 115 | + return new \WP_Error( |
| 116 | + 'smoothgenerator_term_batch_invalid_taxonomy', |
| 117 | + 'The specified taxonomy is invalid.' |
| 118 | + ); |
| 119 | + } |
| 120 | + |
| 121 | + if ( true === $taxonomy_obj->hierarchical ) { |
| 122 | + return self::batch_hierarchical( $amount, $taxonomy, $args ); |
| 123 | + } |
| 124 | + |
| 125 | + $term_ids = array(); |
| 126 | + |
| 127 | + for ( $i = 1; $i <= $amount; $i ++ ) { |
| 128 | + $term = self::generate( true, $taxonomy ); |
| 129 | + if ( is_wp_error( $term ) ) { |
| 130 | + if ( 'term_exists' === $term->get_error_code() ) { |
| 131 | + $i --; // Try again. |
| 132 | + continue; |
| 133 | + } |
| 134 | + |
| 135 | + return $term; |
| 136 | + } |
| 137 | + $term_ids[] = $term->term_id; |
| 138 | + } |
| 139 | + |
| 140 | + return $term_ids; |
| 141 | + } |
| 142 | + |
| 143 | + /** |
| 144 | + * Create multiple terms for a hierarchical taxonomy. |
| 145 | + * |
| 146 | + * @param int $amount The number of terms to create. |
| 147 | + * @param string $taxonomy The taxonomy to assign the terms to. |
| 148 | + * @param array $args Additional args for term creation. |
| 149 | + * @type int $max_depth The maximum level of hierarchy. |
| 150 | + * @type int $parent ID of a term to be the parent of the generated terms. |
| 151 | + * |
| 152 | + * @return int[]|\WP_Error |
| 153 | + */ |
| 154 | + protected static function batch_hierarchical( int $amount, string $taxonomy, array $args = array() ) { |
| 155 | + $defaults = array( |
| 156 | + 'max-depth' => 1, |
| 157 | + 'parent' => 0, |
| 158 | + ); |
| 159 | + |
| 160 | + list( 'max-depth' => $max_depth, 'parent' => $parent ) = filter_var_array( |
| 161 | + wp_parse_args( $args, $defaults ), |
| 162 | + array( |
| 163 | + 'max-depth' => array( |
| 164 | + 'filter' => FILTER_VALIDATE_INT, |
| 165 | + 'options' => array( |
| 166 | + 'min_range' => 1, |
| 167 | + 'max_range' => 5, |
| 168 | + ), |
| 169 | + ), |
| 170 | + 'parent' => FILTER_VALIDATE_INT, |
| 171 | + ) |
| 172 | + ); |
| 173 | + |
| 174 | + if ( false === $max_depth ) { |
| 175 | + return new \WP_Error( |
| 176 | + 'smoothgenerator_term_batch_invalid_max_depth', |
| 177 | + 'Max depth must be a number between 1 and 5.' |
| 178 | + ); |
| 179 | + } |
| 180 | + if ( false === $parent ) { |
| 181 | + return new \WP_Error( |
| 182 | + 'smoothgenerator_term_batch_invalid_parent', |
| 183 | + 'Parent must be the ID number of an existing term.' |
| 184 | + ); |
| 185 | + } |
| 186 | + |
| 187 | + $term_ids = array(); |
| 188 | + |
| 189 | + self::init_faker(); |
| 190 | + |
| 191 | + if ( $parent || 1 === $max_depth ) { |
| 192 | + // All terms will be in the same hierarchy level. |
| 193 | + for ( $i = 1; $i <= $amount; $i ++ ) { |
| 194 | + $term = self::generate( true, $taxonomy, $parent ); |
| 195 | + if ( is_wp_error( $term ) ) { |
| 196 | + if ( 'term_exists' === $term->get_error_code() ) { |
| 197 | + $i --; // Try again. |
| 198 | + continue; |
| 199 | + } |
| 200 | + |
| 201 | + return $term; |
| 202 | + } |
| 203 | + $term_ids[] = $term->term_id; |
| 204 | + } |
| 205 | + } else { |
| 206 | + $remaining = $amount; |
| 207 | + $term_max = 1; |
| 208 | + if ( $amount > 2 ) { |
| 209 | + $term_max = floor( log( $amount ) ); |
| 210 | + } |
| 211 | + $levels = array_fill( 1, $max_depth, array() ); |
| 212 | + |
| 213 | + for ( $i = 1; $i <= $max_depth; $i ++ ) { |
| 214 | + if ( 1 === $i ) { |
| 215 | + // Always use the full term max for the top level of the hierarchy. |
| 216 | + for ( $j = 1; $j <= $term_max && $remaining > 0; $j ++ ) { |
| 217 | + $term = self::generate( true, $taxonomy ); |
| 218 | + if ( is_wp_error( $term ) ) { |
| 219 | + if ( 'term_exists' === $term->get_error_code() ) { |
| 220 | + $j --; // Try again. |
| 221 | + continue; |
| 222 | + } |
| 223 | + |
| 224 | + return $term; |
| 225 | + } |
| 226 | + $term_ids[] = $term->term_id; |
| 227 | + $levels[ $i ][] = $term->term_id; |
| 228 | + $remaining --; |
| 229 | + } |
| 230 | + } else { |
| 231 | + // Subsequent hierarchy levels. |
| 232 | + foreach ( $levels[ $i - 1 ] as $term_id ) { |
| 233 | + $tcount = wp_rand( 0, $term_max ); |
| 234 | + |
| 235 | + for ( $j = 1; $j <= $tcount && $remaining > 0; $j ++ ) { |
| 236 | + $term = self::generate( true, $taxonomy, $term_id ); |
| 237 | + if ( is_wp_error( $term ) ) { |
| 238 | + if ( 'term_exists' === $term->get_error_code() ) { |
| 239 | + $j --; // Try again. |
| 240 | + continue; |
| 241 | + } |
| 242 | + |
| 243 | + return $term; |
| 244 | + } |
| 245 | + $term_ids[] = $term->term_id; |
| 246 | + $levels[ $i ][] = $term->term_id; |
| 247 | + $remaining --; |
| 248 | + } |
| 249 | + } |
| 250 | + } |
| 251 | + if ( $i === $max_depth && $remaining > 0 ) { |
| 252 | + // If we haven't generated enough yet, start back at the top level of the hierarchy. |
| 253 | + $i = 0; |
| 254 | + } |
| 255 | + } |
| 256 | + } |
| 257 | + |
| 258 | + return $term_ids; |
| 259 | + } |
| 260 | +} |
0 commit comments