cakephp specify Theme for an Element in Controller - php

In cakephp, how do we specify which theme to use for an Element. I am initializing View object in Controller. I need to pass the element content as ajax response.
Controller :
$view = new View($this);
$view->layout = 'theme2';
$view->theme = 'newNav';
foreach($ctps as $ctpName)
{
$ctp[] = $view->element($ctpName);
}
At first I thought of accessing it as
$ctp[] = $view->element('../Themed/new/Elements/'.$ctpName);
But it obviously does not take care about element's directory. As some of the elements are in app/View/Elements and some are in app/ViewThemed/new/Elements/ directory.
Please suggest.
As per Arilia's suggestion, I am now trying
$this->viewClass = "Theme";
$this->viewPath = 'Elements';
$view = new View($this);
$view->theme = "new";
$view->layout = "theme";
$ctp = $view->element('userprofile');
echo json_encode($ctp);
die;
I am making an ajax call to this code. and it returns
"Element Not Found: Elements/userprofile.ctp"

what I was trying to develop was to render the basic page at first so that it can be cached. and then with the ajax call fetch the parts of UI that are session dependent and then replace the respective elements on browser.
To implement this, I tried fetching cakephp elements in controller, json encoding them and echoing them back. The code above though it worked for a normal dynamic page, it did not work for ajax calls. Cakephp somehow misbehaved here.
Now, as a better alternative, I have moved the code to View itself and I am echoing the json encoded from there. and as expected it is working well. Code is as
app/View/Themed/new/Elements/get_ctps.ctp :
<?php
foreach($ctps as $ctpName)
{
$ctp[] = $view->element($ctpName);
}
echo json_encode($ctp);
die;
?>
Its not a usual case. However, it might be helpful for someone.

Related

Is there a way to execute required php file once per session?

I am new to php and have just written a basic index.php that will display family tree information for an individual based on input id.
The index.php includes a file called "xml-people-list.php" which loads the information from the family tree and creates a sorted list of people.
My problem is that every time you click on a person to display their details, the included php is reloaded which causes the read from file and creation of sorted list to happen again.
Is there a way to only run this code once per session to avoid multiple loads?
I tried to look at session variables but wasn't sure if they would help or how to use them in this case or if there is another way?
Contents of "xml-people-list.php:
<?php require 'xml-load-person.php';
if (file_exists('people.xml'))
{
$people = simplexml_load_file('people.xml');
foreach ($people->person as $person)
{
$person_list[(string)$person['ID']] = strtoupper($person->FamilyName) . ", " . $person->GivenNames;
}
asort($person_list);
}
else
{
exit('Failed to open people.xml.');
}
?>
Thanks for any help!
Yes, you could use session variables. If you wanted to only parse the list once per visitor, and then "cache" the result into a session variable, you could do something like this (for a simple example):
if (!empty($_SESSION['person_list'])) {
// Here we fetch and decode the the ready list from a session variable, if it's defined:
$person_list = json_decode($_SESSION['person_list']);
}
// Otherwise we load it:
else {
require 'xml-load-person.php';
if (file_exists('people.xml'))
{
$people = simplexml_load_file('people.xml');
foreach ($people->person as $person)
{
$person_list[(string)$person['ID']] = strtoupper($person->FamilyName) . ", " . $person->GivenNames;
}
asort($person_list);
// Here we assign the ready list to a session variable (as a JSON string):
$person_list = json_encode($person_list);
$_SESSION['person_list'] = $person_list;
// Here we revert the JSON-encoded (originally SimpleXML) object into a stdClass object.
$person_list = json_decode($person_list);
}
else
{
exit('Failed to open people.xml.');
}
}
You will need to call session_start() in your file (either this one, or any other file including it, but importantly before any output is sent to the browser). Homework: Read up on sessions in PHP.
Update: Since SimpleXML objects can't be serialized, and since adding an object to $_SESSION causes serialization, I've updated the answer to json_encode/decode the object. Yes there's a bit of processing, but that'd be the case with the default serialization as well, and json_en/decode is fairly light-weight. Certainly heaps lighter than parsing XML on each page load!
Be aware that the returned object will be a stdClass object, not a SimpleXML object. I'm assuming it won't be a problem in your use case.
Maybe try require_once() function
1) First of all, try to see if your buttons are anchor tags then be sure that the href attribute is directing to # example: <a href="#">
2) try to use include_once instead of requiring
3) if you tried this and these couple solutions didn't work for you you can send the id of a person using the global $_GET variable
//this should be you URL http://localhost/projectname/index.php?person_id=1
// your href of each person should appoint to their URL
// <a href="index.php?person_id=1">
you can use this $_GET['person_id'] and store it into a variable so it will give you the id of person.

TYPO3: How can i create a custom page type url with typeNum=20 and reference that on the Controller

I created an empty function. And I have a xml file which has information inside. I want to send this file with Postman to this URL and save the information with my function. Anyone any ideas ? Thanks for your help.
Hey there and welcome to StackOverflow.
I used to handle such a function recently and I did it this way:
Create a page type in TypoScript to handle typenum (in your case 20)
Listen to a special POST parameter (which you defined, e.g. data)
Add your code what should happen with the data
Send the information with POST and the XML via Postman to your.typo3.tld/?type=20
Your TypoScript object will be like this
mycustompageType = PAGE
mycustompageType{
typeNum = 1897
config {
#Required configuration
}
10 = USER_INT
10{
vendorName = YourVendorName
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = YourExtensionName
pluginName = YourPluginName
controller = YourController
switchableControllerActions {
YourController {
1 = YourAction
}
}
}
}
You can get extension detail using below code
// get extension information
echo $this->request->getControllerExtensionName()."<br>";
echo $this->request->getPluginName()."<br>";
echo $this->request->getControllerName()."<br>";
Finally, you have to run this URL "yourdomain.com/?type=1897"
Enjoy!!

Clean URLS in MVC structure using PHP

I am creating a website using the MVC structure. Below is a code I have used to use clean URLS and load the appropriate files. However it only works for the first level.
Say I wanted to visit mywebsite.com/admin it would work, however mywebsite.com/admin/dashboard would not. The problem is in the arrays, how could I get the array to load content after the 2nd level along with the second level.
Would it be best to create an array like this?
Array
- controller
- view
- dashboard
Any help here would be great. Also as a side question. What would be the best way to set up "custom" urls. So if I were to put in mywebsite.com/announcement it would check to see if its got controllers, failing that, check to see if it's got custom content (maybe a file of the same name in "customs" folder, and then if there's nothing execute the 404 page not found stuff) This isn't a priority question though, but loosely associated in how the code works so I thought it best to add.
function hook() {
$params = parse_params();
$url = $_SERVER['REQUEST_URI'];
$url = str_replace('?'.$_SERVER['QUERY_STRING'], '', $url);
$urlArray = array();
$urlArray = explode("/",$url);
var_dump($urlArray);
if (isset($urlArray[2]) & !empty($urlArray[2])) {
$route['controller'] = $urlArray[2];
} else {
$route['controller'] = 'front'; // Default Action
}
if (isset($urlArray[3]) & !empty($urlArray[3])) {
$route['view'] = $urlArray[3];
} else {
$route['view'] = 'index'; // Default Action
}
include(CONTROLLER_PATH.$route['controller'].'.php');
include(VIEW_PATH.$route['controller'].DS.$route['view'].'.php');
var_dump($route['controller']);
var_dump($route['view']);
var_dump($urlArray);
var_dump($params);
// reseting messages
$_SESSION['flash']['notice'] = '';
$_SESSION['flash']['warning'] = '';
}
// Return form array
function parse_params() {
$params = array();
if(!empty($_POST)) {
$params = array_merge($params, $_POST);
}
if(!empty($_GET)) {
$params = array_merge($params, $_GET);
}
return $params;
}
Can you clarify this: "The problem is in the arrays, how could I get the array to load content after the 2nd level along with the second level."
I don't understand how you want this thing to work. I checked your code and it works. Maybe you just need to put $urlArray[1] instead of $urlArray[2] and 2 instead of 3? First element in the array is at index 0.
Usually it's done like this:
Url format:
/controller/action/param1/param2/...
-controller- should be a class. That class has a method/function called -action-.
ex. /shoes/show/121/ --> this will load controller shoes
and execute the method/function show(121)
that will show the shoes that have the id 121 in the
database.
ex. /shoes/list/sport --> this will load controller shoes
and execute function list('sport') that will list all
shoes in the sport category.
As you can see, you only load one controller and from that controller you run only one function and that function will get the rest of the path and use it as parameters.
If you want to have multiple controllers for one URL, then the rest of the controllers will have to be loaded from the main controller. Most MVCs (like CodeIgniter) load only one controller per URL.
Second question:
Best way for pretty urls would be to save them in the db. This means you can have URLs like this:
/I-can-write-anything-here-No-need-to-add-ids-or-controller-names
Then you take this URL and search it in db and get the -controller- and -action- that you need for this URL.
But I have yet to see a popular MVC framework do this. I guess the reason is that the db will get a lot of queries for text matches and that will slow things down.
Popular MVC frameworks use:
/controller/action/param1/param2
This has the benefit that you can directly find the controller/action from the url.
The downside is that you will get urls like:
/shoes/list/sport
//when what you really want is
/shoes/sport
//or just
/sport //if the website only sells shoes
This can be fixed by redirecting /shoes/sport to /shoes/list/sport
If you make your own MVC then you should use OOP because if not, thing will get ugly quick: all actions/functions are in the same namespace.
Personally I would recommend that you use one of the many PHP frameworks that exist as that will take care of the routing for you and let you concentrate on writing your application. CakePHP is one that I've used for a while and it makes my life so much easier.
What I do:
I create a .htaccess file that redirects an url like www.example.com/url/path/or/something to www.example.com/index.php?url=url/path/or/something, so it will be pretty easy to do an explode on your $_GET['url']
Second, it's better because everything a user input, will be redirected to your index.php, so you have FULL control over EVERYTHING.
If you want I can PM you the url to my mvc (bitbucket) so you can have a look on how I do this ;)
(Sorry for the others, but I don't like to put url's to my site in public)
edit:
To be more precise to your particular question; It will solve your problem, because everything goes to index.php and you have full control over the requested url.

PHP Zend_Paginator on mySql query using GET

I am trying to call pages using Zend_Paginate() on a query that loads based on a GET search string the query essentially does the following:
SELECT * FROM table WHERE column LIKE '%searchstring%' OR alt_column LIKE '%searchstring%';
The query works fine when called via search/submit text form and the URL returns something similar to
URLINK.php?search=searchstring
However when trying to move onto the next page the program dumps me back to the paginate alternate URL (used for errors or no page display)-- hope this last line makes sense it is late and am doing my best to type this up with transparency.
What is the best method when using paginate against URL.php?search=searchstring"?
A bit more on the call to the url
//search query
$search = searchQuery('search', 'list_sql_rows.php');
$results - searchTable($dbRead, $search);
search method using the variables above in the order below
if(isset($_POST['submit_search'])) { $searchstring = $_POST['searchstring'];
if($searchstring) { header('Location: results.php?search=' . $searchstring); } }
This bit works well, but when I try to call the results.php?page=2 with paginator the system reverts me to the fall back URL list_sql_rows.php as mentioned above. Any thoughts/comments are appreciated.
Just to clarify a search field/form from the search.php page sends the $searchstring to the results.php page via $_POST && $_GET as fail safe. The get method sends the $searchstring in the URL header so the results of the search DO work on the first page results.php?search=$searchstring. This works just fine. The pagination seems to lose the $searchstring, and I wonder if this is due to a loss of the $_POST/$_GET when paginator begins to 'paginate' it returns URL results.php?page=2 so it seems $_GET may not be the method of choice?
UPDATE
On the write track now paginate works it is my link structure that is broken.
_results_samples.php?search=robert&page=4_ will in fact return page 4 of the paginated results using the word ROBERT
SOLUTION FOUND VIA variant suggestion by ROCKYFORD
variant of recommended method by first persisting $searchstring
change to paginate links as shown below
<a href='" . $_SERVER['PHP_SELF'] . "?search=" . $searchstring . "&page={$page}'>$page</a>
Here is the example of correct using of pagination:
in action-method:
$select = $clients->getAll();
$paginator = new Zend_Paginator(new Zend_Paginator_Adapter_DbSelect($select));
$paginator->setCurrentPageNumber($this->_getParam('page'));
$paginator->setItemCountPerPage(20);
$this->view->clients = $paginator;
in a view script:
<?php if (count($this->clients) > 0): ?>
...
<?php echo $this->paginationControl($this->clients, 'Sliding', 'partials/paginator.phtml'); ?>
<?php else: ?>
<h3 class="notice">No registered clients found!</h3>
<?php endif; ?>
But even if you will fail with this variant, you can always try to compose your own component, Zend only aids us in solving some tasks.
you need to make sure you preserve the query strings between requests, use Zend_Session_Namespace or Zend_registry.
Everytime Zend_Paginator loads a page when using the DbTableSelect or DbSelect adapters it has to hit the db with the query, it just changes the limit option.
Or you could just dump the whole query result into a Zend_Paginator_Adapter_Array and it will page through the array.
[edit]
you are going to have to persist the query string between requests someway so you can put it back in the url string, I usually use Zend_Registry, but then I use the whole MVC stack. You don't seem to be using the whole stack so you'll need another method, probably $_SESSION would work. I'm sure there are many other ways to persist this data.
P.S. you didn't mention which adapter you are using so I'm making some assumptions.
[edit]
Personally I always use $_post for this when possible to avoid all this, only seem to have this problem with $_get.

How do I make a script to grab certain piece of data from a JSON API?

I'm trying to build a little script that would let me do this:
http://example.com/appicons.php?id=284417350
and then display this in plain text
http://a3.mzstatic.com/us/r1000/005/Purple/2c/a0/b7/mzl.msucaqmg.png
This is the API query to get that information (artworkUrl512):
http://ax.itunes.apple.com/WebObjects/MZStoreServices.woa/wa/wsLookup?id=284417350
Any help and example code would be much appreciated!
I am not sure why you have jQuery in your tags, unless you want to make the request dynamically without a page refresh. However you can do this simply in PHP using the following example:
$request = array (
"app_id" => #$_GET["id"]
);
// parse the requests.
if (empty($request["app_id"])) {
// redirects back / displays error
}
else {
$app_uri = "http://ax.itunes.apple.com/WebObjects/MZStoreServices.woa/wa/wsLookup?id=" . $request["app_id"];
$data = file_get_contents ($app_uri);
$json = json_decode (trim($data));
print($json->results[0]->artworkUrl100);
}
$request = file_get_contents($itms_url);
$json = json_decode(trim($request));
echo $json[0]->artworkUrl512;
should work in PHP. Unless of course there is more than one hit to the search. A solution using jQuery is probably not very much more difficult.

Categories