<?php 
/**
 * The main CustomPostType Class. You need to extend this class in order to
 * use it.
 *
 * @package CustomPostType
 * @author Erwan Guillon <erwan@ayctor.com>
 */
namespace CustomPostType;

/**
 * The main CustomPostType Class. You need to extend this class in order to
 * use it.
 */
class CPT{

  /**
   * Internal name for the custom post type
   * @var string
   */
  public $internal_name = '';

  /**
   * Main display name for the custom post type. It tries to generate all the
   * other labels from this one.
   * @var string
   */
  public $name = '';

  /**
   * List of labels for the custom post type.
   * @see https://codex.wordpress.org/Function_Reference/register_post_type
   * for more information on labels
   * @var string[]
   */
  public $labels = array();

  /**
   * Custom post type arguments for register_post_type function
   * @see https://codex.wordpress.org/Function_Reference/register_post_type
   * for more informations on arguments
   * @var array
   */
  public $cpt_args = array(
    'public' => true,
    'publicly_queryable' => true,
    'exclude_from_search' => false,
    'show_ui' => true,
    'show_in_menu' => true,
    'show_in_nav_menus' => true,
    'query_var' => true,
    'capability_type' => 'post',
    'has_archive' => true,
    'hierarchical' => false,
    'menu_icon' => 'dashicons-carrot',
    'rewrite' => true,
    'menu_position' => null,
    'supports' => array('title', 'editor')
  );
  
  /**
   * Contains meta boxes informations when using addMetaBoxes function
   * @var array
   */
  public $meta_boxes = array();

  /**
   * Contains meta fields information
   * @var array
   */
  public $meta_fields = array();

  /**
   * Contains Custom columns
   * @var array
   */
  public $custom_columns = array();

  /**
   * Contains sortable Columns
   * @var array
   */
  public $sortable_columns = array();

  /**
   * Containes Columns display
   * @var array
   */
  public $custom_columns_show = array();

  /**
   * Construct CPT
   */
  public function __construct(){

    if( count($this->labels) > 0 ){
      $this->cpt_args['labels'] = $this->labels;
    } else {
      $this->cpt_args['label'] = $this->name;
    }
    $this->cpt_args['register_meta_box_cb'] = array($this, 'meta_box_cb');

    add_action('init', array($this, 'init'));
    add_action('save_post', array($this, 'meta_box_save'));

    add_filter('manage_edit-' . $this->internal_name . '_columns', array($this, 'custom_columns'));
    add_action('manage_posts_custom_column', array($this, 'custom_columns_show'));
    add_filter('manage_edit-' . $this->internal_name . '_sortable_columns', array($this, 'custom_columns_sort'));
  }

  /**
   * Init the register_post_type function
   * @return void
   */
  public function init(){

    register_post_type($this->internal_name, $this->cpt_args);

  }

  /**
   * Add a metabox to the CustomePostType admin editor
   * @param string  $id    Id of the metabox, must be unique
   * @param string  $title Tile of the metabox
   * @param integer $order Order for all the custom meta boxes
   */
  public function addMetaBoxes($id, $title, $order = 100){
    $this->meta_boxes[] = array('id' => $id, 'title' => $title, 'order' => $order);
  }

  /**
   * Add a field to a custom metabox
   * @param string $id       Field's id, must be unique. It will be the meta
   * key.
   * @param string $label    Label for admin editing
   * @param string $meta_box Custom metaboxe's id
   * @param string $type     Field type
   * (editor|text|date|time|file|textarea|select|number)
   * @param array  $options  List of options for select with key => value
   */
  public function addField($id, $label, $meta_box, $type, $options = array()){
    if(!isset($this->meta_fields[$meta_box])) $this->meta_fields[$meta_box] = array();
    $this->meta_fields[$meta_box][] = array('id' => $id, 'label' => $label, 'type' => $type, 'options' => $options);
  }

  /**
   * Add a custom column for the listing page
   * @param string  $id    Column's id, must be unique
   * @param string  $label Column's name
   * @param boolean $sort  Is the column sortable
   * @param boolean $type  The type of the content to display
   * (editor|text|date|time|file|textarea|select|number)
   */
  public function addCustomColumn($id, $label, $sort, $type = false){
    $this->custom_columns[$id] = __($label);
    if($sort){
      $this->sortable_columns[$id] = $id;
    }
    if($type){
      $this->custom_columns_show[] = array('id' => $id, 'type' => $type);
    }
  }

  /**
   * Register the meta boxes
   */
  public function meta_box_cb(){
    foreach($this->meta_boxes as $mb){
      if(isset($this->meta_fields[$mb['id']])){
        add_meta_box($mb['id'], $mb['title'], array($this, 'meta_box_html'), $this->internal_name, 'normal', 'default');
      }
    }
  }

  /**
   * Display the meta box html
   * @param  WP_Post $post Current post
   * @param  array $args Additional arguments
   */
  public function meta_box_html($post, $args){
    wp_nonce_field( plugin_basename( __FILE__ ), $this->internal_name );
    ?>
    <table class="form-table">
    <?php foreach($this->meta_fields[$args['id']] as $field) : ?>
      <tr>
        <th scope="row">
          <label for="<?php echo $field['id']; ?>"><?php echo $field['label']; ?></label>
        </th>
        <td <?php if ($field['type'] == 'editor'): ?>width="100%"<?php endif; ?>>
          <?php if($field['type'] == 'text') : ?>
            <input type="text" class="regular-text" id="<?php echo $field['id']; ?>" name="<?php echo $field['id']; ?>" value="<?php echo get_post_meta($post->ID, $field['id'], true); ?>">
          <?php elseif($field['type'] == 'date') : ?>
            <input type="text" class="regular-text aycpt-datepicker" id="<?php echo $field['id']; ?>" name="<?php echo $field['id']; ?>" value="<?php echo get_post_meta($post->ID, $field['id'], true); ?>">
          <?php elseif($field['type'] == 'time') : ?>
            <input type="time" class="regular-text" id="<?php echo $field['id']; ?>" name="<?php echo $field['id']; ?>" value="<?php echo get_post_meta($post->ID, $field['id'], true); ?>">
          <?php elseif($field['type'] == 'file') : ?>
            <input type="hidden" value="<?php echo get_post_meta($post->ID, $field['id'], true); ?>" id="<?php echo $field['id']; ?>" name="<?php echo $field['id']; ?>">
            <span class="filename">
            <?php if(get_post_meta($post->ID, $field['id'], true) != '') : ?>
            <a href="<?php echo wp_get_attachment_url( get_post_meta($post->ID, $field['id'], true) ); ?> " target="_blank"><?php echo get_the_title(get_post_meta($post->ID, $field['id'], true)); ?></a> -
            <?php endif; ?>
            </span>
            <a href="#addfile" data-target="<?php echo $field['id']; ?>" data-label="<?php echo $field['label']; ?>" class="addfile">Ajouter le fichier</a>
          <?php elseif($field['type'] == 'textarea') : ?>
            <textarea id="<?php echo $field['id']; ?>" name="<?php echo $field['id']; ?>" rows="5" cols="100"><?php echo get_post_meta($post->ID, $field['id'], true); ?></textarea>
          <?php elseif($field['type'] == 'select') : ?>
            <select id="<?php echo $field['id']; ?>" name="<?php echo $field['id']; ?>">
              <?php foreach ($field['options'] as $key => $value): ?>
                <option value="<?php echo $key; ?>" <?php if (get_post_meta($post->ID, $field['id'], true) == $key): ?>selected<?php endif ?>><?php echo $value; ?></option>
              <?php endforeach ?>
            </select>
          <?php elseif ($field['type'] == 'number'): ?>
            <input type="number" class="regular-text" id="<?php echo $field['id']; ?>" name="<?php echo $field['id']; ?>" value="<?php echo get_post_meta($post->ID, $field['id'], true); ?>">
          <?php elseif ($field['type'] == 'editor'): ?>
            <?php wp_editor( get_post_meta($post->ID, $field['id'], true), $field['id'], array('textarea_rows' => 5) ); ?>
          <?php else : ?>
            <?php _e('Unknown input type'); ?> <?php echo $field['type']; ?>
          <?php endif; ?>
        </td>
      </tr>
    <?php endforeach; ?>
    </table>
    <?php
  }

  /**
   * When the save action is triggered, we save the meta data
   * @param integer $post_id Current post id
   */
  public function meta_box_save($post_id){
    if (!is_user_logged_in())
      return;

    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
      return;

    if (!isset($_POST[$this->internal_name]) OR  !wp_verify_nonce( $_POST[$this->internal_name], plugin_basename( __FILE__ ) ) )
      return;

    if($this->internal_name == $_POST['post_type']) {
      if ( !current_user_can( 'edit_post', $post_id ) )
        return;
    } else return;


    foreach($this->meta_fields as $mfb){
      foreach ($mfb as $mf) {
        if(isset($_POST[$mf['id']])){
          update_post_meta($post_id, $mf['id'], $_POST[$mf['id']]);
        } else {
          delete_post_meta($post_id, $mf['id']);
        }
      }
    }
  }

  /**
   * Change the columns when listings the custom post
   * @param array $columns Contains default columns to display
   * @return array Columns to display
   */
  public function custom_columns($columns) {
    if(count($this->custom_columns) > 0){
      return $this->custom_columns;
    } else {
      return $columns;
    }
  }

  /**
   * Define the sortable columns
   * @param array $columns Array of string for column's name
   * @return array Formatted array for sorting columns
   */
  public function custom_columns_sort($columns) {
    return $this->sortable_columns;
  }

  /**
   * Define the content for custom columns
   * @param array $name Array of name for columns to display
   */
  public function custom_columns_show($name) {
    global $post;
    foreach ($this->custom_columns_show as $show) {
      switch ($show['type']) {
        case 'term':
          if ($name == $show['id']) {
            $terms = get_the_term_list( $post->ID, $show['id'], '', ',', '' );
            if ( is_string( $terms ) ) {
              echo $terms;
            } else {
              echo '-';
            }
          }
        break;
        case 'meta':
          if ($name == $show['id']) {
            echo get_post_meta( $post->ID, $show['id'], true );
          }
        break;
      }
    }
  }

  /**
   * Init the actions for admin scripts and styles
   */
  public static function initAdmin(){
    add_action('admin_enqueue_scripts', array(__CLASS__, 'adminScripts'));
    add_action('admin_print_styles', array(__CLASS__, 'adminStyles'), 11 );
  }

  /**
   * Enqueue admin scripts
   */
  public static function adminScripts() {
    wp_enqueue_media();
    wp_enqueue_script( 'ayadminjs', get_template_directory_uri() . '/vendor/ayctor/cpt/assets/cpt.min.js', array( 'jquery', 'jquery-ui-datepicker', 'media-upload', 'thickbox' ) );
  }

  /**
   * Anqueue admin styles
   */
  public static function adminStyles() {
    wp_enqueue_style('aycptcss', get_template_directory_uri() . '/vendor/ayctor/cpt/assets/cpt.min.css');
    wp_enqueue_style('jquery-style', get_template_directory_uri() . '/vendor/ayctor/cpt/assets/jquery-ui.min.css');
  }

}
