Print variable from action zend2 framework - php

I am trying to print a variable fromm saveAction so i can see what is the value of that variable. I am learning Zend2 and i have continued where other developer stoped so i am trying to understand it better...This application is also using Doctrin.
I have this action which will save some data to database.
public function saveAction() {
$view = new ViewModel();
$logedUser = $this->getLogedUser();
print_r($_POST);
$shopId = (int) $this->params()->fromPost('shop_id', null);
print_r($shopId);
$shop = $this->getServiceLocator()
->get('Catalog\Model\Shop')
->getRepository()
->findOneBy(array('id' => $shopId, 'user' => $logedUser->getId()));
print_r($shop);
return $logedUser;
return $shop;
return $view;
}
I can print values from post, and variable shopId, but print_r($shop); doesn't show anything. How can i see the value of shop variable?

Try this
echo $shop->__toString();

Hi there you might want to try this one:
print_r($this->getAllParams());
instead of using $_POST

$shop = $this->getServiceLocator()
->get('Catalog\Model\Shop')
->findOneBy(array('id' => $shopId, 'user' => $logedUser->getId()));
please remove ->getRepository() from your code, then you will get your result.

At this point we dont know what the Service/Factory 'Catalog\Model\Shop' does. I assume it get's the Entity manager. The query looks ok to me 2. But having 3 return's is just wrong!
Your view will never have the $shop; nor the $view; variable in your .phtml view File. In ZF2 you can just return a Array to your view like so:
return array('shop' => $shop, 'logedUser' => $logedUser);
This will save those variables within your save.phtml
in /yourmodule/view/yourcontroller/save.phtml
If you want to set the .phtml matching yourself you indeed could use the view model like you tried in your code the procedure is a litle diffrent then. It could look like this:
$viewModel = new ViewModel(array(
'logedUser' => $logedUser,
'shop' => $shop,
));
$viewModel->setTemplate('yourmodul/yourcontroller/save');
return $this->getContainerViewModel($viewModel);
Once you have that you can just access your variables in the save.phtml template file like so:
<?php echo $shop->getSomething(); ?>
You did not show us the Shop entity but I assume it has methods like getName(), __toString() etc. You can just call these Object methods within your view.
If you still have trouble understanding the mvc concept of zf2 you might want to re-read the zf2 documentation.

You have to show us what Catalog\Model\Shop and what query are you using for getting your data. Is there possibility that your query just getting null because it fails to get anything from database ? Do you have any kind of checks in your model to find out is your result from query good?

Related

Laravel 8 override relationship value after get the result

My controller looks like this:
public function show($id)
{
$model = MyModel::with([
'model2.model3.model4:id,value',
...
]);
if (myCondition) {
unset($model->model2->model3->model4);
$model->model2->model3->model4 = Model4::where('value', 'Some Value')->first();
}
return $audit;
}
In certain condition I'd like to override the result from the query with another value from the Model4 to return the good data to the client.
But I want to know if there is another way with laravel to do that. Actually I have to use unset and then push the new content if I want to change the value of the model4 property. If I don't use unset the object isn't changed, the value new value assigned to model4 is ignored I don't know why I can't just write this line
$model->model2->model3->model4 = Model4::where('value', 'Some Value')->first();
So I want to know why I can't see changes in my json object when I don't use unset and I want to know if there is anotehr way to deal with laravel for my situation ?
You can simply use setRelation method.
if ($myCondition) {
$model->model2->model3->setRelation('model4', Model4::where(...)->first());
}

How to properly recall a function using custom MVC

Hi and good day to you all..
I'm new to MVC's/model-view-controller frameworks. I've made my own by reverse-engineering a custom MVC framework I've got from a friend of mine, so far it's all going good and smooth until I got to this part where I need to recall a function inside the function it self.. I'm currently creating a binary tree website and need to output values inside the table, what I'm trying to do is call a function and fetch all values and put them inside an array for later referencing.
This is my code in the model folder.
public function getGenealogy($parent) {
$this->db->sql('SELECT * FROM accounts WHERE sponsorUpline = ?');
$this->db->bindValue(1, $parent);
$this->db->execute();
while($row = $this->db->fetch()) {
echo $row['serialNumber'];
$this->getGenealogy($row['serialNumber']);
}
}
And this is my code in the controller folder
public function index() {
$memberAccounts = $this->db->getMemberAccounts();
$getDirectReferal = $this->ddrs->getDirectReferal();
$genealogy = $this->bg->getGenealogy($_SESSION['activationCode']);
$data = [
'memberAccounts' => $memberAccounts,
'getDirectReferal' => $getDirectReferal,
'genealogy' => $genealogy
];
$this->view('dashboards/dashboard', $data);
}
As you can see, I'm trying to call the function inside of the function but what happens is that it doesn't call it self, I tried doing the same method but not with MVC and it works fine.
So my conclusion is there's something wrong about my code that I can't seem to grasp.
Also it outputs the children twice but with same values.
This is my database.
This is the output.
.
Any ideas or help would be appreciated.

Copy one row from one table to another

I need a little help and I can’t find an answer. I would like to replicate a row from one data table to another. My code is:
public function getClone($id) {
$item = Post::find($id);
$clone = $item->replicate();
unset($clone['name'],$clone['price']);
$data = json_decode($clone, true);
Order::create($data);
$orders = Order::orderBy('price', 'asc')->paginate(5);
return redirect ('/orders')->with('success', 'Success');
}
and i got an error :
"Missing argument 1 for
App\Http\Controllers\OrdersController::getClone()"
.
I have two models: Post and Order. After trying to walk around and write something like this:
public function getClone(Post $id) {
...
}
I got another error
Method replicate does not exist.
Where‘s my mistake? What wrong have i done? Maybe i should use another function? Do i need any additional file or code snippet used for json_decode ?
First of all, make sure your controller gets the $id parameter - you can read more about how routing works in Laravel here: https://laravel.com/docs/5.4/routing
Route::get('getClone/{id}','YourController#getClone');
Then, call the URL that contains the ID, e.g.:
localhost:8000/getClone/5
If you want to create an Order object based on a Post object, the following code will do the trick:
public function getClone($id) {
// find post with given ID
$post = Post::findOrFail($id);
// get all Post attributes
$data = $post->attributesToArray();
// remove name and price attributes
$data = array_except($data, ['name', 'price']);
// create new Order based on Post's data
$order = Order::create($data);
return redirect ('/orders')->with('success', 'Success');
}
By writing
public function getClone(Post $id)
you are telling the script that this function needs a variable $id from class Post, so you can rewrite this code like this :
public function getClone(){
$id = new Post;
}
However, in your case this does not make any sence, because you need and integer, from which you can find the required model.
To make things correct, you should look at your routes, because the url that executes this function is not correct, for example, if you have defined a route like this :
Route::get('getClone/{id}','YourController#getClone');
then the Url you are looking for is something like this :
localhost:8000/getClone/5
So that "5" is the actual ID of the post, and if its correct, then Post::find($id) will return the post and you will be able to replicate it, if not, it will return null and you will not be able to do so.
$item = Post::find($id);
if(!$item){
abort(404)
}
Using this will make a 404 page not found error, meaning that the ID is incorrect.

Returning object in a function Laravel 4

I am trying to access a functions variable from another function in the same class. i am fairly new to the concept and I can get it to work in another function but when I try to create it's own function I get an Trying to get property of non-object I know what that means but it's confusing as to what needs to be returned in my function since it does work in my other function.
Function getting the error
public function getEditTotal($id) {
$techs = $this->technician();
$tech = $techs->tech;
var_dump($tech); die;
return View::make('report.edit', array('pageTitle' => 'Edit Report Total', 'id' => $id, 'tech' => $tech));
}`
The function I am trying to call
public function technician() {
$tech = DB::table('technician')
->get();
return $tech;
}
I had that same $tech variable in this function and it worked perfectly fine if I called $this->setComplete($id) instead.
Returned statement in the setComplete($id) function
return View::make('report.total', array('pageTitle' => 'Reporting', 'id' => $id, 'tech' => $tech, 'status' => $status));
I am sure it's just the way it's being returned since that variable is being returned in setComplete($id) in the array. I just don't know how to strictly call it in the technician() function.
When you call $techs = $this->technician(); you are setting the $techs to be whatever the value of the $tech variable in the technician function. That is going to be the result of DB::table('technician')
->get();
Theoretically this should be an array of objects where each object represents one row in the technician table.
If you want to know what's going on, add a var_dump($tech) inside the your technician() function, just prior to the return $tech statement.
Since you indicate it is working as expected, you're getting an array of objects. I'm not sure what you want to do with those, but inside the controller:
foreach ($techs as $tech) {
echo $tech->somefieldInTech;
}
or perhaps
echo $techs[0]->somefieldInTech;
So to be clear, in your laravel template, you might want to pass the entire $techs and foreach through it in the template, although from your code it's not clear what you need to do with the data.

How to convert an existing PHP library file so it can be used in a CakePHP framework?

I have this library in PHP non-Cake format, the usual PHP scripting which currently works like a charm. I need to use this in a Cake framework. The library file is as follow: (example extracted)
<?php
// REST API functions
function sendAction($itemurl, $itemimageurl, $sessionid, $userid, $rating=""){
global $someapiwebsiteURL, $apiKey, $tenantId;
$somewebsiteAPI = $someapiwebsiteURL.$action."?apikey=".$apiKey.
.....
................
}
//Codes extract
?>
I've come across a few ways of doing it. Currently confused, how am I going to place this library file into my Cake framework?
App::import()
Datasource
The functions in the library file above (I supposed it'd be used in one of my Controllers to render the data outputting through the view).
Currently working in a non-Cake framework structure, the view page is such as: (example extracted)
<?php
// my view page
$viewResponse = sendAction($itemdescription ,$itemurl , $itemimageurl,$sessionid,$userid);
//sample code only
?>
Both the files are working fine. The logic of putting it in a CakePHP framework is the problem here. Anyone may suggest "the" way of doing this without over-strenuously working on a data source? If we have to use a data source in App/models/datasources/, how exactly is the structure of it? Like, e.g., in datasource file, do we include the library functions? or is it some generic ReST datasource file which can be found here: CakePHP ReST datasource . I've gone through the cookbook chapter on datasource and understand we have to define the datasource in our database.php, but if someone is certain about their way of accomplishing it either using datasource or app::import() method, please share with more details?
UPDATE:
Hi Lionel!, thanks for filling up. Well, actually users will click on view action: function view (){} in my foods_controller. I'm appending some scripts here to include my view function in my foods_controller so maybe it may help you to help out easier. Thanks..
function view($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid food', true));
$this->redirect(array('action' => 'index'));
}
$this->set('food', $this->Food->read(null, $id));
}
The view action triggers the send_action function, (each time a user clicks on view page on foods controller). So each time, a user clicks on view action, his (dynamic variables): userid, sessionid, that page's itemid, url, itemdescription; (timerange value is a static string value "ALL"), and if any (etc.), so far only these values are available: Will be used as the "parameters" in the Send Action function. What you wrote is close to what the codes can do. You're right. Except we should include the Send Action function inside the view() in foods controller?
If we look at dynamically filling in the variables mentioned in the point above, could you modify your second code (the code from your product_controller, e.g.) so it also works to receive the variables dynamically? (as you asked in the last update: how to get the parameters..)
Just to make it clear.
A user views the page. The send action collects data and send to the API. (as we've already done by calling the function in the library the (ACME.php). *just waiting for your update if possible, thanks.
In the function view() of the foods controller: there's also an additional calling. The (2)second calling which is this:
$recommendResponse = getRecommendations("otherusersviewed", $itemId, $userId);
The second calling calls the ACME.php library file in which there consists the (2)second function that retrieves data, here it is: (it's in working order, but just needs to be changed into a public static function like you did for the (1)first function. Could you help to modify this code too, please?:
function getRecommendations($recommendationType, $itemId, $userId){
// sample code similar to the first one.
}
That's all to it. It seems quite simple in the normal PHP format, and it works easily, but getting it on an MVC framweork is a bit challenging for some, a lot for me. Thanks for helping out, Lionel. :-)
P.S. Hi Lionel, I notice something missing in the library after changes? Look originally we have this:
$somewebsiteAPI = $someapiwebsiteURL.$action."?apikey=".$apiKey.
Look, the variables for $SomeWebsiteAPI and $SomeApiWebsiteURL are different. Did I miss out something? or you have modified so it is more efficient ? I see that the variable named $SomeWebsiteAPI is modified to become variable called $link ? and variable $SomeApiWebsiteURL is changed to the named variable, $url, am I right ? .. thanks.
Thanks, best regards. John Maxim
To me, if I have this piece of code, I would first wrap it into a static (or normal) class, and named it ACME, then I will move the acme.php into /apps/libs/acme.php. Then in the controller, I will use App::import('Lib', 'acme'). This action do nothing but just requiring the file, so you can just use it instantly by calling ACME::sendAction(...).
And regarding the global thing, you might just need to declare a static (or normal) class, then define the shared variables as part of the class properties, so you can share them among all the functions in the class.
For example, this is the /app/libs/acme.php
class ACME {
private static $someapiwebsiteURL = "http://thewebsite/api/1.0/";
private static $apiKey = "0010KIUMLA0PLQA665JJ";
private static $tenantId = "THE_TENANT_NAME";
/**
* Simple builder to build links from array of $params
*
* #param string $url The api url
* #param array $params The given parameters
* #return string built url
*/
private static function BuildLink($url="", $params=array()) {
$link = $url;
foreach($params as $k=>$v) {
$link .= "&$k=$v";
}
//Replace the first & to ?
$link = preg_replace("/&/", "?", $link, 1);
//Not sure if we need URL encode here, please uncomment this
//if the API could not work.
//$link = urlencode($link);
return $link;
}
public static function SendAction($action, $itemId, $itemdescription, $itemurl, $itemimageurl, $sessionid, $userid, $rating="") {
$somewebsiteAPI = self::BuildLink(self::$someapiwebsiteURL.$action, array(
"apikey"=>self::$apiKey,
"sessionid"=>$sessionid,
"userid"=>$userid,
"tenantid"=>self::$tenantId,
"itemid"=>$itemId,
"itemdescription"=>$itemdescription,
"itemurl"=>$itemurl,
"itemimageurl"=>$itemimageurl,
/**
* Assuming your API smart enough to only use this value when
* the action is "rate"
*/
"ratingvalue"=>$rating
));
$xml = simplexml_load_file($somewebsiteAPI);
return $xml;
}
public static function GetRecommendations($recommendationType, $itemId, $userId) {
$somewebsiteAPI = self::BuildLink(self::$someapiwebsiteURL.$recommendationType, array(
'apikey'=>self::$apiKey,
'tenantid'=>self::$tenantId,
'itemid'=>$itemId,
'userid'=>$userId
));
$xml = simplexml_load_file($somewebsiteAPI);
return $xml;
}
}
And in your controller
App::import('Lib', 'acme');
class FoodController extends AppController {
//Food is plural already I assume? You can just use
//food, should be ok I think, else it will be weird
//to use /foods/view/?
var $name = "Food";
var $uses = array("Item", "Food");
function view($id="") {
//We accepts only valid $id and $id > 0.
//Take notes that this $id will be a string, not int.
if (ctype_digit($id) && $id > 0) {
//I don't know how you would gather the information, but I assume you
//have a database with the information ready.
//I assumed you have an `items` table
$item = $this->Item->findById($id);
$sessionid = "00988PPLO899223NHQQFA069F5434DB7EC2E34"; //$this->Session->...?
$timeRange = "ALL";
$userid = "24EH1725550099LLAOP3"; //$this->Auth->user('id')?
if (!empty($item)) {
$desc = $item['Item']['description'];
$url = "/foods/view/".$id;
$img = $item['Item']['img'];
$viewResponse = ACME::SendAction("view", $id, $desc ,$url, $img, $sessionid, $userid);
$this->set('food', $this->Food->read(null, $id));
}else{
$this->Session->setFlash(__('Invalid food', true));
$this->redirect(array('action' => 'index'));
}
}else{
$this->Session->setFlash(__('Invalid food', true));
$this->redirect(array('action' => 'index'));
}
}
}
Edit
The code has been filled up, and of course, without any warranty :). I personally don't really like to have long arguments in a function (like SendAction, error prune), rather use shorter one like the $params in ACME::BuildLink. But just to respect your code, I didn't modify much on the SendAction method.
Then I'm not too sure how you would make use of this code, so I assumed you have a ProductsController, and somehow the user trigger url like /products/send_action/. If you can provide more information, then we would be able to help out.
Edit Again
I have modified the ACME class, as well as the controller. Yea I do miss out some variables, but I had added them back to the updated code.
Not too sure if it would work (perhaps typo), you can just modify the code if it doesn't work for you.
And for personal conventions, I usually capitalize methods which are static, like ACME:GetRecommendations or ACME::SendAction.
Oh yea, I better stick back to the variables you used. Sorry for modifying them, just I don't like long names :)
And btw, the RoadRunner's ACME Corporation? Lol!
Cheers
Lionel

Categories