Ejemplo n.º 1
0
 public function plural_label() {
   $item = $this->item;
   
   if ($item) {
     
     if (isset($item->labels->name) && $item->labels->name != "" && $item->labels->name != $item->name) {
       return WOOF_Inflector::titleize($item->labels->name);
     } else {
       return WOOF_Inflector::titleize(WOOF_Inflector::pluralize($item->name));
     }
     
   }
   
   return "";
 }
Ejemplo n.º 2
0
	public static function init() {
    
    global $meow_provider;
    
    load_plugin_textdomain( MASTERPRESS_DOMAIN, false, "masterpress/languages" );
    
    do_action("mp_pre_init");

    self::$cap_mode = get_site_option("mp_cap", "standard");
    
    global $wf;
    
    global $wpdb;
    
    $snp = explode("/", $_SERVER["SCRIPT_NAME"]);
    
    self::$script = basename($snp[count($snp) - 1], ".php");
    
    
    // Register useful libraries separately, so they may be used by themes

    if (WP_DEBUG || MASTERPRESS_DEBUG) {
    
      // legacy picturefill
      wp_register_script('mp-matchmedia',      MASTERPRESS_URL.'js/src/matchmedia.js',                 array(), MASTERPRESS_VERSION);
      wp_register_script('mp-picturefill',     MASTERPRESS_URL.'js/src/picturefill.js',                array('jquery', 'mp-matchmedia'), MASTERPRESS_VERSION);
      

      wp_register_script('jquery-imageload', MASTERPRESS_URL.'js/src/jquery.imageload.js',             array('jquery'), MASTERPRESS_VERSION);
      // new jQuery picturefill
      wp_register_script('jquery-picturefill', MASTERPRESS_URL.'js/src/jquery.picturefill.js',         array('jquery', 'jquery-imageload'), MASTERPRESS_VERSION);

      wp_register_script('jquery-lazyload',    MASTERPRESS_URL.'js/src/jquery.lazyload.js',            array('jquery'), MASTERPRESS_VERSION);
      
      wp_register_script('jquery-fancybox',    MASTERPRESS_URL.'js/src/jquery.fancybox-1.3.4.js',      array('jquery'), MASTERPRESS_VERSION);
      wp_register_script('jquery-scroll-to',   MASTERPRESS_URL.'js/src/jquery.scroll-to.js',           array('jquery'), MASTERPRESS_VERSION);
      wp_register_script('jquery-metadata',    MASTERPRESS_URL.'js/src/jquery.metadata.js',            array('jquery'), MASTERPRESS_VERSION);
      wp_register_script('select2',            MASTERPRESS_URL.'js/src/select2.js',                    array('jquery'), MASTERPRESS_VERSION);
      
      wp_register_script('codemirror',         MASTERPRESS_URL.'js/src/codemirror.js',                 array(), MASTERPRESS_VERSION);
      wp_register_script('codemirror-modes',   MASTERPRESS_URL.'js/codemirror.modes.min.js',           array(), MASTERPRESS_VERSION);
      wp_register_script('mediaelement',      MASTERPRESS_URL.'js/src/mediaelement-and-player.js',     array(), MASTERPRESS_VERSION);
      wp_register_script('handlebars',         MASTERPRESS_URL.'js/src/handlebars-1.0.0.beta.6.js',    array(), MASTERPRESS_VERSION);
      wp_register_script('inflection',         MASTERPRESS_URL.'js/src/inflection.js',                 array(), MASTERPRESS_VERSION);
      wp_register_script('date-js',            MASTERPRESS_URL.'js/src/date.js',                       array(), MASTERPRESS_VERSION);
      
      wp_register_script('mp-iris',     	   MASTERPRESS_URL.'js/src/iris.js',                	   array('jquery', "jquery-ui-core", "jquery-ui-widget"), MASTERPRESS_VERSION);
    
    } else {

      // legacy picturefill (not enqueued)
      wp_register_script('mp-matchmedia',      MASTERPRESS_URL.'js/matchmedia.min.js',                 array(), MASTERPRESS_VERSION);
      wp_register_script('mp-picturefill',     MASTERPRESS_URL.'js/picturefill.min.js',                array('jquery', 'mp-matchmedia'), MASTERPRESS_VERSION);

      wp_register_script('jquery-imageload', MASTERPRESS_URL.'js/jquery.imageload.min.js',             array('jquery'), MASTERPRESS_VERSION);

      // new jQuery picturefill
      wp_register_script('jquery-picturefill', MASTERPRESS_URL.'js/jquery.picturefill.min.js',         array('jquery', 'jquery-imageload'), MASTERPRESS_VERSION);

      wp_register_script('jquery-lazyload',    MASTERPRESS_URL.'js/jquery.lazyload.min.js',            array('jquery'), MASTERPRESS_VERSION);

      wp_register_script('jquery-fancybox',    MASTERPRESS_URL.'js/jquery.fancybox-1.3.4.min.js',      array('jquery'), MASTERPRESS_VERSION);
      wp_register_script('jquery-scroll-to',   MASTERPRESS_URL.'js/jquery.scroll-to.min.js',           array('jquery'), MASTERPRESS_VERSION);
      wp_register_script('jquery-metadata',    MASTERPRESS_URL.'js/jquery.metadata.min.js',            array('jquery'), MASTERPRESS_VERSION);
      wp_register_script('select2',            MASTERPRESS_URL.'js/select2.min.js',                    array('jquery'), MASTERPRESS_VERSION);
      wp_register_script('date-js',            MASTERPRESS_URL.'js/date.min.js',                       array(), MASTERPRESS_VERSION);

      wp_register_script('mediaelement',       MASTERPRESS_URL.'js/mediaelement-and-player.min.js',    array(), MASTERPRESS_VERSION);
      wp_register_script('codemirror',         MASTERPRESS_URL.'js/codemirror.min.js',                 array(), MASTERPRESS_VERSION);
      wp_register_script('codemirror-modes',   MASTERPRESS_URL.'js/codemirror.modes.min.js',           array(), MASTERPRESS_VERSION);
      wp_register_script('handlebars',         MASTERPRESS_URL.'js/handlebars-1.0.0.beta.6.min.js',    array(), MASTERPRESS_VERSION);
      wp_register_script('inflection',         MASTERPRESS_URL.'js/inflection.min.js',                 array(), MASTERPRESS_VERSION);

      if (!self::has_iris()) {
        wp_register_script('mp-iris',     	   MASTERPRESS_URL.'js/iris.min.js',                	   array('jquery', "jquery-ui-core", "jquery-ui-widget"), MASTERPRESS_VERSION);
      }
    }
    
    
    wp_register_style('jquery-fancybox',       MASTERPRESS_URL.'css/fancybox.css',                    array(), MASTERPRESS_VERSION);
    wp_register_style('select2',               MASTERPRESS_URL.'css/select2.css',                     array(), MASTERPRESS_VERSION);
    wp_register_style('codemirror',            MASTERPRESS_URL.'css/codemirror.css',                  array(), MASTERPRESS_VERSION);
    wp_register_style('codemirror-themes',     MASTERPRESS_URL.'css/codemirror.themes.min.css',       array(), MASTERPRESS_VERSION);
    wp_register_style('mediaelement',          MASTERPRESS_URL.'css/mediaelementplayer.min.css',      array(), MASTERPRESS_VERSION);

    
    
    if ( is_admin() ) {

      // run an upgrade (if required)

      MasterPress::upgrade();

      if (defined('MASTERPRESS_NO_UPLOAD_DIR')) {

        MPV::err( 
          sprintf(  
            __( "<b>Important: </b>When trying to determine the location of your uploads directory, WordPress reported the following error: <code>%s</code>That is, your WordPress installation <b>does not currently contain a writable uploads directory</b>, so MasterPress will not function correctly as it cannot create its own required sub-folders.<br>To avoid further problems, you must correct this before creating or editing anything with MasterPress.<br>", MASTERPRESS_DOMAIN ),
            MASTERPRESS_NO_UPLOAD_DIR
          )
        );
        
      } else {
        self::create_directories();
      }
      
      add_action('admin_menu', array('MasterPress', 'admin_menu'));

      wp_enqueue_script("jquery-lazyload");
      wp_enqueue_script("jquery-imageload");
      wp_enqueue_script("jquery-picturefill");
      

      // Add filters for specific screens
      
      if (self::$script == "options-reading") {
        add_filter( 'get_pages',  array("MasterPress", 'add_front_page_supports' ) );
      }
      
      if (self::is_user_editor()) {
        add_filter( 'mce_external_plugins', array( "MasterPress", 'mce_plugins' ) );
        MPC::incl("user");
        add_action( 'show_user_profile', array("MPC_User", "field_sets" ));
        add_action( 'edit_user_profile', array("MPC_User", "field_sets" ));
      }
      
      if (self::is_term_editor() || self::is_term_manage()) {
        MPC::incl("term");
        if (isset($_GET["taxonomy"])) {
          $taxonomy = $_GET["taxonomy"];
        }
      }
      
      if (self::is_term_editor()) {
        add_filter( 'mce_external_plugins', array( "MasterPress", 'mce_plugins' ) );
        // add field UI hook
        add_action( $taxonomy."_edit_form_fields", array("MPC_Term", "field_sets"), 10, 2 );
      }

      if (self::is_term_manage()) {
        add_filter( 'mce_external_plugins', array( "MasterPress", 'mce_plugins' ) );
        // add field UI hook
        add_action( $taxonomy."_add_form_fields", array("MPC_Term", "field_sets"), 10, 2 );
      }
      
      if (self::is_site_content_editor()) {
        MPV::incl("meta");
        MPC::incl("meta");
        add_filter( 'mce_external_plugins', array( "MasterPress", 'mce_plugins' ) );
      }
      
      if (self::is_post_editor()) {
        add_filter( 'mce_external_plugins', array( "MasterPress", 'mce_plugins' ) );
			  add_action('add_meta_boxes', array('MPC_Post', 'post_editor_meta_boxes'));
        add_action('admin_init', array('MasterPress', 'admin_init'));
		  }

      if (self::is_post_manage()) {
        add_filter("manage_posts_columns", array("MPC_Post", "define_post_columns"));
        add_filter("manage_pages_columns", array("MPC_Post", "define_post_columns"));
        add_action("manage_posts_custom_column", array("MPC_Post", "post_column_content"));
        add_action("manage_pages_custom_column", array("MPC_Post", "post_column_content"));
        add_filter('parse_query', array("MPC_Post", "filter_manage_posts"));
        add_filter('request', array("MPC_Post", "request"));
        
        $meow_provider->set_optimize_mode( "post_list" );
        
      }
      
      
      // add save hooks
      
      add_action('edited_term', array("MPC_Meta", 'save_term_meta') );
      add_action('created_term', array("MPC_Meta", 'save_term_meta') );
      add_action('save_post', array("MPC_Meta", 'save_post_meta'));
      add_action('personal_options_update', array("MPC_Meta", 'save_user_meta'));
      add_action('edit_user_profile_update', array("MPC_Meta", 'save_user_meta'));
      

      add_action('save_post', array("MasterPress", 'save_post'));

      // add inline scripts
      
      add_action("admin_head", array("MasterPress", "inline_scripts"));
      add_action("admin_head", array("MasterPress", "inline_styles"));
      add_action("admin_head", array("MasterPress", "inline_meta"));

    }

    

    // cache the list of all post types
    
    
    $args = array();
    
    if (is_admin()) {
      // only order by menu positions in the admin, as the order doesn't matter on the front-end (slightly faster)
      $args = array("orderby" => "menu_position,menu_sub_position");
    }

    $post_types = MPM_PostType::find($args);
    
    MasterPress::$post_types = array();

    foreach ($post_types as $post_type) {
      MasterPress::$post_types[$post_type->name] = $post_type;
    }

    $taxonomies = MPM_Taxonomy::find( );

    MasterPress::$all_taxonomies = array();
    
    MasterPress::$taxonomies = array();
    
    foreach ($taxonomies as $tax) {
      if (!$tax->disabled) {
        MasterPress::$taxonomies[$tax->name] = $tax;
      }

      MasterPress::$all_taxonomies[$tax->name] = $tax;
    
    }
    

    // create necessary file directories
    
    if (is_admin()) {
    
      $combine = false;
      
      // check for a querystring force
      if (isset($_GET["mpft"])) {
        $combine = true;
      }
      
      // check if debug mode had been switched on, then off (javascript "make" still needs to be run manually)

      $opt_debug = get_option("mp_debug");
      
      if (!MASTERPRESS_DEBUG && $opt_debug != MASTERPRESS_DEBUG) {
        $combine = true;
      }

      if ($opt_debug != MASTERPRESS_DEBUG) {
        update_option("mp_debug", MASTERPRESS_DEBUG);
      }

      if (!file_exists(MASTERPRESS_CONTENT_MPFT_CACHE_DIR."mpft-all.css")) {
        $combine = true;
      }

      if (!file_exists(MASTERPRESS_CONTENT_MPFT_CACHE_DIR."mpft-all.js")) {
        $combine = true;
      }
      

      if ($combine) {
        MPU::combine_type_styles();
        MPU::combine_type_scripts();
      }
      
    }
  

    if (self::is_term_manage()) {
      
      MPC::incl("term");

      add_filter('get_terms_args', array("MPC_Term", "filter_manage_terms"));

      foreach (MasterPress::$taxonomies as $tax) {
        add_filter('manage_edit-'.$tax->name.'_columns', array("MPC_Term", "define_term_columns"));
        add_action('manage_'.$tax->name.'_custom_column', array("MPC_Term", "term_column_content"), 10, 3);
      }
    
    }

    // register post types based on database entries

    do_action('mp_pre_register_post_types');

    self::register_post_types();

    do_action('mp_register_post_types');

    // register taxonomies based on database entries

    do_action('mp_pre_register_taxonomies');

    self::register_taxonomies();

    do_action('mp_pre_register_taxonomies');

    // patch template support
    
    self::register_template_support();
    
    
    do_action('mp_register');

    // look for externally defined post types, and insert models for them in MasterPress.
    
    $reg_post_types = $wf->post_types();

    $rpt_keys = array();
    $pt_keys = array();
	
    foreach ($reg_post_types as $rpt) {
      if (!is_woof_silent($rpt)) {
        $rpt_keys[$rpt->name] = $rpt;
      }
    }
    
    foreach ($post_types as $pt) {
      $pt_keys[$pt->name] = $pt;
    }
    
    $ignore_keys = array("revision", "nav_menu_item");
    
    foreach ($rpt_keys as $key => $pt) {
      
      if (!isset($pt_keys[$key]) && !in_array($key, $ignore_keys)) {

        // create an external post type database entry
        
        $ept = new MPM_PostType();
        
        // ensure that unknown properties return "null", not "WOOF_Silent"
        $pt->set_property_mode("standard");
        
        $ept->set(      
          array( 
            "name" => $pt->name,
            "plural_name" => WOOF_Inflector::pluralize($pt->name),
            "disabled" => false,
            "labels" => $pt->labels,
            "description" => "",
            "publicly_queryable" => (bool) $pt->publicly_queryable,
            "exclude_from_search" => (bool) $pt->exclude_from_search,
            "show_ui" => (bool) $pt->show_ui,
            "show_in_menu" => (bool) $pt->show_in_menu,
            "menu_position" => (int) $pt->menu_position,
            "menu_sub_position" => 0,
            "menu_icon" => isset($pt->menu_icon) ? $pt->menu_icon : "",
            "manage_sort_order" => "post_date|desc",
            "capability_type" => $pt->capability_type,
            "capabilities" => $pt->cap_array(),
            "map_meta_cap" => (bool) $pt->map_meta_cap,
            "hierarchical" => (bool) $pt->hierarchical,
            "supports" => implode(",", $pt->supports_keys()),
            "permalink_epmask" => $pt->permalink_epmask,
            "has_archive" => (bool) $pt->has_archive,
            "rewrite" => $pt->rewrite,
            "query_var" => $pt->query_var,
            "can_export" => $pt->can_export,
            "show_in_nav_menus" => $pt->show_in_nav_menus,
            "_builtin" => false,
            "_external" => true,
            "visibility" => array("sites" => "*") 
          )
        );
        
        $ept->insert();
        
        
        
      }
    }
    
    // look for externally defined taxonomies, and insert models for them in MasterPress.
    
    $reg_tax = $wf->taxonomies();

    $rt_keys = array();
    $t_keys = array();

    foreach ($reg_tax as $tax) {
      $rt_keys[$tax->name] = $tax;
    }
    
    foreach ($taxonomies as $tax) {
      $t_keys[$tax->name] = $tax;
    }
    
    $ignore_keys = array("nav_menu", "link_category", "post_format");
    
    foreach ($rt_keys as $key => $tax) {
      if (!isset($t_keys[$key]) && !in_array($key, $ignore_keys)) {

        // create an external post type database entry
        
        $et = new MPM_Taxonomy();
        
        // ensure that unknown properties return "null", not "WOOF_Silent"
        $tax->set_property_mode("standard");
        
        
        $et->set(      
          array( 
            "name" => $tax->name,
            "plural_name" => WOOF_Inflector::pluralize($tax->name),
            "labels" => $tax->labels,
            "disabled" => false,
            "show_in_nav_menus" => (bool) $tax->show_in_nav_menus,
            "show_ui" => (bool) $tax->show_ui,
            "show_tagcloud" => (bool) $tax->show_tagcloud,
            "hierarchical" => (bool) $tax->hierarchical,
            "rewrite" => $tax->rewrite,
            "update_count_callback" => $tax->update_count_callback,
            "query_var" => $tax->query_var,
            "capabilities" => $tax->cap_array(),
            "object_type" => $tax->object_type,
            "_builtin" => false,
            "_external" => true
          )
        );

        $et->insert();
        
      }
    }
    

    
    if (is_admin()) {
      self::dispatch();
    }
    
    foreach ($wf->types() as $type) {
      if ($type->supports("top-level-slugs")) {
        add_filter("woof_".$type->name."_permalink", array("MasterPress", "woof_permalink"), 100, 2);
      }
    }
    
    // if anyone rewrites URLs, add ours to the queue
    add_filter( 'rewrite_rules_array', array("MasterPress", 'add_rewrite_rules' ));

    do_action('mp_rewrite_rules');
    do_action('mp_pre_flush_rewrite_rules');

    add_rewrite_tag("%mp_rest_endpoint%", '([^&]+)');

    if (is_admin()) {
      // flush rewrite rules (only if marked as needed)
      MasterPress::flush_rewrite_rules();
    }
  
    if (is_admin() && MasterPress::current_user_can("manage_mp_tools")) {
      self::tools_actions();
    }
    
    do_action('mp_init');

  }
Ejemplo n.º 3
0
 /**
 * Converts a class name to its table name according to rails
 * naming conventions.
 * 
 * Converts "Person" to "people"
 * 
 * @access public
 * @static
 * @see classify
 * @param    string    $class_name    Class name for getting related table_name.
 * @return string plural_table_name
 */
 function tableize($class_name)
 {
     return WOOF_Inflector::pluralize(WOOF_Inflector::underscore($class_name));
 }
Ejemplo n.º 4
0
  public static function upload_dir($field) {
    
    global $wf;
    
    $dir = MASTERPRESS_CONTENT_DIR;

    $object_id = $_GET["object_id"];
    $object_type = $_GET["object_type"];
    $object_type_name = $_GET["object_type_name"];
    
    $sub = MASTERPRESS_CONTENT_UPLOADS_FOLDER.WOOF_DIR_SEP;
    
    if ($object_type == "post") {

      $object = $wf->post($object_id);

      if ($object) {
        $sub .= WOOF_Inflector::pluralize($object->type->name).WOOF_DIR_SEP;
      }
      
    } else if ($object_type == "term") {
      
      $object = $wf->term_by_id($object_id);
      
      if ($object) {
        
        if ($object_type_name != "") { 
          $sub .= WOOF_Inflector::pluralize($object_type_name).WOOF_DIR_SEP;
        } else if ($taxonomy = $object->taxonomy()) {
          $sub .= WOOF_Inflector::pluralize($taxonomy->name).WOOF_DIR_SEP;
        }
      }
      
    } else if ($object_type == "user") {

      $object = $wf->user($object_id);
      
      if ($object) {
        if ($role = $object->role()) {
          $sub .= strtolower(WOOF_Inflector::pluralize($role->id())).WOOF_DIR_SEP;
        }
      }

    } else if ($object_type == "site") {

      $sub .= "site".WOOF_DIR_SEP;
    }
    
    
    if ($field) {
      $sub .= WOOF_Inflector::pluralize($field->type).WOOF_DIR_SEP;
    }

    $dir .= $sub;

    if (!file_exists($dir)) {
      if (!wp_mkdir_p($dir)) {
        $dir = MASTERPRESS_CONTENT_UPLOADS_DIR; // fallback to top level
      }
    }
            
    return array($dir, $sub);
    
  }
Ejemplo n.º 5
0
 public static function k($class) {
   return WOOF_Inflector::underscore( WOOF_Inflector::pluralize( str_replace("MPM_", "", $class ) ) );
 }
Ejemplo n.º 6
0
  public static function select($options, $value, $blank = false, $editable = true) {
    
    global $wf;

    $control_style = self::option_value($options, "control_style", "drop_down_list");

    if ($control_style == "dual_list_box") {
      // legacy patch for dual list box - it had bad performance for a large number of items
      $control_style = "list_box_multiple";
    }
    
    $selected_values = array();
    $items = array();
    $values_select = "";
    $values_options = array_flip($value);
    $values_options_attr = array_flip($value);
    
    $options_attr = array();
    
    $count = -1;
    $multiple = count($options["user_roles"]) > 1;
    self::$values_keys = array();

    $row_style = self::option_value($options, "row_style", "icon_title");
    $result_row_prop = self::option_value($options, "result_row_prop", array());

    $grouping = self::option_value($options, "grouping");


    $maxwidth = self::option_value($options, "maxwidth");

    // build a list of users

    foreach ($options["user_roles"] as $role_id) {
      
      $role = $wf->role($role_id);

      $users = array("options" => array(), "options_attr" => array());

      if ($role && $role->exists()) {
        
        $count++;

        foreach ($role->users() as $user) {
          $count++;

          $uid = $user->id();

          
          $title = self::get_row_prop_title($user, $result_row_prop, $role_id);

          if ($title == "") {
            $title = $user->full_name();
          }

          // ensure there are no duplicate titles

          $tcount = 2;
          
          while (isset($users["options"][$title])) {
            $title = $title . " ( ".$tcount." )";
            $tcount++;
          }
          
          $users["options"][$title] = $uid;

          $attr = array( );

          // retrieve special properties
          
          $attr = array();
          
          if ($row_style == "icon_title_excerpt" || $row_style == "image_title_excerpt") {
            $attr = array_merge( $attr, self::get_row_prop_role_name($user, $result_row_prop, $role_id) );
          }

          if ($row_style == "image_title_excerpt" || $row_style == "image_title") {
            $attr = array_merge( $attr, self::get_row_prop_image($user, $result_row_prop, $role_id, $row_style == "image_title" ? 40 : 60) );
          }
          

          $users["options_attr"][] = $attr;
          
          
          if (in_array($uid, $value)) {
            $selected_values[] = $uid;
            $values_options[$uid] = $title;
            $values_options_attr[$uid] = $attr;
          } 

        }

        if (count($users["options"])) {
          $label = WOOF_Inflector::pluralize($role->name());
          $users["optgroup_attr"] = array("label" => $label, "data-selection-prefix" => $role->name().": ");
          $items[$label] = $users;
        }
      }

    }

    self::$values_keys = array_values($values_options);

    $select_style = "";

    $select_attr = array("id" => "{{id}}", "name" => "{{name}}");

    if (is_numeric($maxwidth)) {
      $select_style .= "width: 99%; max-width: ".$maxwidth."px;";
    } else {
      $select_style .= "width: 580px;";
    }


    if ($control_style == "list_box_multiple") {
      $select_attr["multiple"] = "multiple";
      $select_attr["name"] = "{{name}}[]";
    } 

    if ($select_style != "") {
      $select_attr["style"] = $select_style;
    }

    $basic = self::option_value($options, "basic") == "yes";

    if ($control_style == "drop_down_list") {
      // add a prompting empty label
      $items = array("" => "") + $items;
      //array_unshift($options_attr, array());
      $select_attr["data-placeholder"] = self::option_value($options, "placeholder", "-- Select a user --");
    } else {
      $select_attr["data-placeholder"] = self::option_value($options, "placeholder", "-- Select users --");
      $select_attr["data-value-input"] = "{{id}}-value-input";

      if (!$basic) {
        // ensure the select control does not affect the values posted, the hidden input is responsible for this
        $select_attr["name"] = "src_".$select_attr["name"];
      }

    }

    if (!$editable) {
      $select_attr["data-placeholder"] = __("-- None Selected --", MASTERPRESS_DOMAIN);
      $select_attr["disabled"] = "disabled";
    }

    return WOOF_HTML::select( 
      $select_attr,
      $items,
      $selected_values,
      $options_attr
    );
    
  }