permalink-manager-debug.php
2 days ago
permalink-manager-permastructures.php
2 months ago
permalink-manager-settings.php
2 days ago
permalink-manager-tools.php
3 months ago
permalink-manager-ui-elements.php
2 days ago
permalink-manager-uri-editor-post.php
2 days ago
permalink-manager-uri-editor.php
2 days ago
permalink-manager-permastructures.php
301 lines
| 1 | <?php |
| 2 | |
| 3 | if ( ! defined( 'ABSPATH' ) ) { |
| 4 | exit; |
| 5 | } |
| 6 | |
| 7 | /** |
| 8 | * Display the page where the slugs could be regenerated or replaced |
| 9 | */ |
| 10 | class Permalink_Manager_Permastructs { |
| 11 | |
| 12 | public function __construct() { |
| 13 | add_filter( 'permalink_manager_sections', array( $this, 'add_admin_section' ), 2 ); |
| 14 | } |
| 15 | |
| 16 | /** |
| 17 | * Add a new section to the Permalink Manager UI |
| 18 | * |
| 19 | * @param array $admin_sections |
| 20 | * |
| 21 | * @return array |
| 22 | */ |
| 23 | public function add_admin_section( $admin_sections ) { |
| 24 | $admin_sections['permastructs'] = array( |
| 25 | 'name' => __( 'Permastructures', 'permalink-manager' ), |
| 26 | 'function' => array( 'class' => 'Permalink_Manager_Permastructs', 'method' => 'output' ) |
| 27 | ); |
| 28 | |
| 29 | return $admin_sections; |
| 30 | } |
| 31 | |
| 32 | /** |
| 33 | * Return an array of fields that will be used to adjust the permastructure settings |
| 34 | * |
| 35 | * @return array |
| 36 | */ |
| 37 | public function get_fields() { |
| 38 | $post_types = Permalink_Manager_Helper_Functions::get_post_types_array( 'full' ); |
| 39 | $taxonomies = Permalink_Manager_Helper_Functions::get_taxonomies_array( 'full' ); |
| 40 | |
| 41 | // Display additional information in Permalink Manager Lite |
| 42 | if ( ! Permalink_Manager_Admin_Functions::is_pro_active() ) { |
| 43 | /* translators: %s: Permalink Manager Pro website */ |
| 44 | $pro_text = sprintf( __( 'To edit taxonomy permalinks, <a href="%s" target="_blank">Permalink Manager Pro</a> is required.', 'permalink-manager' ), PERMALINK_MANAGER_PROMO ); |
| 45 | $pro_text = sprintf( '<div class="alert info">%s</div>', $pro_text ); |
| 46 | } |
| 47 | |
| 48 | // 1. Get fields |
| 49 | $fields = array( |
| 50 | 'post_types' => array( |
| 51 | 'section_name' => __( 'Post types', 'permalink-manager' ), |
| 52 | 'container' => 'row', |
| 53 | 'fields' => array() |
| 54 | ), |
| 55 | 'taxonomies' => array( |
| 56 | 'section_name' => __( 'Taxonomies', 'permalink-manager' ), |
| 57 | 'container' => 'row', |
| 58 | 'fields' => array(), |
| 59 | 'append_content' => ( ! empty( $pro_text ) ) ? $pro_text : '' |
| 60 | ) |
| 61 | ); |
| 62 | |
| 63 | // 2. Add a separate section for WooCommerce content types |
| 64 | if ( class_exists( 'WooCommerce' ) ) { |
| 65 | $fields['woocommerce'] = array( |
| 66 | 'section_name' => "<i class=\"woocommerce-icon woocommerce-cart\"></i> " . __( 'WooCommerce', 'permalink-manager' ), |
| 67 | 'container' => 'row', |
| 68 | 'fields' => array(), |
| 69 | 'append_content' => ( ! empty( $pro_text ) ) ? $pro_text : '' |
| 70 | ); |
| 71 | } |
| 72 | |
| 73 | // 3A. Add permastructure fields for post types |
| 74 | foreach ( $post_types as $post_type ) { |
| 75 | if ( $post_type['name'] == 'shop_coupon' ) { |
| 76 | continue; |
| 77 | } |
| 78 | |
| 79 | $fields["post_types"]["fields"][ $post_type['name'] ] = self::get_single_permastructure_field( $post_type, false, false ); |
| 80 | } |
| 81 | |
| 82 | // 3B. Add permastructure fields for taxonomies |
| 83 | foreach ( $taxonomies as $taxonomy ) { |
| 84 | $taxonomy_name = $taxonomy['name']; |
| 85 | |
| 86 | // Check if taxonomy exists |
| 87 | if ( ! taxonomy_exists( $taxonomy_name ) ) { |
| 88 | continue; |
| 89 | } |
| 90 | |
| 91 | $fields["taxonomies"]["fields"][ $taxonomy_name ] = self::get_single_permastructure_field( $taxonomy, true, isset( $pro_text ) ); |
| 92 | } |
| 93 | |
| 94 | return apply_filters( 'permalink_manager_permastructs_fields', $fields ); |
| 95 | } |
| 96 | |
| 97 | /** |
| 98 | * Get the row of the permastructure field for single content type |
| 99 | * |
| 100 | * @param $content_type |
| 101 | * @param bool $is_tax |
| 102 | * @param bool $pro_alert |
| 103 | * |
| 104 | * @return string |
| 105 | */ |
| 106 | function get_single_permastructure_field( $content_type, $is_tax = false, $pro_alert = false ) { |
| 107 | global $permalink_manager_permastructs; |
| 108 | |
| 109 | if ( empty( $content_type['name'] ) ) { |
| 110 | return ''; |
| 111 | } |
| 112 | |
| 113 | $content_group = ( $is_tax ) ? "taxonomies" : "post_types"; |
| 114 | $content_type_name = $content_type['name']; |
| 115 | $content_type_label = $content_type['label']; |
| 116 | |
| 117 | $siteurl = Permalink_Manager_Permastructure_Functions::get_permalink_base(); |
| 118 | $tags_container_id = sprintf( 'permastruct-tags-%s-%s', $content_group, $content_type_name ); |
| 119 | $available_tags = self::get_all_structure_tags( $content_type_name, $is_tax ); |
| 120 | |
| 121 | // Get permastructures |
| 122 | $permastructures = ( ! empty( $permalink_manager_permastructs[ $content_group ] ) ) ? $permalink_manager_permastructs[ $content_group ] : array(); |
| 123 | $default_permastruct = trim( Permalink_Manager_Permastructure_Functions::get_default_permastruct( $content_type_name ), "/" ); |
| 124 | $current_permastruct = isset( $permastructures[ $content_type_name ] ) ? $permastructures[ $content_type_name ] : $default_permastruct; |
| 125 | |
| 126 | // Append extra attributes |
| 127 | $field_atts = array( |
| 128 | 'value' => $current_permastruct, |
| 129 | 'input_class' => 'permastruct-field', |
| 130 | 'disabled' => $pro_alert, |
| 131 | 'placeholder' => $default_permastruct, |
| 132 | 'extra_atts' => " data-default=\"{$default_permastruct}\"" |
| 133 | ); |
| 134 | |
| 135 | $field_name = sprintf( '%s[%s]', $content_group, $content_type_name ); |
| 136 | $permastruct_field = sprintf( "<div class=\"permastruct-field-container\"><span><code>%s/</code></span><span>%s</span></div>", $siteurl, Permalink_Manager_UI_Elements::generate_option_field( $field_name, $field_atts ) ); |
| 137 | |
| 138 | $buttons = sprintf( "<p class=\"permastruct-buttons\"> |
| 139 | <span><a href=\"#\" class=\"button button-small button-secondary extra-settings\"><span class=\"dashicons dashicons-admin-settings\"></span> %s</a></span> |
| 140 | <span><a href=\"/?TB_inline&width=800&height=600&inlineId=%s\" class=\"button button-small button-secondary show-tags thickbox\"><span class=\"dashicons dashicons-tag\"></span> %s</a></span> |
| 141 | </p>", __( "Extra settings", "permalink-manager" ), $tags_container_id, __( "Available tags", "permalink-manager" ) ); |
| 142 | |
| 143 | $language_fields = ''; |
| 144 | $languages = Permalink_Manager_Language_Plugins::get_all_languages( true ); |
| 145 | if ( $languages ) { |
| 146 | $language_fields = sprintf( "<h4>%s</h4><p class=\"permastruct-instruction\">%s</p>", __( "Permastructure translations", "permalink-manager" ), __( "If you would like to translate the permastructures and set-up different permalink structure per language, please fill in the fields below. Otherwise the permastructure set for default language (see field above) will be applied.", "permalink-manager" ) ); |
| 147 | |
| 148 | foreach ( $languages as $lang => $name ) { |
| 149 | $current_lang_permastruct = isset( $permastructures["{$content_type_name}_{$lang}"] ) ? $permastructures["{$content_type_name}_{$lang}"] : ''; |
| 150 | |
| 151 | $lang_field_atts = array_merge( $field_atts, array( 'value' => $current_lang_permastruct, 'extra_atts' => 'data-default=""', 'placeholder' => $current_permastruct ) ); |
| 152 | $lang_field_name = str_replace( "]", "_{$lang}]", $field_name ); |
| 153 | |
| 154 | $language_fields .= sprintf( "<label>%s</label><div class=\"permastruct-field-container\"><span><code>%s/</code></span><span>%s</span></div>", $name, Permalink_Manager_Language_Plugins::prepend_lang_prefix( $siteurl, '', $lang ), Permalink_Manager_UI_Elements::generate_option_field( $lang_field_name, $lang_field_atts ) ); |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | $default_permastruct_row = sprintf( "<p class=\"default-permastruct-row columns-container\"> |
| 159 | <span class=\"column-2_4\"><strong>%s:</strong> %s</span> |
| 160 | <span class=\"column-2_4\"><a href=\"#\" class=\"restore-default\"><span class=\"dashicons dashicons-image-rotate\"></span> %s</a></span> |
| 161 | </p>", __( "Default permastructure", "permalink-manager" ), esc_html( $default_permastruct ), __( "Restore default permastructure", "permalink-manager" ) ); |
| 162 | |
| 163 | $permastructure_settings = sprintf( "<h4>%s</h4><div class=\"settings-container\">%s</div>", __( "Permastructure settings", "permalink-manager" ), Permalink_Manager_UI_Elements::generate_option_field( "permastructure-settings[do_not_append_slug][$content_group][{$content_type_name}]", array( 'type' => 'single_checkbox', 'default' => 1, 'checkbox_label' => __( "Do not automatically append the slug", "permalink-manager" ) ) ) ); |
| 164 | |
| 165 | // Combine all HTML chunks |
| 166 | $html = sprintf( "<div class=\"permastruct-container\">%s%s</div>", $permastruct_field, $buttons ); |
| 167 | $html .= sprintf( "<div class=\"permastruct-settings\">%s%s%s</div>", $language_fields, $default_permastruct_row, $permastructure_settings ); |
| 168 | $html .= sprintf( '<div id="%s" style="display:none;">%s</div>', $tags_container_id, $available_tags ); |
| 169 | |
| 170 | $label_tag = sprintf( "<th><label for=\"%s\">%s</label></th>", $field_name, $content_type_label ); |
| 171 | |
| 172 | return sprintf( "<tr id=\"%s_%s\" data-field=\"%s\" class=\"%s\">%s<td><fieldset>%s</fieldset></td></tr>", esc_attr( $content_group ), esc_attr( $content_type_name ), esc_attr( $field_name ), 'field-container permastruct-row', $label_tag, $html ); |
| 173 | } |
| 174 | |
| 175 | |
| 176 | /** |
| 177 | * Get the array with settings and render the HTML output |
| 178 | */ |
| 179 | public function output() { |
| 180 | $sidebar = "<div class=\"notice notice-warning inline\"><p>"; |
| 181 | $sidebar .= __( 'The current permastructures settings will be automatically applied <strong>only to the new posts & terms</strong>.', 'permalink-manager' ); |
| 182 | $sidebar .= '<br />'; |
| 183 | /* translators: %s: Regenerate/reset admin URL */ |
| 184 | $sidebar .= sprintf( __( 'To apply the <strong>new format to existing posts and terms</strong>, please use "<a href="%s">Regenerate/reset</a>" tool after you update the permastructure settings below.', 'permalink-manager' ), admin_url( 'tools.php?page=permalink-manager§ion=tools&subsection=regenerate_slugs' ) ); |
| 185 | $sidebar .= "</div>"; |
| 186 | |
| 187 | return Permalink_Manager_UI_Elements::get_the_form( self::get_fields(), '', array( 'text' => __( 'Save permastructures', 'permalink-manager' ), 'class' => 'primary margin-top' ), $sidebar, array( 'action' => 'permalink-manager', 'name' => 'permalink_manager_permastructs' ) ); |
| 188 | } |
| 189 | |
| 190 | /** |
| 191 | * Get a list of all structure tags |
| 192 | * |
| 193 | * @param string $content_type |
| 194 | * @param bool $is_taxonomy |
| 195 | * |
| 196 | * @return string |
| 197 | */ |
| 198 | static function get_all_structure_tags( $content_type = '', $is_taxonomy = false ) { |
| 199 | if ( empty( $content_type ) ) { |
| 200 | return ''; |
| 201 | } |
| 202 | |
| 203 | $html = ''; |
| 204 | |
| 205 | $tags_groups = array( |
| 206 | 'slug' => array( |
| 207 | 'heading' => __( 'Native slug & title', 'permalink-manager' ), |
| 208 | 'description' => __( 'The native slug is generated from the initial title and will not update automatically if the title is changed later. You can use the %native_title% tag to replace native slugs with actual titles, even if another content item has the same title.', 'permalink-manager' ) |
| 209 | ), |
| 210 | 'meta' => array( |
| 211 | 'heading' => __( 'Meta data', 'permalink-manager' ), |
| 212 | 'description' => __( 'Using meta tags, you may add post-specific information like item IDs or author names to permalinks. This might be beneficial to news, events, and time-sensitive content where you can use date-based tags.', 'permalink-manager' ) |
| 213 | ), |
| 214 | 'taxonomies' => array( |
| 215 | 'heading' => __( 'Taxonomies', 'permalink-manager' ), |
| 216 | 'description' => __( 'Custom permalinks can include taxonomy-based slugs such as categories, tags, and custom taxonomy terms. If a post belongs to multiple terms, the lowest-level one is used unless a specific term is selected as primary.', 'permalink-manager' ) |
| 217 | ), |
| 218 | 'custom_fields' => array( |
| 219 | 'heading' => __( 'Custom fields', 'permalink-manager' ), |
| 220 | 'description' => __( 'Permalinks can be modified with custom fields to dynamically include extra data. For example, you can append product SKUs to WooCommerce URLs or include geolocation details in your custom post types\' permalinks.', 'permalink-manager' ), |
| 221 | 'pro' => true |
| 222 | ) |
| 223 | ); |
| 224 | |
| 225 | if ( ! $is_taxonomy ) { |
| 226 | $post_type_tag = Permalink_Manager_Permastructure_Functions::get_post_tag( $content_type ); |
| 227 | $post_type_taxonomies = get_taxonomies( array( 'object_type' => array( $content_type ) ), 'objects' ); |
| 228 | |
| 229 | $tags_groups['slug']['tags'] = array( |
| 230 | $post_type_tag, |
| 231 | ( $content_type !== 'post' ) ? '%postname%' : '', |
| 232 | '%native_title%' |
| 233 | ); |
| 234 | |
| 235 | $tags_groups['meta']['tags'] = array( |
| 236 | '%post_id%', |
| 237 | '%author%', |
| 238 | '%year%', |
| 239 | '%monthnum%', |
| 240 | '%monthname%', |
| 241 | '%day%', |
| 242 | '%hour%', |
| 243 | '%minute%', |
| 244 | '%second%', |
| 245 | '%post_type%' |
| 246 | ); |
| 247 | |
| 248 | if ( ! empty( $post_type_taxonomies ) ) { |
| 249 | $tags_groups['taxonomies']['tags'] = array(); |
| 250 | |
| 251 | foreach ( $post_type_taxonomies as $post_type_taxonomy ) { |
| 252 | $tags_groups['taxonomies']['tags'][] = sprintf( '%%%s%%', $post_type_taxonomy->name ); |
| 253 | } |
| 254 | } |
| 255 | } else { |
| 256 | $taxonomy_tag = sprintf( '%%%s%%', $content_type ); |
| 257 | |
| 258 | $tags_groups['slug']['tags'] = array( |
| 259 | $taxonomy_tag, |
| 260 | '%term_name%', |
| 261 | '%native_title%' |
| 262 | ); |
| 263 | |
| 264 | $tags_groups['meta']['tags'] = array( |
| 265 | '%term_id%', |
| 266 | '%taxonomy%' |
| 267 | ); |
| 268 | } |
| 269 | |
| 270 | $tags_groups['custom_fields']['tags'] = array( |
| 271 | '%__custom_field_name%' |
| 272 | ); |
| 273 | |
| 274 | foreach ( $tags_groups as $tags_group ) { |
| 275 | if ( empty( $tags_group['tags'] ) ) { |
| 276 | continue; |
| 277 | } |
| 278 | |
| 279 | $html .= sprintf( '<h3>%s</h3>', $tags_group['heading'] ); |
| 280 | |
| 281 | if ( ! empty( $tags_group['pro'] ) ) { |
| 282 | $pro_text = Permalink_Manager_UI_Elements::pro_text( true ); |
| 283 | $html .= ( ! empty( $pro_text ) ) ? sprintf( '<span class="notice notice-error inline">%s</span>', $pro_text ) : ''; |
| 284 | } |
| 285 | |
| 286 | $html .= '<div class="permastruct-tag-container">'; |
| 287 | $html .= sprintf( '<div><p class="description">%s</p></div>', $tags_group['description'] ); |
| 288 | |
| 289 | $html .= '<div><div class="permastruct-tag-buttons">'; |
| 290 | foreach ( $tags_group['tags'] as $tag ) { |
| 291 | $html .= ( ! empty( $tag ) ) ? sprintf( '<button type="button" class="button button-small button-secondary" data-original-text="%1$s">%1$s</button>', $tag ) : ''; |
| 292 | } |
| 293 | $html .= '</div></div>'; |
| 294 | $html .= '</div>'; |
| 295 | } |
| 296 | |
| 297 | return sprintf( "<div class=\"structure-tags-list\">%s</div>", $html ); |
| 298 | } |
| 299 | |
| 300 | } |
| 301 |