CodeIgniter + NuSOAP - Input multidimensional array - arrays

I was looking for it several times but didn't find any answer that help me, so I'm asking now and I hope someone can help me.
I have some webservices in a CodeIgniter application that returns complex types and whatever, and now I need create a service that RECEIVE a complex type like this:
Array ("position1" => 'mambo jambo',
"position2" => 'more mambo jambo',
"position3" => Array("0" => Array(), "1" => Array()),
"position4" => Array("0" => Array(), "1" => Array());
In resume, it a complex type that have some normal data and inside it two arrays that receive N positions of another array. I need it because I receive some Invoice and in invoice I receive N products (every with about 4 positions) and N quotas of payment (every with value, date, etc).
I tryed create a complex type with two positions where every of them as an other complex type that is an array of another complex type. Yes, I know, it is complex =P
Is like this that I use when I create output services to return data like this, but to input doesn't works. When I try test it in SoapUI App that generate this XML:
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:SOAPServerWSDL">
<soapenv:Header/>
<soapenv:Body>
<urn:gravaNotaFiscal soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<token xsi:type="xsd:string">?</token>
<nota_fiscal xsi:type="ped:NotaFiscal" xmlns:ped="http://ultraman/tr1/sistema/api/pedidoservice?wsdl">
<!--You may enter the following 7 items in any order-->
<filial xsi:type="xsd:string">?</filial>
<numero xsi:type="xsd:string">?</numero>
<serie xsi:type="xsd:string">?</serie>
<dt_emissao xsi:type="xsd:string">?</dt_emissao>
<valor xsi:type="xsd:string">?</valor>
<itens_nota xsi:type="ped:Itens_Nota"/>
<duplicatas_nota xsi:type="ped:Duplicatas_Nota"/>
</nota_fiscal>
</urn:gravaNotaFiscal>
</soapenv:Body>
</soapenv:Envelope>
Last two positions "itens_nota" and "duplicatas_nota" need to be my two arrays, but SoapUI doesn't create it right.
Using "itens_nota" for example, I created two complex types like this:
$this->nusoap_server->wsdl->addComplexType(
'ItemNF',
'complexType',
'struct',
'all',
'',
array(
"filial" => array('name' => 'filial', 'type' => 'xsd:string'),
"serie" => array('name' => 'serie', 'type' => 'xsd:string'),
"nota_fiscal" => array('name' => 'nota_fiscal', 'type' => 'xsd:string'),
"seq" => array('name' => 'seq', 'type' => 'xsd:string'),
"pedido" => array('name' => 'pedido', 'type' => 'xsd:string'),
"item" => array('name' => 'item', 'type' => 'xsd:string'),
"qtd" => array('name' => 'qtd', 'type' => 'xsd:string')
)
);
$this->nusoap_server->wsdl->addComplexType("Itens_Nota",
"complexType",
"array",
"",
"SOAP-ENC:Array",
array(),
array(array("ref"=>"SOAP-ENC:arrayType","wsdl:arrayType"=>"tns:ArrayOfString[]")),
"tns:ItemNF"
);
My input parameter is "Nota_Fiscal", is a complex type and it last two positions is:
"itens_nota" => array("name" => 'itens_nota', 'type' => 'tns:Itens_Nota'),
"duplicatas_nota" => array("name" => 'duplicatas_nota', 'type' =>'tns:Duplicatas_Nota')
My arrays!
But doesn't works! Someone know why? Where I made mistakes?
If possible I wanna an example of how make a service to input arrays like this, doesn't need be my problem, only an example to give me a direction.
Thanks!

Related

prestashop multiple checkboxes do not save values

I can't figure out why the checkbox values are not saved in the database using helpers.
Trying to save some customers ids from my module's setting :
The array :
$custs = Customer::getCustomers();
foreach ($custs as $key => $value) {
$options[] = array(
'id_customer' => (int)$value['id_customer'],
'infos' => $value['firstname'].' '.$value['lastname'].' | '.$value['email']
);
}
The checkboxes :
'input' => array(
array(
'type' => 'checkbox',
'label' => $this->l('Customers'),
'desc' => $this->l('Select the Customers.'),
'name' => 'MY_MODULE_CUSTOMERS',
'values' => array(
'query' => $options,
'id' => 'id_customer',
'name' => 'infos',
),
),
)
The $_POST is always empty but works well with another input. Any help will be appreciated.
Thank you.
I don't think its in PS docs. But with a bit of code inspecting you can see in
Backoffice/themes/default/template/helpers/form/form.tpl
<input type="checkbox" name="{$id_checkbox}" id="{$id_checkbox}" class="{if isset($input.class)}{$input.class}{/if}"{if isset($value.val)} value="{$value.val|escape:'html':'UTF-8'}"{/if}{if isset($fields_value[$id_checkbox]) && $fields_value[$id_checkbox]} checked="checked"{/if} />
{$value[$input.values.name]}
add the porperty 'val' to option.
$options[] = array(
'id_carrier' => $carrier['id_carrier'],
'name' => $carrier['name'],
'val' => $carrier['id_carrier'],
);
Adn you get the desired serialization for the input values.
"transportistas" => array:2 [▼
0 => "73"
1 => "78"
]
Your code is correct, I tried it and this is result
http://screencast.com/t/wfsW86iJj
You have to click at least one checkbox.
Show data on server :
print_r($_POST);
die();
a better could be using groupbox but its quite difficult, take a look to the AdminCustomers controller class in the controllers directory of the prestachop, this has a multiselect group that used a relational table event stored in single field
If you want to be easy, using a single field to store in the database, take a look to THE COMPLETE CODE AND ALL THE STEPS AT: https://groups.google.com/forum/m/?hl=es#!topic/venenuxsarisari/z8vfPsvFFjk
at the begining dont forget to added that line:
// aqui el truco de guardar el multiselect como una secuencia separada por comas, mejor es serializada pero bueh
$this->fields_value['MY_MODULE_CUSTOMERS[]'] = explode(',',$obj->id_employee);
this $obj are the representation of the loaded previous stored value when go to edit ... from that object, get the stored value of the field of your multiselect, stored as "1,3,4,6"
and the in the field form helper list of inputs define the select multiple as:
array(
'type' => 'checkbox',
'label' => $this->l('Select and employee'),
'name' => 'MY_MODULE_CUSTOMERS[]',
'required' => false,
'col' => '6',
'default_value' => (int)Tools::getValue('id_employee_tech'),
'values' => array(
'query' => $options,
'id' => 'id_customer',
'name' => 'infos',
),
),
an then override the post process too
public function postProcess()
{
if (Tools::isSubmit('submitTallerOrden'))
{
$_POST['MY_MODULE_CUSTOMERS'] = implode(',', Tools::getValue('MY_MODULE_CUSTOMERS'));
}
parent::postProcess();
}
this make stored in the db as "1,2,3"

Getting data by search filter from associated models

i have an question regarding search filter in cakephp. Without complicating my question, below are the structure of what i want....
1) I have a projects table.
2) another one is project_funder_names table which is associated with projects table. project_id is in project_funder_names table. i have made project_funder_names table because i need multiple funder names for a single project, thats why i have made this table.
3) now the main point is i want if i search multiple funders in search filter which is coming in dropdown with checkbox, i will get project details according to these values. so how it would happen.
here is my cakephp find all query....
$project_info = $this->Project->find('all', array(
'conditions' =>
array(
'Project.status' => 1,
'OR' => array($search)),
'fields' => array('id', 'title', 'short_description', 'budget_allocation', 'currency', 'total_comments', 'published_date'),
'contain' => array(
'ProjectFunderName' => array(
'conditions' => array($search_funder)),
'Currency' => array('currency_symbol'),
'ProjectBookmark' => array('project_id', 'user_id')
)
)
);
problem is in $search_funder.
please help me for this.. thanks.
Looks like you need to search results based on associated models. One drawback of using containable behavior is if you're trying to assign a condition to an associated model, the main model will be retrieved no matter what.
In situations where you'd want to retrieve the main as well as the associated records based on a condition for the associated model, I'd suggest you to use join.
$joins = array(
array('table' => 'project_funder_names',
'alias' => 'ProjectFunderName',
'type' => 'LEFT',
'conditions' => array('ProjectFunderName.project_id = Project.id')
),
array('table' => 'currencies',
'alias' => 'Currency',
'type' => 'LEFT',
// It's unclear how currencies is associated with the other tables. Use appropriate table join condition here
),
array('table' => 'project_bookmarks',
'alias' => 'ProjectBookmark',
'type' => 'LEFT',
'conditions' => array('ProjectBookmark.project_id = Project.id')
)
)
);
$project_info = $this->Project->find('all',
array(
"joins" => $joins,
"fields" => array(.........) // Specify all your desired fields here
"conditions" => array(....) // Specify all conditions for Project, ProjectFunderName models.
)
);
Hope this helps.
Peace! xD

Creating a list out of input fields in cakePHP

I have a form for creating a task, and when creating it, user is asked to select which employees will be assigned to it. There may be just one employee or even up to 10. I allow user to dynamically create those input fields on the go, but the array that i get after the form submition looks like this:
array(
'Event' => array(
'project_id' => '62',
'user_id' => '23',
'user_id2' => '24',
'user_id4' => '28',
'user_id8' => '30',
'hours' => '6',
'minutes' => '0',
'assignment' => '',
'material' => 'safsaf',
'date' => '2013-10-12',
)
)
The problem is I do not know how to iterate over the user_ids.
Is it possible to save the IDs as a list? Or is there any other solution?
Use CakePHP's find('list') to retrieve the $users in an key=>value array, then set the multiple attribute of the input to true:
echo $this->Form->select('Model.field', $users, array('multiple' => true));
$attributes['multiple'] If ‘multiple’ has been set to true for an
input that outputs a select, the select will allow multiple
selections:

Primary and Secondary Sorting in Wordpress

I am creating a Wordpress theme that catalogs albums, and I have created the custom post type, created the custom fields, and have them successfully pulling in. I have several custom fields including; Artist, Album, Size, Label etc. I currently have the posts sorting alphabetically by the Artist name with this array:
$args=array(
'post_type' => 'albums',
'order' => 'ASC',
'meta_key' => 'custom_meta_artist',
'orderby' => 'meta_value',
'posts_per_page' => -1,
);
But I would also like the Albums, 'custom_meta_album', to sort alphabetically if it is the same Artist. Currently if a user enters in 10 albums by the same artist, the post will be alphabetized correctly by the Artist name, but the Albums have no order.
Is there a way to do some sort of second level sorting or primary and secondary sorting in Wordpress? I don't know if it's a IF statement that says "if artists value is equal then also sort albums ascending" or something along those lines. I figure there needs to be some way to tell Wordpress which field it should sort by first and then continue to the second level.
You may try this, hope this will work
// keep this function in your functions.php
function myCustomOrderby($orderby) {
return str_replace('menu_order', 'mt1.meta_value, mt2.meta_value', $orderby);
}
This is your args array
$args=array(
'post_type' => 'albums',
'orderby' => 'title',
'order' => 'ASC',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'custom_meta_artist',
'value' => '',
'compare' => 'LIKE'
),
array(
'key' => 'custom_meta_album',
'value' => '',
'compare' => 'LIKE'
)
)
);
add_filter('posts_orderby','myCustomOrderby'); // Add filter before you call the WP_Query
$albums = new WP_Query($args);
remove_filter('posts_orderby','myCustomOrderby'); // Remove filter after you call the WP_Query
// Start your loop
while ( $albums->have_posts() ) : $albums->the_post();
//...
endwhile;

CakePHP function to convert dotted arrays to multidimensional

In CakePHP, it seems like a lot of functions can take their arguments as nested, multidimensional arrays, or as dotted strings:
$this->MyModel->contain(array(
'Something', 'Something.Else', 'Something.Else.Entirely'
));
$this->MyModel->contain(array(
'Something' => array(
'Else' => 'Entirely'
)
));
Therefore, I figure there must be a function somewhere in the core to switch from dotted to nested associative, but I can't find it for the life of me. Any ideas?
I've actually figured my own way to get this working leveraging the built-in Set functions.
Given:
$input = array (
'Post.id' => 1,
'Post.title' => 'Some post title.',
'Post.Tag.0.id' => 4,
'Post.Tag.0.name' => 'cakephp',
'Post.Tag.1.id' => 7,
'Post.Tag.1.name' => 'mysql',
);
This code will put that into a nested associative array.
$output = array();
foreach ($input as $key => $value) {
$output = Set::insert($output, $key, $value);
}
Here's the docs for Set::insert()
What you're looking for is Set::flatten(). It's not documented in the CakePHP manual, but take a look at the API definition.
It works something like this (the result might not be exact, this is from my head):
$array = array(
'Post' => array(
'id' => 1,
'title' => 'Some post title.',
'Tag' => array(
0 => array(
'id' => 4,
'name' => 'cakephp',
),
1 => array(
'id' => 7,
'name' => 'mysql',
),
),
);
);
$array = Set::flatten($array);
var_dump($array);
Your $array variable will now look like this:
Array (
'Post.id' => 1,
'Post.title' => 'Some post title.',
'Post.Tag.0.id' => 4,
'Post.Tag.0.name' => 'cakephp',
'Post.Tag.1.id' => 7,
'Post.Tag.1.name' => 'mysql',
)
It's just a convention throughout Cake, but each part does its own, customized parsing. If you look at the function ContainableBehavior::containments() in cake/libs/model/behaviors/containable.php, you'll see a lot of preg_matching and explode('.')ing going on. At least in the case of Containable, the verbose array('name' => array(...)) syntax seems to be the canonical syntax, but it can be abbreviated with the dot syntax, which will just be expanded. I'd guess that the expanding itself is just too varied among different parts to be easily summarized in a central function.
That, or they just haven't gotten to it yet. :)
Great question, I was just searching for the same thing. Apparently it's coming in Cake 2.2.
The new Hash class (a new, improved version of the Set class) has an expand() function which does this. You can view the code on Github if you need to use it in the meantime:
https://github.com/cakephp/cakephp/blob/2.2/lib/Cake/Utility/Hash.php
...However the solution nickf posted works great, too. :-)

Resources