I have two models .. One is called Schedule and the other ScheduleContact.
Schedule belongsTo ScheduleContact
From an action belonging to scheduleController, I want to save values coming from a serialized form for the main model as well as the associated model.
In my view I have the following
<?php echo $this->Form->input('Schedule.start_at', array('id' => 'start_at', 'type' => 'hidden')); ?>
<?php echo $this->Form->input('Schedule.finish_at', array('id' => 'finish_at', 'type' => 'hidden')); ?>
<?php echo $this->Form->input('ScheduleContact.0.name', array('id' => 'name','div' => 'inline-input')); ?>
<?php echo $this->Form->input('ScheduleContact.0.surname', array('id' => 'surname','div' => 'inline-input compact')); ?>
etc..
The request data comes in this form (from var_dump($this->request->data)):
array (size=3)
'Schedule' =>
array (size=3)
'start_at' => string '2014-3-25 11:15' (length=15)
'finish_at' => string '2014-03-25 11:30:00' (length=19)
'donation_method_id' => string '1' (length=1)
'ScheduleContact' =>
array (size=1)
0 =>
array (size=6)
'name' => string 'Jane' (length=4)
'surname' => string 'Powell' (length=6)
'address' => string 'Hamilton Hodell, 5th Floor 66-68 Margaret Street' length=39)
'city' => string 'London' (length=6)
'tel_no' => string '+44(0)20-7636 1221' (length=18)
'email' => string 'powell_jane#gmail.com' (length=22)
'log' =>
array (size=3)
'ds' => string 'default' (length=7)
'sql' => string 'SELECT `Schedule`.`id`, `Schedule`.`donation_method_id`, `Schedule`.`schedule_contact_id`, `Schedule`.`start_at`, `Schedule`.`finish_at`, `DonationMethod`.`id`, `DonationMethod`.`donation_method`, `DonationMethod`.`recovery_time`, `DonationMethod`.`duration`, `ScheduleContact`.`id`, `ScheduleContact`.`name`, `ScheduleContact`.`surname`, `ScheduleContact`.`address`, `ScheduleContact`.`city`, `ScheduleContact`.`tel_no`, `ScheduleContact`.`email`, `ScheduleContact`.`donor_id` FROM `blood_services_db`.`schedule'... (length=852)
'hash' => string '5f2b2b3a462f6555cb5290fb49c42df04a7948e0' (length=40)
Finally I am trying to save the data like so :
if($this->Schedule->saveAssociated($this->request->data)){
which is not saving anything to the database, therefore the this if condition is never met.
What could be wrong ? Thanks
Basically the problem was that saveAssociated needs to be applied in the main model. With that in mind, as it was set up above, the main model had a bolongsTo relationship, which means that the current model contains the foreign key., which is also indeed correct. So where is the problem you might ask?
The problem is that saveAsocciated is equivalent to
$user = $this->User->save($this->request->data);
// If the user was saved, Now we add this information to the data
// and save the Profile.
if (!empty($user)) {
// The ID of the newly created user has been set
// as $this->User->id.
$this->request->data['Profile']['user_id'] = $this->User->id;
}
Which means that it attempts to save the main model first. Therefore my setup was incorrect since the main model needed to be ScheduleContact, since the foreign key will be saved inside the Schedule model after data in ScheduleContact id successfully inserted.
There you go... CakePHP is Great once you get past that learning curve.
Your Model-Name is breaking Cake's naming convention. It should be:
ScheduleContact
A few questions to give you a better answer:
Can you add the Model Association Variables ($belongsTo, etc)?
Do you use Containable behaviour?
Related
I want to create new array base on object with structure like this :
object(stdClass)[33]
public 'IKSindividuList' =>
array (size=6)
0 =>
object(stdClass)[27] // <---- i need to get the 27
public 'indikator' => string 'nik' (length=3)
public 'value' => string '123654789' (length=9)
1 =>
object(stdClass)[28]
public 'indikator' => string 'name' (length=4)
public 'value' => string 'afdikage' (length=8)
and the new array that i want to create, more or less should look like this :
array(size=6)
27 => // and put the 27 as index number
array(size=1)
'nik' => '123654789'
28 =>
array(size=1)
'name' => 'afdikage'
I don't have any idea what is that number and how to get it. Can someone help me with this?
If you use XDebug you get this in the brackets, if you don't it will be after the hash like this object(stdClass)#1
This is object identifier, which you should not rely or care in real life. See: http://php.net/manual/en/language.oop5.references.php
You can get the object ID using spl_object_id, but that seems like a bad idea. Consider if the object gets destroyed that ID might get reused and your will not have any real meaning.
You can also take a look at a similar SO question What is # next to object(someClass) in var_dump of an object? I have an inference. Am I right?
I would like to extends/override the APIs of CMS Pages and Blocks to add custom fields (for example, an array of store_ids to allow the creation of a CMS block on different stores with an webapi call, it's my main goal).
I tried many things, but this does not seem clean, standards-compliant. I have the impression of overloading the whole module CMS (data interface, repository interface, model, repository factory, etc..) just for adding new fields in webapi.
I will explain what I have done for now :
1/ I wrote an new data api \BlockInterface who extends the core interface to add my new field (store_id) and declare his getter and setter methods.
namespace Reflet\CmsExtension\Api\Data;
interface BlockInterface extends \Magento\Cms\Api\Data\BlockInterface
{
/**
* New fields
*/
const STORE_ID = 'store_id';
/**
* Get Store Ids
*
* #return array
*/
public function getStoreId();
/**
* Set Store Ids
*
* #param array $storeIds
* #return \Reflet\CmsExtension\Api\Data\BlockInterface
*/
public function setStoreId($storeIds);
}
2/ I implements the Data Interface in the new \Block model object.
3/ With many in the di.xml file, I override the block model type.
4/ I reimplement the api \BlockRepositoryInterface and the webapi.xml file to change the data type used in the repository.
5/ I testing the getById() and the save() methods for the block #1 with simple repository call and webapi.
Here, is my result :
1/ If, I get the block #1 with the repository, the store_id is load in the result object.
array (size=12)
'row_id' => string '1' (length=1)
'block_id' => string '1' (length=1)
'created_in' => string '1' (length=1)
'updated_in' => string '2147483647' (length=10)
'title' => string 'Catalog Events Lister' (length=21)
'identifier' => string 'catalog_events_lister' (length=21)
'content' => string '{{block class="Magento\\CatalogEvent\\Block\\Event\\Lister" name="catalog.event.lister" template="lister.phtml"}}' (length=113)
'creation_time' => string '2017-02-14 14:33:20' (length=19)
'update_time' => string '2017-02-14 14:33:20' (length=19)
'is_active' => string '1' (length=1)
'store_id' =>
array (size=1)
0 => string '0' (length=1)
'stores' =>
array (size=1)
0 => string '0' (length=1)
2/ If, I get the block #1 with the WebAPI, the store_id is also load in the result object.
public 'store_id' =>
array (size=1)
0 => string '0' (length=1)
public 'id' => int 1
public 'identifier' => string 'catalog_events_lister' (length=21)
public 'title' => string 'Catalog Events Lister' (length=21)
public 'content' => string '{{block class="Magento\\CatalogEvent\\Block\\Event\\Lister" name="catalog.event.lister" template="lister.phtml"}}' (length=113)
public 'creation_time' => string '2017-02-14 14:33:20' (length=19)
public 'update_time' => string '2017-02-14 14:33:20' (length=19)
public 'active' => boolean true
3/ If, I save the block #1 with the WebAPI, an error occurs, he load the wrong BlockInterface. I need to reimplement the BlockRepository ? I don't think it's the good and cleaner method (...) ?
public 'message' => string 'Property "StoreId" does not have corresponding setter in class "Magento\Cms\Api\Data\BlockInterface".' (length=101)
public 'trace' => string '#0 /var/www/vhosts/reflet.com/storemanager/vendor/magento/framework/Reflection/NameFinder.php(59): Magento\Framework\Reflection\NameFinder->findAccessorMethodName(Object(Zend\Code\Reflection\ClassReflection), 'StoreId', 'getStoreId', 'isStoreId')
#1 /var/www/vhosts/reflet.com/storemanager/vendor/magento/framework/Webapi/ServiceInputProcessor.php(158): Magento\Framework\Reflection\NameFinder->getGetterMethodName(Object(Zend\Code\Reflection\ClassReflection), 'StoreId')
#2 /var/www/vhosts/reflet.com/storemanag'... (length=2239)
For this example, I use the 'store_id' only, but in the future, it's must be works with all custom fields in Page or Block object.
How do you recommend this modification to be as clean as possible and limit conflicts in the future ? Do you have an example ?
If you want to test, you can find in this archive, my two current Magento modules (Reflet_Api an simple adapter to call REST WebApi and Reflet_CmsExtension to override CMS Blocks) : https://drive.google.com/file/d/0B12trf96j0ALSjhZdmJPTzBPT0U/view
Thank you for your answers.
Best regards.
Jonathan
So here's my issue:
I am fetching data in my database and want to provide them in jSON format.
My controller is the following:
public function testAction()
{
$articles = Article::find();
if (count($articles) > 0) {
$final_array = array();
foreach ($articles as $article) {
$user = Users::find("id = " . $article->getUsersId());
$current = array('id' => $article->getId(),
'name' => $article->getName(),
'replies' => $article->getReplies(),
'date' => $article->getDate(),
'illustration' => $article->getIllustration(),
'content' => $article->getContent(),
'link' => $article->getLink(),
'user_id' => $article->getUsersId(),
'user_name' => $user[0]->getPseudo());
$final_array[] = $current;
}
$result = array('status' => 1,
'message' => 'article have been downloaded',
'response' => $final_array);
} else {
$result = array('status' => 1,
'message' => 'no article in the stack');
}
$this->view->disable();
$this->response->setContentType('application/json', 'UTF-8');
echo json_encode($result);
}
The view displayed provide nothing:
<html>
<head></head>
<body></body>
</html>
The trouble doesn't come from my model or SQL request, because if I var_dump my result instead by changing my controller like this:
[...]
//$this->view->disable();
//$this->response->setContentType('application/json', 'UTF-8');
var_dump($result);
[...]
It provides me the following (length doesn't match all the time because I voluntary changed the content which is not interesting in this case):
array (size=3)
'status' => int 1
'message' => string 'article have been downloaded' (length=28)
'response' =>
array (size=1)
0 =>
array (size=9)
'id' => string '1' (length=1)
'name' => string 'Champion de CAPU' (length=16)
'replies' => string '0' (length=1)
'date' => string '2014-06-10 06:22:35' (length=19)
'illustration' => string 'illustration_link' (length=69)
'content' => string 'content_text' (length=182)
'link' => string 'more_link' (length=50)
'user_id' => string '6' (length=1)
'user_name' => string 'bathiatus' (length=9)
which is what I want to get...
Moreover, I actually did the same in another controller in order to provide all the users (so UserController, jGetAllUsersAction) and it works pretty well (the code is the same except that the table in the database are different).
I finally figured out the issue.
Thank you for the answers, I found that all purposed way to display the view is working (including the one I purposed in my question).
I don't really know which way is the best, but I guess the one in my question is not.
By the way, the issue was that I was trying to inject special characters (such as é, è, à, ë, ...) in my Json object. Indeed, my content is in french.
Json object do not support these kind of characters while printing them with a var_dump presents no issue.
If you want just a json response you can do this in your controller:
return $this->response->setJsonContent($result);
Phalcon disables the view and sets the right content type automatically with that. The json_encode is also done, so just put in your $result.
By default Phalcon needs a view to return the response (in your case the JSON).
Controller code:
$this->response->setContentType('application/json', 'UTF-8');
$this->view->setVar("some_var", $result);
Then you have to create a view corresponing to the name of the controller and the function
and put there:
<?php echo json_encode($some_var); ?>
If you don't want to crate a additional view, please use this link for further reference:
http://docs.phalconphp.com/en/latest/reference/response.html
I'm working on an admin-generator module. I'd like to hide the item-list until the user has used the filters. So I'd like to check, if the filter-form has been sent.
Is there any var I can check for this in the indexSuccess.php Template?
Filters are stored inside the session when the user submit them.
So, in your template, you can access defined filter by calling the session. If you don't have defaults filter, it will return an empty array (might be sfOutputEscaperArrayDecorator if you use output protection).
If you module name is car for example, you can get filters inside your template using:
$filters = $sf_user->getAttribute('car.filters', null, 'admin_module');
And if you use output protection, you can do:
$filters = sfOutputEscaper::unescape($sf_user->getAttribute('car.filters', null, 'admin_module'));
If you do not have filters, you will get something like this with a var_dump (with the first solution):
object(sfOutputEscaperArrayDecorator)[181]
private 'count' => int 0
protected 'value' =>
array
empty
protected 'escapingMethod' => string 'esc_specialchars' (length=16)
And with the second:
array
empty
For example, if you have some filters define, you will get :
array
'model' =>
array
'text' => string 'test' (length=4)
'updated_at' =>
array
'from' => null
'to' => null
'created_at' =>
array
'from' => null
'to' => null
Suppose you have this array with objects:
array
0 =>
object(User\Entity\User)[297]
public 'id' => int 1
private 'first_name' => string 'Peter' (length=5)
private 'last_name' => string 'Johnson' (length=7)
private 'initials' => string 'J.J.' (length=4)
private 'email' => string 'test#gmail.com' (length=21)
1 =>
object(User\Entity\User)[296]
public 'id' => int 2
private 'first_name' => string 'Edith' (length=8)
private 'last_name' => string 'Peters' (length=7)
private 'initials' => string 'R.J.' (length=4)
private 'email' => string 'edit#gmail.com' (length=26)
Now i want to put them in a table. But since i want to make it universal i try to do it on an abstract way.
I have a $aColnames array in the function below in to be able to only show the get the values of the fields i want to see in the table.
This is the method i am trying to build:
private function generateTable()
{
foreach($this->aData as $aData){
$this->sTable.= '<tr>';
foreach($this->aColnames as $sColname){
$this->sTable.= '<td>';
/****What code goes here ****/
$this->sTable.= '</td>';
}
$this->sTable.= '</tr>';
}
}
The question is no how do i get the values from the objects? Do i need to instantiate the objects each time? Can anyone help me out please?
No, you do not need to instantiate the objects again. They are instantiated when you placed them in the array in the first place!
You will however need to either declare these variables public, so that they may be accessed, or have some sort of getter functions.