first commit: gustavoo-portfolio theme + gustavoo-portfolio-core plugin
This commit is contained in:
@@ -0,0 +1,563 @@
|
||||
<?php
|
||||
/**
|
||||
* Project content model and admin UI.
|
||||
*
|
||||
* @package GustavoPortfolioCore
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Registers the portfolio project post type, taxonomies and metadata.
|
||||
*/
|
||||
final class GSO_Projects {
|
||||
const POST_TYPE = 'gso_project';
|
||||
const TAX_TYPE = 'gso_project_type';
|
||||
const TAX_TECH = 'gso_project_tech';
|
||||
|
||||
const META_URL = '_gso_project_url';
|
||||
const META_CLIENT = '_gso_project_client';
|
||||
const META_YEAR = '_gso_project_year';
|
||||
const META_FEATURED = '_gso_project_featured';
|
||||
const META_LINK_LABEL = '_gso_project_link_label';
|
||||
const META_ACCENT = '_gso_project_accent';
|
||||
|
||||
/**
|
||||
* Register hooks.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function init() {
|
||||
add_action( 'init', array( __CLASS__, 'register_content_types' ) );
|
||||
add_action( 'add_meta_boxes_' . self::POST_TYPE, array( __CLASS__, 'add_meta_boxes' ) );
|
||||
add_action( 'save_post_' . self::POST_TYPE, array( __CLASS__, 'save_meta_box' ) );
|
||||
|
||||
add_filter( 'manage_' . self::POST_TYPE . '_posts_columns', array( __CLASS__, 'admin_columns' ) );
|
||||
add_action( 'manage_' . self::POST_TYPE . '_posts_custom_column', array( __CLASS__, 'render_admin_column' ), 10, 2 );
|
||||
add_filter( 'manage_edit-' . self::POST_TYPE . '_sortable_columns', array( __CLASS__, 'sortable_columns' ) );
|
||||
add_action( 'pre_get_posts', array( __CLASS__, 'apply_admin_sorting' ) );
|
||||
add_action( 'restrict_manage_posts', array( __CLASS__, 'taxonomy_filters' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the post type, taxonomies and REST-aware metadata.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register_content_types() {
|
||||
register_post_type(
|
||||
self::POST_TYPE,
|
||||
array(
|
||||
'labels' => array(
|
||||
'name' => __( 'Projetos', 'gustavoo-portfolio-core' ),
|
||||
'singular_name' => __( 'Projeto', 'gustavoo-portfolio-core' ),
|
||||
'menu_name' => __( 'Portfólio', 'gustavoo-portfolio-core' ),
|
||||
'name_admin_bar' => __( 'Projeto', 'gustavoo-portfolio-core' ),
|
||||
'add_new' => __( 'Adicionar projeto', 'gustavoo-portfolio-core' ),
|
||||
'add_new_item' => __( 'Adicionar novo projeto', 'gustavoo-portfolio-core' ),
|
||||
'edit_item' => __( 'Editar projeto', 'gustavoo-portfolio-core' ),
|
||||
'new_item' => __( 'Novo projeto', 'gustavoo-portfolio-core' ),
|
||||
'view_item' => __( 'Ver projeto', 'gustavoo-portfolio-core' ),
|
||||
'search_items' => __( 'Buscar projetos', 'gustavoo-portfolio-core' ),
|
||||
'not_found' => __( 'Nenhum projeto encontrado.', 'gustavoo-portfolio-core' ),
|
||||
'not_found_in_trash' => __( 'Nenhum projeto encontrado na lixeira.', 'gustavoo-portfolio-core' ),
|
||||
'all_items' => __( 'Projetos', 'gustavoo-portfolio-core' ),
|
||||
'featured_image' => __( 'Imagem do projeto', 'gustavoo-portfolio-core' ),
|
||||
'set_featured_image' => __( 'Definir imagem do projeto', 'gustavoo-portfolio-core' ),
|
||||
'remove_featured_image' => __( 'Remover imagem do projeto', 'gustavoo-portfolio-core' ),
|
||||
),
|
||||
'public' => false,
|
||||
'publicly_queryable' => false,
|
||||
'exclude_from_search' => true,
|
||||
'show_ui' => true,
|
||||
'show_in_menu' => true,
|
||||
'show_in_admin_bar' => true,
|
||||
'show_in_nav_menus' => false,
|
||||
'show_in_rest' => true,
|
||||
'menu_position' => 25,
|
||||
'menu_icon' => 'dashicons-portfolio',
|
||||
'capability_type' => 'post',
|
||||
'map_meta_cap' => true,
|
||||
'hierarchical' => false,
|
||||
'has_archive' => false,
|
||||
'rewrite' => false,
|
||||
'query_var' => false,
|
||||
'supports' => array( 'title', 'editor', 'excerpt', 'thumbnail', 'page-attributes', 'revisions', 'custom-fields' ),
|
||||
)
|
||||
);
|
||||
|
||||
register_taxonomy(
|
||||
self::TAX_TYPE,
|
||||
self::POST_TYPE,
|
||||
array(
|
||||
'labels' => array(
|
||||
'name' => __( 'Tipos de projeto', 'gustavoo-portfolio-core' ),
|
||||
'singular_name' => __( 'Tipo de projeto', 'gustavoo-portfolio-core' ),
|
||||
'menu_name' => __( 'Tipos', 'gustavoo-portfolio-core' ),
|
||||
'all_items' => __( 'Todos os tipos', 'gustavoo-portfolio-core' ),
|
||||
'edit_item' => __( 'Editar tipo', 'gustavoo-portfolio-core' ),
|
||||
'add_new_item' => __( 'Adicionar tipo', 'gustavoo-portfolio-core' ),
|
||||
'search_items' => __( 'Buscar tipos', 'gustavoo-portfolio-core' ),
|
||||
),
|
||||
'public' => false,
|
||||
'publicly_queryable' => false,
|
||||
'show_ui' => true,
|
||||
'show_admin_column' => false,
|
||||
'show_in_rest' => true,
|
||||
'hierarchical' => true,
|
||||
'rewrite' => false,
|
||||
)
|
||||
);
|
||||
|
||||
register_taxonomy(
|
||||
self::TAX_TECH,
|
||||
self::POST_TYPE,
|
||||
array(
|
||||
'labels' => array(
|
||||
'name' => __( 'Tecnologias', 'gustavoo-portfolio-core' ),
|
||||
'singular_name' => __( 'Tecnologia', 'gustavoo-portfolio-core' ),
|
||||
'menu_name' => __( 'Tecnologias', 'gustavoo-portfolio-core' ),
|
||||
'all_items' => __( 'Todas as tecnologias', 'gustavoo-portfolio-core' ),
|
||||
'edit_item' => __( 'Editar tecnologia', 'gustavoo-portfolio-core' ),
|
||||
'add_new_item' => __( 'Adicionar tecnologia', 'gustavoo-portfolio-core' ),
|
||||
'search_items' => __( 'Buscar tecnologias', 'gustavoo-portfolio-core' ),
|
||||
'separate_items_with_commas' => __( 'Separe tecnologias com vírgulas', 'gustavoo-portfolio-core' ),
|
||||
),
|
||||
'public' => false,
|
||||
'publicly_queryable' => false,
|
||||
'show_ui' => true,
|
||||
'show_admin_column' => false,
|
||||
'show_in_rest' => true,
|
||||
'hierarchical' => false,
|
||||
'rewrite' => false,
|
||||
)
|
||||
);
|
||||
|
||||
self::register_meta();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register project metadata.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function register_meta() {
|
||||
$common = array(
|
||||
'single' => true,
|
||||
'show_in_rest' => true,
|
||||
'auth_callback' => array( __CLASS__, 'authorize_meta' ),
|
||||
);
|
||||
|
||||
register_post_meta(
|
||||
self::POST_TYPE,
|
||||
self::META_URL,
|
||||
array_merge(
|
||||
$common,
|
||||
array(
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => array( __CLASS__, 'sanitize_external_url' ),
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
foreach ( array( self::META_CLIENT, self::META_LINK_LABEL ) as $meta_key ) {
|
||||
register_post_meta(
|
||||
self::POST_TYPE,
|
||||
$meta_key,
|
||||
array_merge(
|
||||
$common,
|
||||
array(
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
register_post_meta(
|
||||
self::POST_TYPE,
|
||||
self::META_YEAR,
|
||||
array_merge(
|
||||
$common,
|
||||
array(
|
||||
'type' => 'integer',
|
||||
'sanitize_callback' => array( __CLASS__, 'sanitize_year' ),
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
register_post_meta(
|
||||
self::POST_TYPE,
|
||||
self::META_FEATURED,
|
||||
array_merge(
|
||||
$common,
|
||||
array(
|
||||
'type' => 'boolean',
|
||||
'sanitize_callback' => 'rest_sanitize_boolean',
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
register_post_meta(
|
||||
self::POST_TYPE,
|
||||
self::META_ACCENT,
|
||||
array_merge(
|
||||
$common,
|
||||
array(
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => 'sanitize_hex_color',
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restrict meta updates to users who can edit the project.
|
||||
*
|
||||
* @param bool $allowed Current authorization result.
|
||||
* @param string $meta_key Meta key.
|
||||
* @param int $post_id Project ID.
|
||||
* @return bool
|
||||
*/
|
||||
public static function authorize_meta( $allowed, $meta_key, $post_id ) {
|
||||
unset( $allowed, $meta_key );
|
||||
|
||||
return current_user_can( 'edit_post', (int) $post_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow only valid external HTTP(S) URLs.
|
||||
*
|
||||
* @param mixed $value Raw URL.
|
||||
* @return string
|
||||
*/
|
||||
public static function sanitize_external_url( $value ) {
|
||||
$url = esc_url_raw( trim( (string) $value ), array( 'http', 'https' ) );
|
||||
|
||||
return $url && wp_http_validate_url( $url ) ? $url : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a four-digit project year.
|
||||
*
|
||||
* @param mixed $value Raw year.
|
||||
* @return int
|
||||
*/
|
||||
public static function sanitize_year( $value ) {
|
||||
$year = absint( $value );
|
||||
$max_year = (int) gmdate( 'Y' ) + 5;
|
||||
|
||||
return $year >= 1900 && $year <= $max_year ? $year : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the project details metabox.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function add_meta_boxes() {
|
||||
add_meta_box(
|
||||
'gso-project-details',
|
||||
__( 'Detalhes do projeto', 'gustavoo-portfolio-core' ),
|
||||
array( __CLASS__, 'render_meta_box' ),
|
||||
self::POST_TYPE,
|
||||
'normal',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render project fields.
|
||||
*
|
||||
* @param WP_Post $post Current project.
|
||||
* @return void
|
||||
*/
|
||||
public static function render_meta_box( $post ) {
|
||||
$url = (string) get_post_meta( $post->ID, self::META_URL, true );
|
||||
$client = (string) get_post_meta( $post->ID, self::META_CLIENT, true );
|
||||
$year = absint( get_post_meta( $post->ID, self::META_YEAR, true ) );
|
||||
$featured = (bool) get_post_meta( $post->ID, self::META_FEATURED, true );
|
||||
$link_label = (string) get_post_meta( $post->ID, self::META_LINK_LABEL, true );
|
||||
$accent = sanitize_hex_color( get_post_meta( $post->ID, self::META_ACCENT, true ) );
|
||||
|
||||
if ( ! $accent ) {
|
||||
$accent = '#7cf3da';
|
||||
}
|
||||
|
||||
wp_nonce_field( 'gso_save_project_details', 'gso_project_details_nonce' );
|
||||
?>
|
||||
<table class="form-table" role="presentation">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row"><label for="gso-project-url"><?php esc_html_e( 'URL externa', 'gustavoo-portfolio-core' ); ?></label></th>
|
||||
<td>
|
||||
<input class="regular-text" id="gso-project-url" name="gso_project_url" type="url" value="<?php echo esc_attr( $url ); ?>" inputmode="url" placeholder="https://">
|
||||
<p class="description"><?php esc_html_e( 'Aceita somente uma URL completa usando HTTP ou HTTPS.', 'gustavoo-portfolio-core' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="gso-project-client"><?php esc_html_e( 'Cliente ou marca', 'gustavoo-portfolio-core' ); ?></label></th>
|
||||
<td><input class="regular-text" id="gso-project-client" name="gso_project_client" type="text" value="<?php echo esc_attr( $client ); ?>" maxlength="160"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="gso-project-year"><?php esc_html_e( 'Ano', 'gustavoo-portfolio-core' ); ?></label></th>
|
||||
<td><input class="small-text" id="gso-project-year" name="gso_project_year" type="number" value="<?php echo $year ? esc_attr( (string) $year ) : ''; ?>" min="1900" max="<?php echo esc_attr( (string) ( (int) gmdate( 'Y' ) + 5 ) ); ?>" step="1"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="gso-project-link-label"><?php esc_html_e( 'Texto do CTA', 'gustavoo-portfolio-core' ); ?></label></th>
|
||||
<td><input class="regular-text" id="gso-project-link-label" name="gso_project_link_label" type="text" value="<?php echo esc_attr( $link_label ); ?>" maxlength="80" placeholder="<?php esc_attr_e( 'Ver projeto', 'gustavoo-portfolio-core' ); ?>"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="gso-project-accent"><?php esc_html_e( 'Cor de acento', 'gustavoo-portfolio-core' ); ?></label></th>
|
||||
<td><input id="gso-project-accent" name="gso_project_accent" type="color" value="<?php echo esc_attr( $accent ); ?>"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><?php esc_html_e( 'Destaque', 'gustavoo-portfolio-core' ); ?></th>
|
||||
<td>
|
||||
<label for="gso-project-featured">
|
||||
<input id="gso-project-featured" name="gso_project_featured" type="checkbox" value="1" <?php checked( $featured ); ?>>
|
||||
<?php esc_html_e( 'Exibir entre os projetos em destaque', 'gustavoo-portfolio-core' ); ?>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Save project fields after nonce and capability checks.
|
||||
*
|
||||
* @param int $post_id Project ID.
|
||||
* @return void
|
||||
*/
|
||||
public static function save_meta_box( $post_id ) {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Verified immediately below.
|
||||
$nonce = isset( $_POST['gso_project_details_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['gso_project_details_nonce'] ) ) : '';
|
||||
|
||||
if ( ! $nonce || ! wp_verify_nonce( $nonce, 'gso_save_project_details' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || wp_is_post_revision( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( self::POST_TYPE !== get_post_type( $post_id ) || ! current_user_can( 'edit_post', $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Missing -- Nonce verified above.
|
||||
$url = isset( $_POST['gso_project_url'] ) ? self::sanitize_external_url( wp_unslash( $_POST['gso_project_url'] ) ) : '';
|
||||
$client = isset( $_POST['gso_project_client'] ) ? sanitize_text_field( wp_unslash( $_POST['gso_project_client'] ) ) : '';
|
||||
$year = isset( $_POST['gso_project_year'] ) ? self::sanitize_year( wp_unslash( $_POST['gso_project_year'] ) ) : 0;
|
||||
$link_label = isset( $_POST['gso_project_link_label'] ) ? sanitize_text_field( wp_unslash( $_POST['gso_project_link_label'] ) ) : '';
|
||||
$accent = isset( $_POST['gso_project_accent'] ) ? sanitize_hex_color( wp_unslash( $_POST['gso_project_accent'] ) ) : '';
|
||||
$featured = isset( $_POST['gso_project_featured'] ) ? '1' : '';
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
||||
|
||||
self::update_or_delete_meta( $post_id, self::META_URL, $url );
|
||||
self::update_or_delete_meta( $post_id, self::META_CLIENT, $client );
|
||||
self::update_or_delete_meta( $post_id, self::META_YEAR, $year );
|
||||
self::update_or_delete_meta( $post_id, self::META_LINK_LABEL, $link_label );
|
||||
self::update_or_delete_meta( $post_id, self::META_ACCENT, $accent );
|
||||
self::update_or_delete_meta( $post_id, self::META_FEATURED, $featured );
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a non-empty value, otherwise remove the metadata row.
|
||||
*
|
||||
* @param int $post_id Project ID.
|
||||
* @param string $meta_key Metadata key.
|
||||
* @param mixed $value Sanitized value.
|
||||
* @return void
|
||||
*/
|
||||
private static function update_or_delete_meta( $post_id, $meta_key, $value ) {
|
||||
if ( '' === $value || 0 === $value || null === $value ) {
|
||||
delete_post_meta( $post_id, $meta_key );
|
||||
return;
|
||||
}
|
||||
|
||||
update_post_meta( $post_id, $meta_key, $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Define project list columns.
|
||||
*
|
||||
* @param array<string, string> $columns Existing columns.
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function admin_columns( $columns ) {
|
||||
return array(
|
||||
'cb' => $columns['cb'] ?? '<input type="checkbox">',
|
||||
'gso_thumbnail' => __( 'Imagem', 'gustavoo-portfolio-core' ),
|
||||
'title' => __( 'Projeto', 'gustavoo-portfolio-core' ),
|
||||
'gso_client' => __( 'Cliente', 'gustavoo-portfolio-core' ),
|
||||
'gso_type' => __( 'Tipo', 'gustavoo-portfolio-core' ),
|
||||
'gso_tech' => __( 'Tecnologias', 'gustavoo-portfolio-core' ),
|
||||
'gso_year' => __( 'Ano', 'gustavoo-portfolio-core' ),
|
||||
'gso_featured' => __( 'Destaque', 'gustavoo-portfolio-core' ),
|
||||
'gso_url' => __( 'URL', 'gustavoo-portfolio-core' ),
|
||||
'gso_menu_order' => __( 'Ordem', 'gustavoo-portfolio-core' ),
|
||||
'date' => $columns['date'] ?? __( 'Data', 'gustavoo-portfolio-core' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render one project list cell.
|
||||
*
|
||||
* @param string $column Column ID.
|
||||
* @param int $post_id Project ID.
|
||||
* @return void
|
||||
*/
|
||||
public static function render_admin_column( $column, $post_id ) {
|
||||
switch ( $column ) {
|
||||
case 'gso_thumbnail':
|
||||
if ( has_post_thumbnail( $post_id ) ) {
|
||||
echo wp_kses_post( get_the_post_thumbnail( $post_id, array( 64, 48 ), array( 'style' => 'width:64px;height:48px;object-fit:cover;border-radius:4px;' ) ) );
|
||||
} else {
|
||||
echo '<span aria-hidden="true">—</span><span class="screen-reader-text">' . esc_html__( 'Sem imagem', 'gustavoo-portfolio-core' ) . '</span>';
|
||||
}
|
||||
break;
|
||||
case 'gso_client':
|
||||
echo esc_html( (string) get_post_meta( $post_id, self::META_CLIENT, true ) ?: '—' );
|
||||
break;
|
||||
case 'gso_type':
|
||||
self::render_terms_column( $post_id, self::TAX_TYPE );
|
||||
break;
|
||||
case 'gso_tech':
|
||||
self::render_terms_column( $post_id, self::TAX_TECH );
|
||||
break;
|
||||
case 'gso_year':
|
||||
$year = absint( get_post_meta( $post_id, self::META_YEAR, true ) );
|
||||
echo $year ? esc_html( (string) $year ) : '—';
|
||||
break;
|
||||
case 'gso_featured':
|
||||
if ( get_post_meta( $post_id, self::META_FEATURED, true ) ) {
|
||||
echo '<span class="dashicons dashicons-star-filled" aria-hidden="true"></span><span class="screen-reader-text">' . esc_html__( 'Sim', 'gustavoo-portfolio-core' ) . '</span>';
|
||||
} else {
|
||||
echo '<span aria-hidden="true">—</span><span class="screen-reader-text">' . esc_html__( 'Não', 'gustavoo-portfolio-core' ) . '</span>';
|
||||
}
|
||||
break;
|
||||
case 'gso_url':
|
||||
$url = self::sanitize_external_url( get_post_meta( $post_id, self::META_URL, true ) );
|
||||
if ( $url ) {
|
||||
$host = wp_parse_url( $url, PHP_URL_HOST );
|
||||
printf(
|
||||
'<a href="%1$s" target="_blank" rel="noopener noreferrer external">%2$s<span class="screen-reader-text"> %3$s</span></a>',
|
||||
esc_url( $url ),
|
||||
esc_html( $host ?: $url ),
|
||||
esc_html__( '(abre em nova aba)', 'gustavoo-portfolio-core' )
|
||||
);
|
||||
} else {
|
||||
echo '—';
|
||||
}
|
||||
break;
|
||||
case 'gso_menu_order':
|
||||
echo esc_html( (string) get_post_field( 'menu_order', $post_id ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render taxonomy terms in an admin column.
|
||||
*
|
||||
* @param int $post_id Project ID.
|
||||
* @param string $taxonomy Taxonomy name.
|
||||
* @return void
|
||||
*/
|
||||
private static function render_terms_column( $post_id, $taxonomy ) {
|
||||
$terms = get_the_terms( $post_id, $taxonomy );
|
||||
|
||||
if ( ! $terms || is_wp_error( $terms ) ) {
|
||||
echo '—';
|
||||
return;
|
||||
}
|
||||
|
||||
echo esc_html( implode( ', ', wp_list_pluck( $terms, 'name' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Make selected columns sortable.
|
||||
*
|
||||
* @param array<string, string> $columns Existing sortable columns.
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function sortable_columns( $columns ) {
|
||||
$columns['gso_client'] = 'gso_client';
|
||||
$columns['gso_year'] = 'gso_year';
|
||||
$columns['gso_featured'] = 'gso_featured';
|
||||
$columns['gso_menu_order'] = 'menu_order';
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply safe sorting to the main project admin query.
|
||||
*
|
||||
* @param WP_Query $query Current query.
|
||||
* @return void
|
||||
*/
|
||||
public static function apply_admin_sorting( $query ) {
|
||||
if ( ! is_admin() || ! $query->is_main_query() || self::POST_TYPE !== $query->get( 'post_type' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( $query->get( 'orderby' ) ) {
|
||||
case 'gso_client':
|
||||
$query->set( 'meta_key', self::META_CLIENT );
|
||||
$query->set( 'orderby', 'meta_value' );
|
||||
break;
|
||||
case 'gso_year':
|
||||
$query->set( 'meta_key', self::META_YEAR );
|
||||
$query->set( 'orderby', 'meta_value_num' );
|
||||
break;
|
||||
case 'gso_featured':
|
||||
$query->set( 'meta_key', self::META_FEATURED );
|
||||
$query->set( 'orderby', 'meta_value_num' );
|
||||
break;
|
||||
case 'menu_order':
|
||||
$query->set( 'orderby', 'menu_order title' );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add type and technology filters above the project list.
|
||||
*
|
||||
* @param string $post_type Current list post type.
|
||||
* @return void
|
||||
*/
|
||||
public static function taxonomy_filters( $post_type ) {
|
||||
if ( self::POST_TYPE !== $post_type ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( array( self::TAX_TYPE, self::TAX_TECH ) as $taxonomy ) {
|
||||
$tax_object = get_taxonomy( $taxonomy );
|
||||
if ( ! $tax_object ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only list filter.
|
||||
$selected = isset( $_GET[ $taxonomy ] ) ? sanitize_title( wp_unslash( $_GET[ $taxonomy ] ) ) : '';
|
||||
|
||||
wp_dropdown_categories(
|
||||
array(
|
||||
'show_option_all' => sprintf(
|
||||
/* translators: %s: taxonomy label. */
|
||||
__( 'Todos: %s', 'gustavoo-portfolio-core' ),
|
||||
$tax_object->labels->name
|
||||
),
|
||||
'taxonomy' => $taxonomy,
|
||||
'name' => $taxonomy,
|
||||
'orderby' => 'name',
|
||||
'selected' => $selected,
|
||||
'hide_empty' => false,
|
||||
'hierarchical' => $tax_object->hierarchical,
|
||||
'value_field' => 'slug',
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user