In my wordpress theme there is a custom post type named songs and in that post type there is a custom field named playlist which contain songs information like artist name,download link,song lyric etc...
My problem is that this custom field is serialized in json version of my website
and i don't know how to fix that.
I use json api plugin for word press.
here is an example of what it shows in json
...
"custom_fields": {
...
"playlist": [
"a:1:{i:0;a:19:{s:5:\"title\";s:44:\"Hosein Tohi And Sami Beigi - Ba Man Miraghsi\";s:3:\"mp3\";s:134:\"http:\/\/dl.paradi3emusic.com\/Musics\/Aban%2094\/Persian\/Single\/Hosein%20Tohi%20And%20Sami%20Beigi%20-%20Ba%20Man%20Miraghsi%20-%20128.mp3\";s:7:\"radioip\";s:0:\"\";s:9:\"radioport\";s:0:\"\";s:11:\"buy_title_a\";s:14:\"\u06a9\u06cc\u0641\u06cc\u062a 320\";s:10:\"buy_icon_a\";s:14:\"cloud-download\";s:10:\"buy_link_a\";s:134:\"http:\/\/dl.paradi3emusic.com\/Musics\/Aban%2094\/Persian\/Single\/Hosein%20Tohi%20And%20Sami%20Beigi%20-%20Ba%20Man%20Miraghsi%20-%20320.mp3\";s:11:\"buy_title_b\";s:14:\"\u06a9\u06cc\u0641\u06cc\u062a 128\";s:10:\"buy_icon_b\";s:14:\"cloud-download\";s:10:\"buy_link_b\";s:134:\"http:\/\/dl.paradi3emusic.com\/Musics\/Aban%2094\/Persian\/Single\/Hosein%20Tohi%20And%20Sami%20Beigi%20-%20Ba%20Man%20Miraghsi%20-%20128.mp3\";s:11:\"buy_title_c\";s:0:\"\";s:10:\"buy_icon_c\";s:14:\"cloud-download\";s:10:\"buy_link_c\";s:0:\"\";s:11:\"buy_title_d\";s:0:\"\";s:10:\"buy_icon_d\";s:14:\"cloud-download\";s:10:\"buy_link_d\";s:0:\"\";s:10:\"buy_custom\";s:0:\"\";s:11:\"lyric_title\";s:0:\"\";s:5:\"lyric\";s:0:\"\";}}"
],
...
},
...
****EDIT*****
I want to have another custom field which contain json array of these serialized data but unserialized
also I tried this but didn't worked.
add_post_meta($id, 'myplaylist1', $playlist);
You will need to write a filter to deserialize the content before it is output by the json api plugin.
There is a filter applied by the plugin just before the json is output, documented here:
https://en-gb.wordpress.org/plugins/json-api/other_notes/#5.-Extending-JSON-API
That would be suitable for this task.
Add the following to your themes functions.php:
add_filter('json_api_encode', function($response){
if (isset($response['posts'])) {
foreach ($response['posts'] as $post) {
deserialize_playlist($post);
}
} else if (isset($response['post'])) {
deserialize_playlist($response['post']);
}
return $response;
});
function deserialize_playlist(&$post) {
if(isset($post->custom_fields->playlist)){
$playlists = $post->custom_fields->playlist;
//custom fields appear to always be returned as an array
foreach($playlists as &$playlist){
$playlist = unserialize($playlist);
}
$post->custom_fields->playlist = $playlists;
}
}
You can use wordpress built in maybe_unserialize() function to unserialize a serialize data
https://codex.wordpress.org/Function_Reference/maybe_unserialize
Related
Is there method to use wp all export php functions to replace data or maybe any other statement we can use directly inside custom XML export.
What i need is to achieve this logic
I have custom taxonomy in XML called {Conditions} which return value of each post as "Used" "New"
Values appear correctly, but where i need to export XML required different values then those above, which i need to replace during export.
Logic:
If {Conditions} = "Used"
Set Used = "20";
Elseif{Conditions} = "New"
Set New = "10";
WP ALL EXPORT PLUGIN
Please take a look at "Pass Data Through PHP Functions" doc:
"...you can click on the export field and then use the "Export the value returned by a PHP function" option."
https://www.wpallimport.com/documentation/export/pass-data-through-php-functions/
You would specify the function name into the text field as in the screenshot on the documentation page (convert_conditions) or, if running a custom XML export, call the function from the field with something like this:
[convert_conditions({Conditions})]
...and provide the function in the function editor for the field:
function convert_conditions($cond_from_xml = null) {
if($cond_from_xml === 'Used') {
return '20';
} elseif($cond_from_xml === 'New') {
return '10';
} else {
return '0';
}
}
I am using a Toolset plugin for Wordpress and try to make it save the id of the page where the user fills up the form.
This plugin has "hooks" for it.
This is what they say about it.
cred_save_data
Description
This hook allows doing a custom action when post data is saved to the database.
Arguments
post_id. The id of the current created or edited post.
form_data. An associative array of data about current form:
id. The form of ID.
post_type. The post type that the form operates on.
form_type. The type of form - 'new' or 'edit'.
container_id. Refers to the post_id of the post, page or custom post type that contains the CRED form
EXAMPLE:
add_action('cred_save_data', 'my_save_data_action',10,2);
function my_save_data_action($post_id, $form_data)
{
// if a specific form
if ($form_data['id']==12)
{
if (isset($_POST['my_custom_field']))
{
// add it to saved post meta
add_post_meta($post_id, '__my_custom_field', $_POST['my_custom_field'], true);
}
}
}
so I added this modified PHP code in functions.php of the theme:
add_action('cred_save_data', 'my_save_data_action',10,2);
function my_save_data_action($post_id, $form_data)
{
// if a specific form
if ($form_data['id']==2080) // the id of the form
{
if (isset($_POST['container_id']))
{
// add it to saved post meta
add_post_meta($post_id, 'formetadata', $_POST['container_id'], true);
}
}
}
where for metadata is a slug for custom field created to collect metadata, including the id of the page, where the form was filled up.
It does not work. The form collects data, creates a post, but the field for metadata remains empty.
What did I do wrong?
I don't have enough knowledge about PHP and may be completely misunderstood instructions...
So looking at the docs and your function I see they use the key container_id and you use $_POST['container_id']. Im just guessing but it sounds like those are the same id? If so then you can access it via the $form_data like below:
add_action('cred_save_data', 'my_save_data_action',10,2);
function my_save_data_action($post_id, $form_data)
{
// if a specific form
if ($form_data['id']==2080) // the id of the form
{
if (isset($_POST['container_id']))
{
// add it to saved post meta
add_post_meta($post_id, 'formetadata', $form_data['container_id'], true);
}
}
}
Running Joomla 3.3.0-dev
I'm following the info posted here about adding tag support to a third-party component.
I've added the content type to the #__content_types table and modified my table file like this:
class MycomponentTableElement extends JTable
{
public $tagsHelper = null; // failed when protected and public
public function __construct(&$_db)
{
parent::__construct('#__mycomponent', 'id', $_db);
// Add Joomla tags
JObserverMapper::addObserverClassToClass('JTableObserverTags', 'MycomponentTableElement', array('typeAlias' => 'com_mycomponent.element'));
//$this->_observers = new JObserverUpdater($this); JObserverMapper::attachAllObservers($this); // failed with or without this line
}
I added the tag field in the edit template, and it worked fine-- but when I save an object I get the following error:
Save failed with the following error: Unknown column 'tagsHelper' in 'field list'
What am I missing? There's no other steps (besides front-end steps!) that are mentioned. It seems like I need to modify the model but that info is not applicable.
Thanks
"This Page Needs Copy Editing" and it's really true!
I also follow initial steps as described in page
Register a 'Content type' for the extension view(s)
Add 'Observer methods' to the extension table class(es)
Add 'Tag fields' to the extension edit forms
But to make field tag works on custom extensions I need to explicit set form field value in view file of backend:
$tagsHelper = new JHelperTags;
$this->form= $this->get('Form');
$this->form->setValue('tags', null, $tagsHelper->getTagIds( $this->item->id, 'com_custom.viewname') );
in this way on edit page all seems to work correctly.. surely exist better and more clean method, but until doc page will not be updated, this can help someone!
1- Add tag field to your xml form file or edit template file
2- Modify #__content_types table file:
function __construct(&$db)
{
parent::__construct('#__ir_products', 'id', $db);
JTableObserverTags::createObserver($this, array('typeAlias' => 'com_itemreview.product'));
}
3- Modify model file getItem function:
public function getItem($pk = null)
{
$item = parent::getItem($pk);
if (!empty($item->id))
{
$item->tags = new JHelperTags;
$item->tags->getTagIds($item->id, 'com_yourcomponent.yourmodel');
}
return $item;
}
I have an app that has rows, each row contains data. The rows are created by the user (just cloning a sample row).
My ajax function looks like this.
save : function(el) {
//Renaming the properties to match the row index and organize
jQuery('#application-builder-layout .builder-row').each(function(row) {
// Iterate over the properties
jQuery(this).find('input, select, textarea').each(function() {
// Save original name attr to element's data
jQuery(this).data('name', jQuery(this).attr('name') );
// Rewrite the name attr
jQuery(this).attr('name', 'application[rows]['+row+'][elements]['+jQuery(this).attr('name')+']');
});
});
//Looping through each row and saving them seperately with new rowkey
setTimeout(function() {
// Iterate over the layers
jQuery('#application-builder-layout .row-box').each(function(row) {
// Reindex layerkey
jQuery(this).find('input[name="rowkey"]').val(row);
// Data to send
$data = jQuery('#application-builder-layout .row-box').eq(row).find('input, textarea, select');
//$data = $data.add( jQuery('#application-builder-layout') );
jQuery.ajax(jQuery('#form').attr('action'), {
type : 'POST',
data : $data.serialize(),
async : false,
success: function( response ) {
//console.log( response );
}
});
});
}, 500);
},
This is the jQuery, it's application style format so this function is inside a var and is called inside a submit function, the problem is not the ajax, looking at it in the console it saves the data fine, just like I have before.
The Problem I cant get all the data into the database (only the last ajax request) take a look below at "Form Data" it shows what my ajax data looks like and how it's inserting into the DB vs how it should insert, I am using json encode and usually this works, but recently I switched to OOP style coding in PHP so I am not sure if that changes anything?
The PHP:
class MyApp {
const Post_Type = 'page';
public function __construct() {
// register actions
add_action('init', array(&$this, 'init'));
}
public function init() {
// Initialize Post Type
add_action('save_post', array(&$this, 'save_post'));
}
//The main save method
public function save_post($post_id) {
// Empty the builder
if($_POST['rowkey'] == 0) {
$builder = array();
}
$builder['rows'][$_POST['rowkey']] = $_POST['application']['rows'][$_POST['rowkey']];
$builder = esc_sql(json_encode($builder));
if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if($_POST['post_type'] == self::Post_Type && current_user_can('edit_post', $post_id)) {
// Update the post's meta field
update_post_meta($post_id, 'MY_DATABASE', $builder);
} else {
return;
}
}
}
The above works fine, except its not inserting the data as an array just inserting the last ajax post call, not each. I am sure in my save method I need to reconfig that somehow, but I am just hacking away and cant find info on the web, so I could really use some insight.
I hope I provided enough.
My code summed up: Just to be clear on whats going on here, let me you some basic HTML of my app.
//This gets cloned and the jQuery renames the rowkey to match the index.
<div class="row-box">
<input type="hidden" name="rowkey" value="0">
<div class="builder-row">
<textarea style="display: block;" name="html"></textarea>
<textarea style="display: block;" name="breakingbad"></textarea>
</div>
</div>
So summed up lets say there is 4 rows, the jQuery renames each row, then loops through each and submits an ajax call for each of them. Then the PHP handles the $_POST, in prior applications working with my custom DB I got it to work but working with wp database I am having issues, maybe I am missing something in my method?
Form Data: the ajax form data looks like this (this is the form data inside headers which can be found in the console(firbug) or network(chrome))
//First element
rowkey:0
application[rows][0][elements][html]:A
application[rows][0][elements][breakingbad]:123
Then if there is another row ajax posts again
//Second element
rowkey:1
application[rows][1][elements][html]:B
application[rows][1][elements][breakingbad]:456
So an and so forth, the database looks like this
{"rows":{"2":{"elements":{"html":"B","breakingbad":"456"}}}}
It should be more like this
{"rows":[{"elements":{"html":"A","breakingbad":"123"},{"elements":{"html":"B","breakingbad":"456"}]}
Holy Smokes Batman: I think I got it, It all resides inside how I handle the $_POST ill update soon with an answer..
The database looks good like this
{"rows":[
{"elements":{"html":"A","breakingbad":"123"}},
{"elements":{"html":"B","breakingbad":"456"}}]
}
Now I can continue to build.. whew this was a MASSIVE headache.
I am modifying an already contributed drupal module (Inline Ajax Search) to handle searching of a specific content type with some search filters (i.e. when searching for help documentation, you filter out your search results by selecting for which product and version of the product you want help with).
I have modified the module some what to handle all the search filters.
I also added in similar functionality from the standard core search module to handle the presenting of the search form and search results on the actual search page ( not the block form ).
The problem is that when i submit the form, i discovered that I'd lose all my post data on that submit because somewhere, and i don't know where, drupal is either redirecting me or something else is happening that is causing me to lose everything in the $_POST array.
here's the hook_menu() implementation:
<?php
function inline_ajax_search_menu() {
$items = array();
$items['search/inline_ajax_search'] = array(
'title' => t('Learning Center Search'),
'description' => t(''),
'page callback' => 'inline_ajax_search_view',
'access arguments' => array('search with inline_ajax_search'),
'type' => MENU_LOCAL_TASK,
'file' => 'inline_ajax_search.pages.inc',
);
}
?>
the page callback is defined as such (very similar to the core search module's search_view function):
<?php
function inline_ajax_search_view() {
drupal_add_css(drupal_get_path('module', 'inline_ajax_search') . '/css/inline_ajax_search.css', 'module', 'all', FALSE );
if (isset($_POST['form_id'])) {
$keys = $_POST['keys'];
// Only perform search if there is non-whitespace search term:
$results = '';
if(trim($keys)) {
require_once( drupal_get_path( 'module', 'inline_ajax_search' ) . '/includes/inline_ajax_search.inc' );
// Collect the search results:
$results = _inline_ajax_search($keys, inline_ajax_search_get_filters(), "page" );
if ($results) {
$results = theme('box', t('Search results'), $results);
}
else {
$results = theme('box', t('Your search yielded no results'), inline_ajax_search_help('inline_ajax_search#noresults', drupal_help_arg()));
}
}
// Construct the search form.
$output = drupal_get_form('inline_ajax_search_search_form', inline_ajax_search_build_filters( variable_get( 'inline_ajax_search_filters', array() ) ) );
$output .= $results;
return $output;
}
return drupal_get_form('inline_ajax_search_search_form', inline_ajax_search_build_filters( variable_get( 'inline_ajax_search_filters', array() ) ) );
}
?>
from my understanding, things should work like this: A user goes to www.mysite.com/search/inline_ajax_search and drupal will process the path given in my url and provide me with a page that holds the themed form for my search module. When i submit the form, whose action is the same url (www.mysite.com/search/inline_ajax_search), then we go thru the same function calls, but we now have data in the $_POST array and one of them is indeed $_POST['form_id'] which is the name of the form "inline_ajax_search_search_form". so we should be able to enter into that if block and put out the search results.
but that's not what happens...somewhere from when i submit the form and get my results and theme it all up, i get redirected some how and lose all my post data.
if anybody can help me, it'd make me so happy lol.
drupal_get_form actually wipes out the $_POST array and so that's why I lose all my post data.
according to this: http://drupal.org/node/748830 $_POST should really be ignored when doing things in drupal. It's better to find a way around using it. One way is the way described in the link, making ur form data persist using the $_SESSION array. I'm sure there are various other and better ways to do this, but yeah, drupal_get_form was the culprit here...