/** * Callback to render the "Custom Fields" metabox. * * @access private * @since 0.8 * @param cnEntry $entry An instance of the cnEntry object. * @param array $metabox The metabox attributes array set in self::register(). * @return void */ public static function meta($entry, $metabox) { /** @var wpdb $wpdb */ global $wpdb; $results = $wpdb->get_results($wpdb->prepare("SELECT meta_key, meta_value, meta_id, entry_id\n\t\t\tFROM " . CN_ENTRY_TABLE_META . " WHERE entry_id = %d\n\t\t\tORDER BY meta_key,meta_id", $entry->getId()), ARRAY_A); $metabox = $metabox['args']; $keys = cnMeta::key('entry'); $options = array(); // Toss the meta that is saved as part of a custom field. if (!empty($results)) { foreach ($results as $metaID => $meta) { if (cnMeta::isPrivate($meta['meta_key'])) { unset($results[$metaID]); } } } // Build the meta key select drop down options. if (!empty($keys)) { $options = array_combine(array_map('esc_attr', array_keys($keys)), array_map('esc_html', $keys)); array_walk($options, create_function('&$key', '$key = "<option value=\\"$key\\">$key</option>";')); } array_unshift($options, '<option value="-1">— ' . __('Select', 'connections') . ' —</option>'); $options = implode($options, PHP_EOL); // echo '<input type="hidden" name="wp_meta_box_nonce" value="', wp_create_nonce( basename(__FILE__) ), '" />'; echo '<div class="cn-metabox-section" id="meta-fields">'; ?> <table id="list-table" style="<?php echo empty($results) ? 'display: none;' : 'display: table;'; ?> "> <thead> <tr> <th class="left"><?php _e('Name', 'connections'); ?> </th> <th><?php _e('Value', 'connections'); ?> </th> </tr> </thead> <tbody id="the-list"> <?php if (!empty($results)) { foreach ($results as $metaID => $meta) { // Class added to alternate tr rows for CSS styling. $alternate = !isset($alternate) || $alternate == '' ? 'alternate' : ''; ?> <tr id="meta-<?php echo $meta['meta_id']; ?> " class="<?php echo $alternate; ?> "> <td class="left"> <label class="screen-reader-text" for='meta[<?php echo $meta['meta_id']; ?> ][key]'><?php _e('Key', 'connections'); ?> </label> <input name='meta[<?php echo $meta['meta_id']; ?> ][key]' id='meta[<?php echo $meta['meta_id']; ?> ][key]' type="text" size="20" value="<?php echo esc_textarea($meta['meta_key']); ?> " /> <div class="submit"> <input type="submit" name="deletemeta[<?php echo $meta['meta_id']; ?> ]" id="deletemeta[<?php echo $meta['meta_id']; ?> ]" class="button deletemeta button-small" value="<?php _e('Delete', 'connections'); ?> " /> </div> </td> <td> <label class="screen-reader-text" for='meta[<?php echo $meta['meta_id']; ?> ][value]'><?php _e('Value', 'connections'); ?> </label> <textarea name='meta[<?php echo $meta['meta_id']; ?> ][value]' id='meta[<?php echo $meta['meta_id']; ?> ][value]' rows="2" cols="30"><?php echo esc_textarea(cnFormatting::maybeJSONencode($meta['meta_value'])); ?> </textarea> </td> </tr> <?php } ?> <?php } ?> <!-- This is the row that will be cloned via JS when adding a new Custom Field. --> <tr style="display: none;"> <td class="left"> <label class="screen-reader-text" for='newmeta[0][key]'><?php _e('Key', 'connections'); ?> </label> <input name='newmeta[0][key]' id='newmeta[0][key]' type="text" size="20" value=""/> <div class="submit"> <input type="submit" name="deletemeta[0]" id="deletemeta[0]" class="button deletemeta button-small" value="<?php _e('Delete', 'connections'); ?> " /> <!-- <input type="submit" name="newmeta-0-submit" id="newmeta-0-submit" class="button updatemeta button-small" value="Update" /> --> </div> <!-- <input type="hidden" id="_ajax_nonce" name="_ajax_nonce" value="0db0025bba" /> --> </td> <td> <label class="screen-reader-text" for='newmeta[0][value]'><?php _e('Value', 'connections'); ?> </label> <textarea name='newmeta[0][value]' id='newmeta[0][value]' rows="2" cols="30"></textarea> </td> </tr> </tbody> </table> <p><strong><?php _e('Add New Custom Field:', 'connections'); ?> </strong></p> <table id="newmeta"> <thead> <tr> <th class="left"><label for="metakeyselect"><?php _e('Name', 'connections'); ?> </label></th> <th><label for="metavalue"><?php _e('Value', 'connections'); ?> </label></th> </tr> </thead> <tbody> <tr> <td id="newmetaleft" class="left"> <select id="metakeyselect" name="metakeyselect"> <?php echo $options; ?> </select> <input class="hide-if-js" type=text id="metakeyinput" name="newmeta[99][key]" value=""/> <a href="#postcustomstuff" class="postcustomstuff hide-if-no-js"> <span id="enternew"><?php _e('Enter New', 'connections'); ?> </span> <span id="cancelnew" class="hidden"><?php _e('Cancel', 'connections'); ?> </span></a> </td> <td> <textarea id="metavalue" name="newmeta[99][value]" rows="2" cols="25"></textarea> </td> </tr> </tbody> <tfoot> <td colspan="2"> <div class="submit"> <input type="submit" name="addmeta" id="newmeta-submit" class="button" value="<?php _e('Add Custom Field', 'connections'); ?> " /> </div> <!-- <input type="hidden" id="_ajax_nonce-add-meta" name="_ajax_nonce-add-meta" value="a7f70d2878" /> --> </td> </tfoot> </table> <?php if (isset($metabox['desc']) && !empty($metabox['desc'])) { printf('<p>%1$s</p>', esc_html($metabox['desc'])); } echo '</div>'; }
/** * Add, update or delete the entry meta data. * * @access public * @since 0.8 * @param string $action The action to being performed to an entry. * @param int $id The entry ID. * * @return mixed array | bool An array of meta IDs or FALSE on failure. */ public static function processEntryMeta($action, $id) { /** @var wpdb $wpdb */ global $wpdb; if (!($id = absint($id))) { return FALSE; } $meta = array(); $newmeta = array(); $metaSelect = array(); $metaIDs = array(); switch ($action) { case 'add': if (isset($_POST['newmeta']) || !empty($_POST['newmeta'])) { foreach ($_POST['newmeta'] as $row) { // If the key begins with an underscore, remove it because those are private. if (isset($row['key'][0]) && '_' == $row['key'][0]) { $row['key'] = substr($row['key'], 1); } $newmeta[] = cnMeta::add('entry', $id, $row['key'], $row['value']); } } if (isset($_POST['metakeyselect']) && $_POST['metakeyselect'] !== '-1') { $metaSelect[] = cnMeta::add('entry', $id, $_POST['metakeyselect'], $_POST['newmeta']['99']['value']); } $metaIDs['added'] = array_merge($newmeta, $metaSelect); break; case 'copy': // Copy any meta associated with the source entry to the new entry. if (isset($_POST['meta']) || !empty($_POST['meta'])) { foreach ($_POST['meta'] as $row) { // If the key begins with an underscore, remove it because those are private. if (isset($row['key'][0]) && '_' == $row['key'][0]) { $row['key'] = substr($row['key'], 1); } // Add the meta except for those that the user deleted for this entry. if ($row['value'] !== '::DELETED::') { $meta[] = cnMeta::add('entry', $id, $row['key'], $row['value']); } } } // Lastly, add any new meta the user may have added. if (isset($_POST['newmeta']) || !empty($_POST['newmeta'])) { foreach ($_POST['newmeta'] as $row) { // If the key begins with an underscore, remove it because those are private. if (isset($row['key'][0]) && '_' == $row['key'][0]) { $row['key'] = substr($row['key'], 1); } $metaIDs[] = cnMeta::add('entry', $id, $row['key'], $row['value']); } // $newmeta = cnMeta::add( 'entry', $id, $_POST['newmeta']['0']['key'], $_POST['newmeta']['99']['value'] ); } if (isset($_POST['metakeyselect']) && $_POST['metakeyselect'] !== '-1') { $metaSelect[] = cnMeta::add('entry', $id, $_POST['metakeyselect'], $_POST['newmeta']['99']['value']); } $metaIDs['added'] = array_merge($meta, $newmeta, $metaSelect); break; case 'update': // Query the meta associated to the entry. //$results = cnMeta::get( 'entry', $id ); $results = $wpdb->get_results($wpdb->prepare("SELECT meta_key, meta_value, meta_id, entry_id\n\t\t\t\t\t\t\tFROM " . CN_ENTRY_TABLE_META . " WHERE entry_id = %d\n\t\t\t\t\t\t\tORDER BY meta_key,meta_id", $id), ARRAY_A); if ($results !== FALSE) { // Loop thru $results removing any custom meta fields. Custom meta fields are considered to be private. foreach ($results as $metaID => $row) { if (cnMeta::isPrivate($row['meta_key'])) { unset($results[$row['meta_id']]); } } // Loop thru the associated meta and update any that may have been changed. // If the meta id doesn't exist in the $_POST data, assume the user deleted it. foreach ($results as $metaID => $row) { // Update the entry meta if it differs. if (isset($_POST['meta'][$row['meta_id']]['value']) && $_POST['meta'][$row['meta_id']]['value'] !== $row['meta_value'] || isset($_POST['meta'][$row['meta_id']]['key']) && $_POST['meta'][$row['meta_id']]['key'] !== $row['meta_key'] && $_POST['meta'][$row['meta_id']]['value'] !== '::DELETED::') { // If the key begins with an underscore, remove it because those are private. //if ( isset( $row['key'][0] ) && '_' == $row['key'][0] ) $row['key'] = substr( $row['key'], 1 ); //cnMeta::update( 'entry', $id, $_POST['meta'][ $row['meta_id'] ]['key'], $_POST['meta'][ $row['meta_id'] ]['value'], $row['meta_value'], $row['meta_key'], $row['meta_id'] ); cnMeta::updateByID('entry', $row['meta_id'], $_POST['meta'][$row['meta_id']]['value'], $_POST['meta'][$row['meta_id']]['key']); $metaIDs['updated'] = $row['meta_id']; } if (isset($_POST['meta'][$row['meta_id']]['value']) && $_POST['meta'][$row['meta_id']]['value'] === '::DELETED::') { // Record entry meta to be deleted. cnMeta::deleteByID('entry', $row['meta_id']); $metaIDs['deleted'] = $row['meta_id']; } } } // Lastly, add any new meta the user may have added. if (isset($_POST['newmeta']) || !empty($_POST['newmeta'])) { foreach ($_POST['newmeta'] as $row) { // If the key begins with an underscore, remove it because those are private. if (isset($row['key'][0]) && '_' == $row['key'][0]) { $row['key'] = substr($row['key'], 1); } $metaIDs[] = cnMeta::add('entry', $id, $row['key'], $row['value']); } // $newmeta = cnMeta::add( 'entry', $id, $_POST['newmeta']['0']['key'], $_POST['newmeta']['99']['value'] ); } if (isset($_POST['metakeyselect']) && $_POST['metakeyselect'] !== '-1') { $metaSelect[] = cnMeta::add('entry', $id, $_POST['metakeyselect'], $_POST['newmeta']['99']['value']); } $metaIDs['added'] = array_merge($newmeta, $metaSelect); break; } return $metaIDs; }
/** * Outputs the data saved in the "Custom Fields" entry metabox. * This should not be confused with the fields registered with * cnMetaboxAPI. Those fields should be output using a registered * action which runs in $this->getMetaBlock(). * * @access private * @since 0.8 * @uses wp_parse_args() * @uses apply_filters() * @param array $metadata The metadata array passed from $this->getMetaBlock(). @see self::getMetaBlock(). * * @return string */ private function renderMetaBlock($metadata) { $out = ''; $defaults = array('container_tag' => 'ul', 'item_tag' => 'li', 'key_tag' => 'span', 'value_tag' => 'span', 'separator' => ': ', 'before' => '', 'after' => ''); $atts = wp_parse_args(apply_filters('cn_output_meta_atts', $defaults), $defaults); foreach ((array) $metadata as $key => $value) { // Do not render any private keys; ie. ones that begin with an underscore // or any fields registered as part of a custom metabox. if (cnMeta::isPrivate($key, 'entry')) { continue; } $out .= apply_filters('cn_entry_output_meta_key', sprintf('<%1$s><%2$s class="cn-entry-meta-key">%3$s%4$s</%2$s><%5$s class="cn-entry-meta-value">%6$s</%5$s></%1$s>' . PHP_EOL, $atts['item_tag'], $atts['key_tag'], trim($key), $atts['separator'], $atts['value_tag'], implode(', ', (array) $value)), $atts, $key, $value); } if (empty($out)) { return ''; } $out = apply_filters('cn_entry_output_meta_container', sprintf('<%1$s class="cn-entry-meta">%2$s</%1$s>' . PHP_EOL, $atts['container_tag'], $out), $atts, $metadata); echo $atts['before'] . $out . $atts['after'] . PHP_EOL; }