/** * Creates instance of this class * * @param string $key Content list title * @param array $data Data list * @param array $config Configuration * @return object This class instance */ protected function __createInstance($key, $data = array(), array $config = array()) { $title = $key; $key = Utils::slugify($key); // Default main configuration $default_config = array('key' => $key, 'title' => $title, 'description' => '', 'field_name' => $key, 'show_top_form' => true, 'show_bottom_form' => true, 'type' => 'single', 'mode' => 'default', 'file_upload' => ['name' => 'id', 'config' => ['modal_title' => 'Upload or select existing images', 'modal_button_text' => 'Add Images', 'modal_select_multiple' => true, 'mime_types' => ['image']]], 'labels' => array('add_button' => 'Add Item', 'sort_button' => 'Sort', 'edit_all_button' => 'Edit All'), 'no_items_message' => 'No items added until now'); // Main configuration $this->config = new Collection(array_replace_recursive($default_config, $config)); // Data $this->data = new Collection($data ?: array()); // Views $this->views_sections = (new Collection(array('browse' => [], 'reorder' => [], 'edit' => [])))->disableDottedNotation(); $this->views = (new Collection(array('browse' => '', 'reorder' => '', 'edit' => '')))->disableDottedNotation(); // Labels $this->labels = (new Collection($this->config->get('labels')))->disableDottedNotation(); // Forms $this->forms = (new Collection())->disableDottedNotation(); // Add default form // This is inherited by user added forms without form elements $this->addForm('default', array('add' => __DIR__ . '/views/partials/form/default/elements/add.php', 'sort' => __DIR__ . '/views/partials/form/default/elements/sort.php', 'edit_all' => __DIR__ . '/views/partials/form/default/elements/edit_all.php')); // Add main form $this->addForm('main', array('add' => __DIR__ . '/views/partials/form/default/elements/add.php', 'sort' => __DIR__ . '/views/partials/form/default/elements/sort.php', 'edit_all' => __DIR__ . '/views/partials/form/default/elements/edit_all.php')); // Register templates on admin footer add_action('admin_footer', array($this, 'renderTemplates')); return $this; }
/** * Modify module after setting initial user vars * * @return void */ protected function __afterSetVars() { // If there is no name set it as a "slugified" label if ($this->getVar('label') && !$this->getVar('name')) { $this->setVar('name', Utils::slugify($this->getVar('label'))); } $this->el = new Media($this->getVar('name'), null, []); }
/** * Sets a single option * * @param string $value Option value * @param string $label Option label * @param boolean $selected Option selection status */ public function addOption($label, $value = null, $selected = false) { if (!is_string($label)) { throw new \Exception('Option label must be a string'); } $this->config->push(['label' => $label, 'value' => $value ? $value : Utils::slugify($label), 'selected' => $selected], 'options'); return $this; }
/** * Modify module after setting initial user vars * * @return void */ protected function __afterSetVars() { // If there is no name set it as a "slugified" label if ($this->getVar('label') && !$this->getVar('name')) { $this->setVar('name', Utils::slugify($this->getVar('label'))); } // Initialize main element $this->el = new RadioElement(['attrs.name' => $this->getVar('name'), 'options' => $this->getVar('options')]); }
public static function getKey() { $child_class = get_called_class(); if (!$child_class::$__key) { $class = new \ReflectionClass($child_class); $class_name = $class->getShortName(); $key = Utils::slugify($class_name); $child_class::$__key = $key; } return $child_class::$__key; }
/** * Modify module after setting initial user vars * * @return void */ protected function __afterSetVars() { // If there is no name set it as a "slugified" label if ($this->getVar('label') && !$this->getVar('name')) { $this->setVar('name', Utils::slugify($this->getVar('label'))); } $this->el = new ContentList($this->getVar('name'), [], $this->getVar('config')); $item_views = $this->getVar('item_views'); if ($item_views && is_array($item_views)) { foreach ($item_views as $view => $sections) { if ($sections && is_array($sections)) { $this->el->addItemViewSections($view, $sections); } } } }
/** * Instantiates UI object * */ protected function __construct() { // Get URL for current directory self::$__base_url = Utils::getPathUrl(__DIR__); // Instantiate plugins collection object $this->__plugins = new Collection(); // Add built-in plugins $this->addPlugins(array('Ponticlaro\\Bebop\\UI\\Plugins\\Media\\Media', 'Ponticlaro\\Bebop\\UI\\Plugins\\ContentList\\ContentList', 'Ponticlaro\\Bebop\\UI\\Plugins\\MultiContentList\\MultiContentList', 'Ponticlaro\\Bebop\\UI\\Plugins\\Gallery\\Gallery')); // Register common UI scripts add_action('init', array($this, 'registerScripts')); // Set assets directory $assets_dir = __DIR__ . '/UI/assets'; // Set static assets URL $paths = PathManager::getInstance(); $paths->set('_bebop/static/ui', $assets_dir); // Set static assets directory $urls = UrlManager::getInstance(); $urls->set('_bebop/static/ui', $urls->get('home', '_bebop/static/ui')); // Setup static assets server $http_api = new HttpApi('bebop_ui_static_assets', '_bebop/static/ui'); new StaticAssetsServer($http_api, $assets_dir); }
/** * Modify module after setting initial user vars * * @return void */ protected function __afterSetVars() { // If there is no name set it as a "slugified" label if ($this->getVar('label') && !$this->getVar('name')) { $this->setVar('name', Utils::slugify($this->getVar('label'))); } $this->el = new ContentList($this->getVar('name'), [], $this->getVar('config')); $search_config = []; if ($this->getVar('placeholder')) { $search_config['placeholder'] = $this->getVar('placeholder'); } if ($this->getVar('url')) { $search_config['url'] = $this->getVar('url'); } if ($this->getVar('query')) { $search_config['query'] = $this->getVar('query'); } if ($this->getVar('mapping')) { $search_config['mapping'] = $this->getVar('mapping'); } if ($this->getVar('placeholder')) { $search_config['templates'] = $this->getVar('templates'); } $config = array_replace_recursive(['ui' => 'postsearch', 'attrs' => ['bebop-list--formElId' => 'selector']], $search_config, ['attrs' => ['style' => 'min-width:220px;max-width:100%;display:block']]); $this->el->setFormElement('main', 'add', [$config, ['ui' => 'button', 'text' => '<span class="bebop-ui-icon-add"></span> Add', 'class' => 'button-primary', 'attrs' => ['bebop-list--formAction' => 'bebop-ui-action--addAssociatedType']]]); $config = array_replace_recursive(['ui' => 'postsearch', 'name' => 'id', 'attrs' => ['disabled' => true, 'bebop-ui-mod-associatedtypes-selector' => true]], $search_config); $this->el->addItemViewSection('browse', $config); $config = array_replace_recursive(['ui' => 'postsearch', 'name' => 'id', 'attrs' => ['bebop-ui-mod-associatedtypes-selector' => true]], $search_config); $this->el->addItemViewSection('edit', $config); $item_views = $this->getVar('item_views'); if ($item_views && is_array($item_views)) { foreach ($item_views as $view => $sections) { if ($sections && is_array($sections)) { $this->el->addItemViewSections($view, $sections); } } } }
/** * Does a pre-flight check * * @return void */ public function preFlightCheck() { $this->slim->hook('slim.before', function () { $request = $this->slim->request(); $method = $request->getMethod(); $resource_uri = $request->getResourceUri(); $content_type = $request->headers->get('CONTENT_TYPE'); $request_body = $request->getBody(); if (in_array($method, array('POST', 'PUT', 'PATCH'))) { if ($request_body) { // Throw error if content-type is not 'application/json' if (!$content_type || !preg_match('/application\\/json/', $content_type)) { throw new \UnexpectedValueException("You need to send the Content-type header with 'application/json' as its value", 1); } // Validate request body as JSON string if (!Utils::isJson($request_body)) { throw new BaseException("Request body must be a valid JSON string", 400); } // Get Raw body as $input $input = json_decode($request_body, true); // Check if using json_decode($request_body, true) returns array if (!is_array($input) && !is_object($input)) { throw new BaseException("Request body must be either a JSON object or array", 400); } } } }); return $this; }
/** * Modify module after setting initial user vars * * @return void */ protected function __afterSetVars() { parent::__afterSetVars(); // Get user defined section types $set_section_types = $this->getVar('set_section_types') ?: []; // Add Section types if ($set_section_types) { foreach ($set_section_types as $section_type_config) { $title = isset($section_type_config['title']) && $section_type_config['title'] ? $section_type_config['title'] : null; if ($title) { $section_type_id = isset($section_type_config['id']) && $section_type_config['id'] ? $section_type_config['id'] : Utils::slugify($title); $this->setType($section_type_id, $section_type_config); } } } // Handle enabled section types $section_types = $this->getVar('enabled_section_types') ?: []; if ($section_types) { $selector_options = []; $browse_view = []; $reorder_view = []; $edit_view = []; foreach ($section_types as $id) { $id = Utils::slugify($id); $sconf = isset($this->section_types[$id]) ? $this->section_types[$id] : null; // Get section title $title = $sconf['title']; if ($title) { // Get section type and sections $id = isset($sconf['id']) && $sconf['id'] ? $sconf['id'] : Utils::slugify($title); $browse_sections = isset($sconf['browse_sections']) && is_array($sconf['browse_sections']) ? $sconf['browse_sections'] : []; $reorder_sections = isset($sconf['reorder_sections']) && is_array($sconf['reorder_sections']) ? $sconf['reorder_sections'] : []; $edit_sections = isset($sconf['edit_sections']) && is_array($sconf['edit_sections']) ? $sconf['edit_sections'] : []; if (!$reorder_sections) { $reorder_sections = $browse_sections; } // Add section option to options list $selector_options[] = ['label' => $title, 'value' => $id]; ///////////////// // Browse View // ///////////////// // Set opening tag to enclose HTML for this section type $browse_view[] = ['ui' => 'rawHtml', 'html' => "{{#type_is_{$id}}}"]; foreach ($browse_sections as $section) { $browse_view[] = $section; } // Set closing tag to enclose HTML for this section type $browse_view[] = ['ui' => 'rawHtml', 'html' => "{{/type_is_{$id}}}"]; ////////////////// // Reorder View // ////////////////// // Set opening tag to enclose HTML for this section type $reorder_view[] = ['ui' => 'rawHtml', 'html' => "{{#type_is_{$id}}}"]; foreach ($reorder_sections as $section) { $reorder_view[] = $section; } // Set closing tag to enclose HTML for this section type $reorder_view[] = ['ui' => 'rawHtml', 'html' => "{{/type_is_{$id}}}"]; /////////////// // Edit View // /////////////// // Set opening tag to enclose HTML for this section type $edit_view[] = ['ui' => 'rawHtml', 'html' => "{{#type_is_{$id}}}"]; // Add hidden input with section type id' $edit_view[] = ['ui' => 'hidden', 'name' => 'type', 'value' => $id]; // Add hidden input with section type 'title' $edit_view[] = ['ui' => 'hidden', 'name' => 'type_title', 'value' => $title]; foreach ($edit_sections as $section) { $edit_view[] = $section; } // Set closing tag to enclose HTML for this section type $edit_view[] = ['ui' => 'rawHtml', 'html' => "{{/type_is_{$id}}}"]; } } // Replace 'add' for element $this->el->setFormElement('main', 'add', [['ui' => 'select', 'name' => true, 'attrs' => ['bebop-list--formElId' => 'selector'], 'options' => $selector_options], ['ui' => 'button', 'text' => '<span class="bebop-ui-icon-add"></span> Add', 'class' => 'button-primary', 'attrs' => ['bebop-list--formAction' => 'bebop-ui-action--addSection']]]); // Set 'browse' view for list items $this->el->addItemViewSections('browse', $browse_view); // Set 'reorder' view for list items $this->el->addItemViewSections('reorder', $reorder_view); // Set 'edit' view for list items $this->el->addItemViewSections('edit', $edit_view); } }
/** * Modify module after setting initial user vars * * @return void */ protected function __afterSetVars() { // If there is no name set it as a "slugified" label if ($this->getVar('label') && !$this->getVar('name')) { $this->setVar('name', Utils::slugify($this->getVar('label'))); } $this->el = new ContentList($this->getVar('name'), [], $this->getVar('config')); $item_views = $this->getVar('item_views'); $media_sources = $this->getVar('media_sources') ?: []; // Handle media sources dropdrown if ($media_sources) { $selector_options = []; foreach ($media_sources as $source_id => $source_config) { if ($source_config && $this->allowsMediaSource($source_id) && MediaSourcesFactory::canManufacture($source_id)) { $media_source = MediaSourcesFactory::create($source_id, is_array($source_config) ? $source_config : []); $selector_options[] = ['value' => $source_id, 'label' => $media_source->getName()]; } } // Replace 'add' form element $total_selector_options = count($selector_options); if ($total_selector_options > 0) { $ui_elements = []; if ($total_selector_options == 1) { $single_option = reset($selector_options); $ui_elements[] = ['ui' => 'input', 'name' => true, 'value' => $single_option['value'], 'attrs' => ['bebop-list--formElId' => 'selector', 'type' => 'hidden']]; } else { $ui_elements[] = ['ui' => 'select', 'name' => true, 'attrs' => ['bebop-list--formElId' => 'selector'], 'options' => $selector_options]; } $ui_elements[] = ['ui' => 'button', 'text' => '<span class="bebop-ui-icon-add"></span> Add', 'class' => 'button-primary', 'attrs' => ['bebop-list--formAction' => 'bebop-ui-action--addMediaFromTargetSource']]; $this->el->setFormElement('main', 'add', $ui_elements); } } // Handle UI sections if ($item_views && is_array($item_views)) { foreach ($item_views as $view => $sections) { $view_sections = []; $sections = is_array($sections) ? $sections : []; if ($media_sources) { foreach ($media_sources as $source_id => $source_config) { if ($source_config && $this->allowsMediaSource($source_id) && MediaSourcesFactory::canManufacture($source_id)) { $media_source = MediaSourcesFactory::create($source_id, is_array($source_config) ? $source_config : []); $id_field = $media_source->getIdentifierField(); // Set openning tag to enclose HTML for this media source $opening_html = '<div bebop-ui-mod-list--item-with-media-source-visual'; if ($view != 'edit') { $opening_html .= ' {{^' . $id_field . '}}status-is="warning"{{/' . $id_field . '}}'; } $opening_html .= '>'; $media_source_sections = [['ui' => 'rawHtml', 'html' => "{{#source_id_is_{$source_id}}}{$opening_html}"]]; // - Add hidden input with media source if ($view == 'edit') { $media_source_sections[] = ['ui' => 'hidden', 'name' => 'source_id', 'value' => '{{source_id}}']; $media_source_sections[] = ['ui' => 'hidden', 'name' => 'source_name', 'value' => '{{source_name}}']; } // Add media source sections $source_config = is_array($source_config) ? $source_config : []; $media_source_sections = array_merge($media_source_sections, $media_source->getContentListUISections($view, $source_config)); // Add user defined sections $media_source_sections = array_merge($media_source_sections, $sections); // Set closing tag to enclose HTML for this media source $media_source_sections[] = ['ui' => 'rawHtml', 'html' => "</div>{{/source_id_is_{$source_id}}}"]; // Add media source sections to current view list of sections if ($media_source_sections) { $view_sections = array_merge($view_sections, $media_source_sections); } } } } if ($view_sections && is_array($view_sections)) { $this->el->addItemViewSections($view, $view_sections); } } } }
/** * Registers grouped settings * * @return void */ public function __handleSettingsRegistration() { // Get sections & callable $sections = $this->sections->getAll(); $function = $this->getFunction(); $names = []; // Fetch control elements name attribute from function if ($function) { $names += Utils::getControlNamesFromCallable($function, array($this->data, $this)); if ($names) { $this->setOptions($names); } } // Fetch control elements name attribute from sections if ($sections) { $names += Utils::getControlNamesFromCallable([$this, '__collectSectionsFieldNames'], array($this->data, $this)); if ($names) { $this->setOptions($names); } } $options = $this->options->getAll(); if ($options) { foreach ($options as $option) { register_setting($this->getId(), $option); } } // Reset sections so that we do not have duplicates $this->sections->clear()->pushList($sections); }
/** * Sets the field name * * @param mixed $name Field name value * @return object This classobject */ public function setName($name) { if (is_string($name)) { $this->config->set('field_name', Utils::slugify($name)); } return $this; }
/** * Gets field names from callback function * */ private function __setMetaFields() { // Only execute if there are no manually defined meta fields if (!$this->meta_fields->getAll()) { // Set callable arguments $args = array($this->data, new \WP_Post(new \stdClass()), $this); // Collect current sections $sections = $this->sections->getAll(); if ($callback = $this->getCallback()) { // Collect field names from callable $names = Utils::getControlNamesFromCallable($callback, $args); $this->meta_fields->pushList($names); } if ($this->getAllSections()) { $names = Utils::getControlNamesFromCallable([$this, '__collectSectionsFieldNames'], $args); $this->meta_fields->pushList($names); } // Reset sections so that we do not have duplicates $this->sections->clear()->pushList($sections); } }
/** * Instantiates new post type * * @param mixed $name String or array with singular name first and plural name in second */ public function __construct($name) { // Throw exception if we're trying to modify built-in post-types if (in_array(Utils::slugify(is_array($name) ? reset($name) : $name), ['attachment', 'post', 'page', 'revision', 'nav_menu_item'])) { throw new \Exception("You should not use this class to modify built-in post types"); } // Instantiate configuration object with defaults $this->config = new Collection(array('public' => true, 'has_archive' => true, 'publicly_queryable' => true, 'show_ui' => true, 'query_var' => true, 'can_export' => true)); // Instantiate features object with defaults $this->features = new Collection(array('title', 'editor', 'revisions')); // Instantiate labels object $this->labels = new Collection(); // Instantiate capabilities object $this->capabilities = new Collection(); // Instantiate taxonomies object $this->taxonomies = new Collection(); // Instantiate rewrite configuration object $this->rewrite_config = new Collection(['with_front' => false]); // Set post type name call_user_func_array(array($this, '__setName'), is_array($name) ? $name : array($name)); // Set post_type id $this->__trackable_id = Utils::slugify(is_array($name) ? $name[0] : $name); // Set default labels based on singular and plural names $this->__setDefaultLabels(); // Hook into init action to register post type add_action("init", array($this, '__register'), 1); }
/** * Sets default Api routes * * @return void */ public function setDefaultRoutes() { // Hello World route $this->api->get('/', function () { return array('Hello World'); }); // Get all registered post types $post_types = get_post_types(array(), 'objects'); ////////////////////////// // Add /search endpoint // ////////////////////////// $this->api->get("search(/)(:keywords)", function ($keywords = null) { // Override context ContextManager::getInstance()->overrideCurrent('api/search'); // Get all registered post types $post_types = get_post_types(array(), 'objects'); // Default query args $default_query = ['type' => []]; // Add all publicly queryable types to search results if ($post_types) { foreach ($post_types as $type) { if ($type->name == 'page' || $type->publicly_queryable) { $default_query['type'][] = $type->name; } } } // Enable developers to modify $default_query for this resource $default_query = apply_filters("bebop:api:search:default_query", $default_query); // Capture 'post_type' argument if (isset($_GET['post_type'])) { $_GET['type'] = $_GET['post_type']; unset($_GET['post_type']); } // Merge default query args with user query args $query = array_merge($default_query, $_GET); // Add keywords to query if ($keywords) { $query['s'] = $keywords; } // Enable developers to modify final query for this resource $query = apply_filters("bebop:api:search:query", $query); // Get results $response = Db::wpQuery($query)->setOption('with_meta', true)->execute(); // Apply model modifications for each post type if ($response['items']) { foreach ($response['items'] as $index => $post) { if (ModelFactory::canManufacture($post->post_type)) { $response['items'][$index] = ModelFactory::create($post->post_type, array($post)); } } } // Enable developers to modify response for this resource $response = apply_filters("bebop:api:search:response", $response); // Return response return $response; }); ///////////////////////////////////////////////// // Add endpoints for all available posts types // ///////////////////////////////////////////////// foreach ($post_types as $slug => $post_type) { if ($post_type->public) { $resource_name = Utils::slugify($post_type->labels->name); // Add post resource $this->api->get("{$resource_name}(/)(:id)", function ($id = null) use($post_type, $resource_name) { if (is_numeric($id)) { // Override context ContextManager::getInstance()->overrideCurrent('api/single/' . $resource_name); $post = get_post($id); if ($post instanceof \WP_Post) { if (ModelFactory::canManufacture($post->post_type)) { $post = ModelFactory::create($post->post_type, array($post)); } $response = $post; } } else { // Override context ContextManager::getInstance()->overrideCurrent('api/archive/' . $resource_name); if (isset($_GET['type'])) { unset($_GET['type']); } if ($resource_name == 'media') { if (isset($_GET['status'])) { unset($_GET['status']); } $_GET['post_type'] = 'attachment'; $_GET['post_status'] = 'inherit'; } else { $_GET['post_type'] = $post_type->name; } $response = Db::wpQuery($_GET)->setOption('with_meta', true)->execute(); if ($response['items']) { foreach ($response['items'] as $index => $post) { if (ModelFactory::canManufacture($post->post_type)) { $response['items'][$index] = ModelFactory::create($post->post_type, array($post)); } } } } // Enable developers to modify response for target resource $response = apply_filters("bebop:api:{$resource_name}:response", $response); // Return response return $response; }); ///////////////////////////////////// // Get all or individual post meta // ///////////////////////////////////// $this->api->get("{$resource_name}/:post_id/meta/:meta_key(/)(:meta_id)", function ($post_id, $meta_key, $meta_id = null) use($post_type, $resource_name) { // Throw error if post do not exist if (!get_post($post_id) instanceof \WP_Post) { throw new ApiException("Target entry do not exist", 404); } // Get meta data $post_meta = new ObjectMeta('post', $post_id, array('projection' => $this->postmeta_projection)); $response = $meta_id ? $post_meta->get($meta_key, $meta_id) : $post_meta->getAll($meta_key); // Enable developers to modify response $response = apply_filters("bebop:api:postmeta:{$meta_key}:response", $response, $post_id); // Enable developers to modify response $response = apply_filters('bebop:api:postmeta:response', $response, $meta_key, $post_id); // Return response return $response; }); ///////////////////////////// // Create single post meta // ///////////////////////////// $this->api->post("{$resource_name}/:post_id/meta/:meta_key(/)", function ($post_id, $meta_key) { // Check if current user can edit the target post if (!current_user_can('edit_post', $post_id)) { throw new ApiException("You cannot edit the target entry", 403); } // Get request body $data = json_decode($this->api->router()->request()->getBody(), true); // Throw error if payload is null if (is_null($data)) { throw new ApiException("You cannot send an empty request body", 400); } // Defined storage method $storage_method = isset($_GET['storage_method']) ? $_GET['storage_method'] : 'json'; // Check storage type if (!in_array($storage_method, array('json', 'serialize'))) { throw new ApiException("Storage method needs to be either 'json' or 'serialize'", 400); } // Throw error if post do not exist if (!get_post($post_id) instanceof \WP_Post) { throw new ApiException("Target entry do not exist", 404); } // Instantiate PostMeta object $post_meta = new ObjectMeta('post', $post_id, array('projection' => $this->postmeta_projection)); // Add new meta row $new_item = $post_meta->add($meta_key, $data, $storage_method); // Throw error if it was not able to create new postmeta item if (!$new_item) { throw new ApiException("Failed to create new postmeta item", 500); } // Return response return $new_item; }); ///////////////////////////// // Update single post meta // ///////////////////////////// $this->api->put("{$resource_name}/:post_id/meta/:meta_key/:meta_id(/)", function ($post_id, $meta_key, $meta_id) { // Check if current user can edit the target post if (!current_user_can('edit_post', $post_id)) { throw new ApiException("You cannot edit the target entry", 403); } // Get request body $data = json_decode($this->api->router()->request()->getBody(), true); // Throw error if payload is null if (is_null($data)) { throw new ApiException("You cannot send an empty request body", 400); } // Defined storage method $storage_method = isset($_GET['storage_method']) ? $_GET['storage_method'] : 'json'; // Check storage type if (!in_array($storage_method, array('json', 'serialize'))) { throw new ApiException("Storage method needs to be either 'json' or 'serialize'", 400); } // Throw error if post do not exist if (!get_post($post_id) instanceof \WP_Post) { throw new ApiException("Target entry do not exist", 404); } // Instantiate PostMeta object $post_meta = new ObjectMeta('post', $post_id, array('projection' => $this->postmeta_projection)); // Update Meta $updated_item = $post_meta->update($meta_key, $meta_id, $data, $storage_method); // Throw error if it was not able to update the target postmeta item if (!$updated_item) { throw new ApiException("Failed to update postmeta item", 500); } // Return updated item return $updated_item; }); ///////////////////////////// // Delete single post meta // ///////////////////////////// $this->api->delete("{$resource_name}/:post_id/meta/:meta_key/:meta_id(/)", function ($post_id, $meta_key, $meta_id) use($post_type, $resource_name) { // Check if current user can edit the target post if (!current_user_can('edit_post', $post_id)) { throw new ApiException("You cannot edit the target entry", 403); } // Throw error if post do not exist if (!get_post($post_id) instanceof \WP_Post) { throw new ApiException("Target entry do not exist", 404); } // Instantiate PostMeta object $post_meta = new ObjectMeta('post', $post_id, array('projection' => $this->postmeta_projection)); // Delete post meta $remaining_items = $post_meta->delete($meta_key, $meta_id); // Return remaining items return $remaining_items; }); } } // Add endpoint to inform about available endpoints $this->api->get("_resources(/)", function () use($post_types) { if (!current_user_can('manage_options')) { $this->api->router()->slim()->halt(403, json_encode(array('error' => array('status' => 403, 'message' => "You're not an authorized user.")))); exit; } $base_url = '/' . $this->api->getBaseUrl(); // Loop through all defined routes foreach ($this->api->routes()->getAll() as $route) { $resources[] = array('method' => strtoupper($route->getMethod()), 'endpoint' => $base_url . ltrim($route->getPath(), '/')); } // Return resources return $resources; }); return $this; }
/** * Creates single instance of the MultiContentList plugin * * @param string $title Instance Title. Also used to create a slugified key * @param array $config Configuration array * @return object Ponticlaro\Bebop\UI\Plugins\MultiContentList */ private function __createInstance($title, array $config = array()) { // Create slugified $key from $title $key = Utils::slugify($title); // Set default configuration values $this->__config->set(array('key' => $key, 'title' => $title, 'mode' => 'default')); // Set configuration values from input $this->__config->set($config); return $this; }
/** * Normalizes ID string * * @param string $source_string ID string to clean * @return string Clean string */ private static function __getNormalizedId($raw_id) { // Slugify $id = Utils::slugify($raw_id); // Replace dots with underscores $id = str_replace('.', '_', $id); // Return ID return $id; }
/** * Adds single post_type * * @param string $post_type * @return \Ponticlaro\Bebop\Cms\Taxonomy Taxonomy instance */ public function addPostType($post_type) { if (is_a($post_type, 'Ponticlaro\\Bebop\\PostType')) { $post_type = $post_type->getId(); } if (!is_string($post_type)) { throw new \Exception('Taxonomy post type must be either a string or a \\Ponticlaro\\Bebop\\PostType instance.'); } $this->post_types->push(Utils::slugify($post_type)); return $this; }
/** * Handles any call to undefined static methods * * @param string $name Name of the target method * @param array $args Arguments for the target method * @return mixed */ public static function __callStatic($name, $args) { ////////////////////////////// // Check for correct method // ////////////////////////////// // Check for get $is_get = substr($name, 0, 3) == 'get' ? true : false; ///////// // Get // ///////// if ($is_get) { $get_action = substr($name, 3, strlen($name)); $is_getPostType = $get_action == 'PostType' ? true : false; $is_getTaxonomy = $get_action == 'Taxonomy' ? true : false; $is_getMetabox = $get_action == 'Metabox' ? true : false; if ($is_getPostType || $is_getTaxonomy || $is_getMetabox) { if (!isset($args[0])) { return; } if (is_string($args[0])) { $key = Utils::slugify($args[0]); if ($is_getPostType) { $type = 'post_type'; } if ($is_getTaxonomy) { $type = 'taxonomy'; } if ($is_getMetabox) { $type = 'metabox'; } return $type ? ObjectTracker::get($type, $key) : null; } } } else { return call_user_func_array(array('Ponticlaro\\Bebop\\Core\\Helpers\\BebopFactory', 'create'), array($name, $args)); } }
/** * Checks if current WordPress installation is a network * * @return boolean True if it is a network, false otherwise */ protected function isNetwork() { return Utils::isNetwork(); }
/** * Captures custom meta arguments * * @param array $args * @return void */ protected function __captureCustomMetaArgs(array &$args = array()) { foreach ($args as $key => $value) { if (preg_match('/^meta\\:/', $key)) { $data_string = str_replace('meta:', '', $key); if ($data_string) { $data = null; if (Utils::isJson($data_string)) { $data = $data_string ? json_decode($data_string, true) : null; } else { // check for comparator $params = explode(':', $data_string); $data = array('key' => isset($params[0]) ? $params[0] : '', 'compare' => isset($params[1]) && array_key_exists(strtolower($params[1]), static::$comparator_map) ? static::$comparator_map[$params[1]] : '='); } if (isset($data['key']) && $data['key']) { if (!$this->clean_args->hasKey('meta_query') && isset($args['meta_relation'])) { $relation = $args['meta_relation']; unset($args['meta_relation']); $this->clean_args->set('meta_query.relation', $relation); } if (!isset($data['compare']) || !$data['compare']) { $data['compare'] = '='; } if (!isset($data['type']) || !$data['type']) { $data['type'] = 'CHAR'; } // Search for a value type $params = explode(':', $value); if (count($params) == 2 && array_key_exists(strtolower($params[0]), static::$value_type_map)) { $data['type'] = $params[0]; $value = $params[1]; } $data['value'] = stripslashes($value); $this->clean_args->push($data, 'meta_query'); } } unset($args[$key]); } } }