Wordpress Not Saving Custom Post Input Fields - php

I am trying to save a custom post type. I can't figure out why the save isn't working for the input fields listed below.
I included all the relevant code, as I can't see where the problem might be. It seems like everything is working except for the save function (listed last).
I am only trying to save inputs where 'type' => 'singleinput'. I haven't tried to save the 'fulltext' ones.
Can anyone point out where I am going wrong?
//input boxes for custom post
$specialpage->inputs = array(
'item1' => array(
'type' => 'singleinput',
'headline' => 'Page headline',
'bullet1' => 'Bullet Point 1:',
'bullet2' => 'Bullet Point 2:',
'bullet3' => 'Bullet Point 3:'
),
'item2' => array(
'type' => 'fulltext',
'promo1' => 'Promo text 1:',
'promo2' => 'Promo text 2:',
'promo3' => 'Promo text 3:'
),
'item3' => array(
'type' => 'singleinput',
'quote' => 'The quote'
)
);
This function is called to display the meta box.
public function display_meta_box_($post_object){
foreach($this->inputs as $item){
foreach($item as $name => $title){
if ($title == 'singleinput'){
$activate = 'singleinput';
continue;
}
if ($title == 'fulltext'){
$activate = 'fulltext';
continue;
}
if ($activate == 'singleinput'){
$this->singleinput[$name] = $title;
${$this->name . $name} = get_post_meta($post_object->ID, $this->name . $name, true);
echo '<span class="meta_titles">' . $title . '</span>';
?>
<input type='text' class='input_single' name='<?php echo $this->name . $name;?>_name' value='<?php echo ${$this->name . $name}; ?>' >
<?php
}
}
This is the save function
public function save_profile( $post_id, $post_object ) {
if( $this->name == $post_object->post_type){
//check if singleinput are defined for this custom post type
if ($this->singleinput){
//save single line text input boxes
foreach ($this->singleinput as $name => $title){
update_post_meta($post_id, $this->name . $name, $_POST[$this->name . $name . '_name']);
}
}
}
Edit: Added Save Function
$simplejoiner->saveNow();
public function saveNow(){
add_action( 'save_post', array($this, 'save_profile'), 10, 2 );
}

Related

Add a custom field to Woocommerce general setting in store address section

I'm looking to add a Phone number field to the Woocommerce settings page. I can get the field to add to the settings list, but it gets appended to the bottom of the entire tab. Ideally I'd like to add the field in the Store Address sections on the general tab.
Here's what I'm using now (trimmed down):
add_filter('woocommerce_general_settings', 'woocommerce_add_phone');
function woocommerce_add_phone($settings) {
$settings[] = array(
'title' => 'Phone Number',
'type' => 'text',
);
$sections[] = array( 'type' => 'sectionend', 'id' => 'store_address' );
return $settings;
}
I made an attempt at using array_splice but couldn't get anywhere with it.
Any advice would be greatly appreciated.
This can be done in a simple way targeting the woocommerce_store_postcode field ID to insert the Store phone custom field in this general settings at the right location:
add_filter('woocommerce_general_settings', 'general_settings_shop_phone');
function general_settings_shop_phone($settings) {
$key = 0;
foreach( $settings as $values ){
$new_settings[$key] = $values;
$key++;
// Inserting array just after the post code in "Store Address" section
if($values['id'] == 'woocommerce_store_postcode'){
$new_settings[$key] = array(
'title' => __('Phone Number'),
'desc' => __('Optional phone number of your business office'),
'id' => 'woocommerce_store_phone', // <= The field ID (important)
'default' => '',
'type' => 'text',
'desc_tip' => true, // or false
);
$key++;
}
}
return $new_settings;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and work… You will get something like:
LoicTheAztec code works fine but I wanted to find a solution without looping. Here is my version:
function add_phone_number_settings($settings) {
// Search array for the id you want
$key = array_search('woocommerce_store_postcode', array_column($settings, 'id')) + 1;
$custom_setting[] = array(
'title' => __('Phone Number'),
'desc' => __("Enter shop phone number"),
'id' => 'woocommerce_store_phone_number',
'default' => '',
'type' => 'text',
'desc_tip' => true,
);
// Merge with existing settings at the specified index
$new_settings = array_merge(array_slice($settings, 0, $key), $custom_setting, array_slice($settings, $key));
return $new_settings;
}
add_filter('woocommerce_general_settings', 'add_phone_number_settings');
This code will add your phone number after the post code element in the Store Address section. I borrowed the splice function from here.
add_filter('woocommerce_general_settings', 'woocommerce_general_settings_add_phone_number');
function woocommerce_general_settings_add_phone_number($settings) {
$phone_number = array(
'title' => __( 'Phone Number', 'woocommerce' ),
'desc' => __( 'Add your phone number.', 'woocommerce' ),
'id' => 'woocommerce_store_phone_number',
'default' => '',
'type' => 'text',
'desc_tip' => false,
);
$array_pos = 0;
foreach ($settings as $key => $value) {
if ( $value['id'] == 'woocommerce_store_postcode' ) {
$array_pos = $key;
break;
}
}
$settings = array_insert( $settings, $phone_number, $array_pos + 1 );
return $settings;
}
/*
Array insert
#array the array to add an element to
#element the element to add to the array
#position the position in the array to add the element
*/
if(!function_exists('array_insert')) {
function array_insert($array, $element, $position) {
// if the array is empty just add the element to it
if(empty($array)) {
$array[] = $element;
// if the position is a negative number
} elseif(is_numeric($position) && $position < 0) {
// if negative position after count
if(count($array) + $position < 0) {
$position = 0;
} else {
$position = count($array) + $position;
}
// try again with a positive position
$array = array_insert($array, $element, $position);
// if array position already set
} elseif(isset($array[$position])) {
// split array into two parts
$split1 = array_slice($array, 0, $position, true);
$split2 = array_slice($array, $position, null, true);
// add new array element at between two parts
$array = array_merge($split1, array($position => $element), $split2);
// if position not set add to end of array
} elseif(is_null($position)) {
$array[] = $element;
// if the position is not set
} elseif(!isset($array[$position])) {
$array[$position] = $element;
}
// clean up indexes
$array = array_values($array);
return $array;
}
}

Yii dependant dropDownList

I need to create to dependant dropDownLists with yii. Thus, I create a view and an action in controller like this :
The view
<?php
echo "<div class='row'>";
echo $form->labelEx($model, 'id_structure');
echo $form->dropDownList($model, 'id_structure', GxHtml::listDataEx(StructureInformation::model()->findAllAttributes()),
array('ajax' => array('type' => 'POST',
'url' => CController::createUrl('InfoComplementAAjouter/fillTypeList'),
'update' => '#typeDonnee',
'data' => array('id_structure' => 'js:this.value'))
));
echo $form->error($model, 'id_structure');
echo '</div>';
echo "<div class='row'>";
echo $form->labelEx($model, 'type');
echo $form->dropDownList($model, 'type', array(), array('prompt' => 'Sélectionner', 'id' => 'typeDonnee'));
echo $form->error($model, 'type');
echo '<div>';
?>
Now the action in the Controller InfoComplementAAjouterController :
public function actionFillTypeList(){
$id_struct = $_POST['InfoComplementAAjouter']['id_structure']; //I get the selected value
$taille = StructureInformation::model()->find('id = ' . (int)$id_struct)->taille; //and then pass it to the StructureInformation model to obtain the attribute taille
//I create two arrays which content will be the options of my dropDownList.
$un = array('text'=> 'Texte', 'radio' => 'Bouton radio', 'dropDownList' => 'Liste déroulante');
$plusieurs = array( 'checkboxlist' => 'Choix multiple',);
//If $taille == 1, I display the contents of $un; if $taille > 1, the content of $plusieurs will be displayed.
if($taille == 1){
foreach ($un AS $value => $name){
$opt = array();
$opt['value'] = $value;
echo CHtml::tag('option', $opt, CHtml::encode($name), true);
}
}
if($taille > 1){
foreach ($plusieurs AS $value => $name){
$opt = array();
$opt['value'] = $value;
echo CHtml::tag('option', $opt, CHtml::encode($name), true);
}
}
die;
}
I remark that the action is not executed. I can not understand why.
Can somebody help me to fix the problem ?
I just saw a typo:
'upedate' => '#typeDonnee',
should be 'update'
try with fixing it first
Edit:
you have more small errors/typos
echo $form->dropDownList($model, 'id_structure', GxHtml::listDataEx(StructureInformation::model()->findAllAttributes(),
array('ajax' => array('type' => 'POST',
'url' => CController::createUrl('InfoComplementAAjouter/fillTypeList'),
'update' => '#typeDonnee',
'data' => array('id_structure' => 'js:this.value'))
));
here you need to close parentheses
=====================================================
StructureInformation::model()->findAllAttributes()
there is no findAllAttributes() method in CActiveRecord
maybe you wanted to use findAllByAttributes(), but then you would want to pass some attributes. If this is your custom method then you should explain how it works, or paste a code
Edit 2:
$_POST['InfoComplementAAjouter']['id_structure']
Try to access post like this:
$_POST['id_structure']
I think you send post in that structure
It's not that easy for me to duplicate your situation, so I'm kinda shooting in the dark

Yii cgridview add custom html attribute to buttons from data not working

I tried to add custom html attribute to cgridview buttons from dataProvider , Im using bootstrap yii bootstrap bootstrap.widgets.TbButtonColumn
I tried
'pbs_id'=>'{$data->pbs_id}',
and
'pbs_id'=>'{$data["psp_id"]}',
but it return it as string
$this->widget('bootstrap.widgets.TbGridView', array(
'type'=>'striped bordered condensed',
'dataProvider'=>$db_slabs_data,
'template'=>"{items}",
'columns'=>array(
array('name'=> 'pbs_id', 'header'=>'Slab Id'),
array('name'=> 'pbs_name', 'header'=>'Slab Name'),
array(
'htmlOptions' => array('nowrap'=>'nowrap'),
'class'=>'bootstrap.widgets.TbButtonColumn',
'template'=>"{update}",
'updateButtonUrl'=>'Yii::app()->createUrl("", array("pbs_id"=>$data["pbs_id"]))',
'buttons'=>array
(
'update' => array
(
'label'=> Yii::t('common', 'LBL_UPDATE'),
'icon'=>'icon-pencil',
'url'=>'Yii::app()->createUrl("", array("pbs_id"=>$data["pbs_id"]))',
'options'=>array(
'pbs_id'=>'{$data["psp_id"]}',
),
),
),
),
),
));
ad the result is :
<i class="icon-pencil"></i>
how I can do that.
Thanks
I solved my problem by:
inside this file /protected/extensions/bootstrap/widgets/TbButtonColumn.php there are a method renderButton()
I override this method to to render additional html attribute for buttons:
protected function renderButton($id, $button, $row, $data) {
if (isset($button['visible']) && !$this->evaluateExpression($button['visible'], array('row' => $row, 'data' => $data)))
return;
$label = isset($button['label']) ? $button['label'] : $id;
$url = isset($button['url']) ? $this->evaluateExpression($button['url'], array('data' => $data, 'row' => $row)) : '#';
$options = isset($button['options']) ? $button['options'] : array();
/* added to render additional html attribute */
if (isset($button['options']) AND !(empty($button['options']))) {
foreach ($button['options'] as $key => $value) {
if (preg_match('#\$(data|row)#', $value)) {
$options["$key"] = $this->evaluateExpression($button['options'][$key], array('data' => $data, 'row' => $row));
} else {
$options["$key"] = $value;
}
}
}
/* end */
if (!isset($options['title']))
$options['title'] = $label;
if (!isset($options['rel']))
$options['rel'] = 'tooltip';
if (isset($button['icon'])) {
if (strpos($button['icon'], 'icon') === false)
$button['icon'] = 'icon-' . implode(' icon-', explode(' ', $button['icon']));
echo CHtml::link('<i class="' . $button['icon'] . '"></i>', $url, $options);
}
else if (isset($button['imageUrl']) && is_string($button['imageUrl']))
echo CHtml::link(CHtml::image($button['imageUrl'], $label), $url, $options);
else
echo CHtml::link($label, $url, $options);
}
and inside the grid
'buttons'=>array
(
'update' => array
(
'label'=> Yii::t('common', 'LBL_UPDATE'),
'icon'=>'icon-pencil',
'url'=>'Yii::app()->createUrl("", array("pbs_id"=>$data["pbs_id"]))',
'options'=>array(
'id'=>'$data["id"]',
'new_attribute'=> '$data["your_key"]',
),
),
),
Well, you simply cannot do this like this, options values will not be evaluated as PHP expression : http://www.yiiframework.com/doc/api/1.1/CButtonColumn#buttons-detail
You should extend bootstrap.widgets.TbButtonColumn to handle this, e.g. :
Create a new file MyTbButtonColumn.php in protected/widgets (or else) :
Yii::import('bootstrap.widgets.TbButtonColumn');
class MyTbButtonColumn extends TbButtonColumn
{
protected function renderButton($id, $button, $row, $data)
{
if (isset($button['options']) && is_array($button['options']))
{
foreach ($button['options'] as &$v)
{
// evaluate ?
if (preg_match('#\$(data|row)#', $v))
$v = $this->evaluateExpression($v, array('data'=>$data, 'row'=>$row));
}
}
parent::renderButton($id, $button, $row, $data);
}
}
And modify your view :
$this->widget('application.widgets.MyTbButtonColumn', array(...));
PS: You could also use javascript to add these attributes.

Every third element should have a date beside it

So I have been asking a lot of array based questions as I strive to understand PHP's main source of data structure.
I am currently working on building a class that spits out a list of artists and their songs. each third song has a date beside it. as seen in this array:
$music = array(
'Creed' => array(
'Human Clay' => array(
array(
'title' => 'Are You Ready'
),
array(
'title' => 'What If'
),
array(
'title' => 'Beautiful',
'date' => '2012'
),
array(
'title' => 'Say I'
),
array(
'title' => 'Wrong Way'
),
array(
'title' => 'Faceless Man',
'date' => '2013'
),
array(
'title' => 'Never Die'
),
array(
'title' => 'With Arms Wide pen'
),
array(
'title' => 'Higher',
'date' => '1988'
),
array(
'title' => 'Was Away Those Years'
),
array(
'title' => 'Inside Us All'
),
array(
'title' => 'Track 12',
'date' => '1965'
),
),
),
);
What I wrote was the following:
class Music{
protected $_music = array();
protected $_html = '';
public function __construct(array $music){
$this->_music = $music;
}
public function get_music(){
$year = '';
$this->_html .= '<d1>';
foreach($this->_music as $artist=>$album){
$this->_html .= '<dt>' . $artist . '</dt>';
foreach($album as $track=>$song){
foreach($song as $songTitle){
if(isset($songTitle['date']) && !empty($songTitle['date'])){
$year = '['.$songTitle['date'].']';
}
$this->_html .= '<dd>' . $songTitle['title'] . $year. '</dd>';
}
}
}
$this->_html .= '</d1>';
}
public function __toString(){
return $this->_html;
}
}
$object = new Music($music);
$object->get_music();
echo $object;
My question is that I end up getting something back that looks like this:
Creed
Are You Ready
What If
Beautiful[2012]
Say I[2012]
Wrong Way[2012]
Faceless Man[2013]
Never Die[2013]
With Arms Wide pen[2013]
Higher[1988]
Was Away Those Years[1988]
Inside Us All[1988]
Track 12[1965]
As you can see almost every song has a date beside it when in the array that is not the case. My question is whats the deal? I thought in my loop I was very clear in stating if this song has a year, set it and then print it beside the song title?
Can some one point me in the right direction please?
When the date is not set for a song, the year variable is holding the value from the previous song (for which it was set). You are still actually telling it to print year next to the title, whether or not the date is set.
You need an else clause on the if:
if(isset($songTitle['date']) && !empty($songTitle['date'])){
$year = '['.$songTitle['date'].']';
} else {
$year = '';
}
This will clear out year when the date is not set.
You never reset $year after you set it, so once you encounter the first year value in your array, you'll be constantly using that same year until a new one comes along:
if(isset($songTitle['date']) && !empty($songTitle['date'])){
$year = '['.$songTitle['date'].']';
} else {
$year = ''; /// reset year to blank
}
And in somewhat unrelated stuff, this is probably a typo:
$this->_html .= '<d1>';
^--- number one? not letter L for a `<dl>` tag?
You are not resetting year in foreach loop, so it is using last set year until value is reassigned. Here is corrected Music class.
class Music{
protected $_music = array();
protected $_html = '';
public function __construct(array $music){
$this->_music = $music;
}
public function get_music(){
$year = '';
$this->_html .= '<d1>';
foreach($this->_music as $artist=>$album){
$this->_html .= '<dt>' . $artist . '</dt>';
foreach($album as $track=>$song){
foreach($song as $songTitle){
if(isset($songTitle['date']) && !empty($songTitle['date'])){
$year = '['.$songTitle['date'].']';
}
$this->_html .= '<dd>' . $songTitle['title'] . $year. '</dd>';
$year = "";
}
}
}
$this->_html .= '</d1>';
}
public function __toString(){
return $this->_html;
}
}

How to add html to an array in php?

I am trying to add some html code before each tag printed as an array element.
My code:
$term_links = array();
foreach ($vars['node']->taxonomy as $term)
{
$term_links[] = l($term->name, 'taxonomy/term/' . $term->tid,
array(
'attributes' => array(
'title' => $term->description
)));
}
$vars['node_terms'] = implode(', ', $term_links);
At the moment the tags are printed seperated by a comma. I would like to add a small image before each tag element using img src="tag.png" How can I do this?
EDIT - My current Code, still not working.
if (module_exists('taxonomy')) {
$img = 'some html';
$text = $img . $term->name;
$path = 'taxonomy/term/' . $term->tid;
$term_links = array();
foreach ($vars['node']->taxonomy as $term) {
$term_links[] = l($text, $path, array(
'html' => TRUE,
'attributes' => array(
'title' => $term->description
)));
}
$vars['node_terms'] = implode(', ', $term_links);
}
}
Dupal's l() function has an option "html" you can set it to TRUE and use IMG + TITLE as a title.
Here is the example:
$img = '<img src="..." />';
$text = $img . $term->name;
$path = 'taxonomy/term/' . $term->tid;
$term_links[] = l($text, $path, array(
'html' => TRUE,
'attributes' => array(
'title' => $term->description
)
));

Categories