How to properly recall a function using custom MVC - php

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.

Related

PHP . execute code only once at all ,

I'm new to PHP and just started to learn it. There is this problem that I'm working on it for quite a time now but nothing seems to work.
well, the problem is that I have a piece of code for a web page and I need it to be executed only once. By that I mean the code must be executed when the very first client views the webpage and stop working for the second and other clients who view the page.
I have tried "include" and "required once" but these execute code once per run. I have also tried using session but it this case also the code executes once for each client.
And Also, yes I know I can use a flag and check database to make this work, but I wanna know that PHP has it handled or not
So I'm kinda stuck here.
We know that PHP is the server side language; therefore does it have any feature which executes a code once and stores the results in its global space?
Here is my code, I read data from excel and then I create my array of items.
// foreach row
// I read $col1 ..$col6 from excel for each row
new itemdata($col1,$col2,$col3,$col4,$col5,$col6);
class itemdata
{
public $item;
public $cat;
public $unit;
public $prec;
public $alarmType;
public $order;
static $items=array();
function __construct($item,$cat,$unit,$prec,$alarm,$order)
{
$this->item = $item ;
$this->cat = $cat;
$this->unit = $unit;
$this->prec = $prec ;
$this->alarmType = $alarm;
$this->order = $order;
array_push(self::$items,$this);
}
// And some methods for searching declared array 'items'
I need to execute this code once at all .
I appreciate your help.

Concrete5 MVC parent::save() having trouble finding database insert function, how to save to database

I am editing a concrete5 add-on and am trying to figure out how the program is saving values to the database. The following function is where the database save is happening but I am not sure where the "parent::save()" function is.
protected function SaveRecord() {
$func = 'jso'.'n_encode';
$this->errors = is_array($this->errors) ? $func($this->errors) : $this->errors;
$this->effectiveDate = is_numeric($this->effectiveDate) ? date('Y-m-d', $this->effectiveDate) : $this->effectiveDate;
$this->expirationDate = is_numeric($this->expirationDate) ? date('Y-m-d', $this->expirationDate) : $this->expirationDate;
//var_dump($this); die();
parent::Save();
// a bit hacky, but we are saving the errors as JSON, and we might need to access them later.
$this->errors = (array) json_decode($this->errors);
}
I have followed the class up to its parent and it does not have a save function. I followed the parent up to its parent until I found a save function in the "adodb" class, but die() never happens when put in this function. Please help me figure out how I am supposed to save values in Concrete5 to the database! (More of my code at: https://stackoverflow.com/questions/26940176/concrete5-add-on-extension-save-value-to-database).
#CaitlinHavener Your SaveRecord method should be like this.
public function SaveRecord($data){
$data['my_array'] = serialize($data['my_array']);
parent::save($data);
}
refer this link concrete5 document

Print variable from action zend2 framework

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?

Passing parameters in CodeIgniter

I have been banging my head against this problem for about an hour now. I have looked high and low but nothing is working for me. This should be simple and I am sure it is.
I am trying to pass some parameters in CodeIgniter to a URL and nothing seems to be working. Here is my controller:
class Form_controller extends CI_Controller {
public function change($key = NULL) {
if (is_null($key)) {
redirect("reset");
} else {
echo "Hello world!";
}
}
}
Here is my route:
$route['change/(:any)'] = "form_controller/change/$1";
Every time I visit /index.php/change/hello I get the string "Hello world!" but when I visit /index.php/change I got a 404 not found.
What I am trying to do is pass a parameter to my controller for the purposes of checking the DB for a specific key and then acting upon it. If the key does not exist in the DB then I need to redirect them somewhere else.
Any thoughts on this?
Never mind, I figured it out. I ended up making two different routes to handle them, like so:
$route['change'] = "form_controller/change";
$route['change/(:any)'] = "form_controller/change/$1";
And the function in the controller looks like this now:
public function change($key = NULL) {
if (is_null($key)) {
redirect("reset");
} else if ($this->form_model->checkKey($key)) {
$this->load->view("templates/gateway_header");
$this->load->view("forms/change");
$this->load->view("templates/gateway_footer");
} else {
redirect("reset");
}
}
If anyone has a better solution, I am all ears. This worked for me though.
This might help you out
public function change() {
$key = $this->uri->segment(3);
http://ellislab.com/codeigniter/user-guide/helpers/url_helper.html
This allows you to grab the segment easily using the CI url helper
index.php/change/(3RD Segment) this part will go into that variable $key.
This may not be what you are looking for but it is very useful if you are trying to pass two variables or more because you can just grab the segment from the url and store it into the variable

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