my url is http://localhost/myAppliation/....
I want to get the "myApplication". Which is the key word to get the value?
I think you want:
$this->webroot
or
$this->base
or
$this->here
in your controller. See http://api.cakephp.org/class/controller for definition of this variables.
Edit: Didn't see that you were using CakePHP. If you weren't using any frameworks, you would get the path via this:
First you need to reconstruct the URL.
$pageURL = (#$_SERVER["HTTPS"] == "on") ? "https://" : "http://";
if ($_SERVER["SERVER_PORT"] != "80")
{
$pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
}
else
{
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}
Then parse it for the path.
$parts = parse_url($pageURL);
$path = $parts['path'];
After that if you want to only get the first path, explode it on '/', strip out the null values, and then the first one will be the first path, and so on.
$paths = explode('/', $path);
foreach($paths as $key => $value)
{
if(!empty($value))
{
$new_paths[] = $value;
}
}
$first_path = $new_paths[0];
There is something called the $Name attribute, but I'm not sure if that gives you the application name. The CakePHP manual says:
PHP4 users should start out their
controller definitions using the $name
attribute. The $name attribute should
be set to the name of the controller.
Usually this is just the plural form
of the primary model the controller
uses. This takes care of some PHP4
classname oddities and helps CakePHP
resolve naming.
http://book.cakephp.org/view/52/name
http://book.cakephp.org/view/317/Cake-s-Global-Constants-And-Functions
I think you want to use the WEBROOT_DIR constant.
Related
In CakePHP 4.x I'm having some trouble with the mailer() function, specifically passing variables from my controller to a template.
I need a user to be able to receive an email with a list of items. I'm able to use ajax to send an array to my controller, but I can't get the controller to pass the variables to the email template. I'm getting the email but not the dynamic content and I just can't get it to work via setViewVars.
My controller function:
public function bar(): void
{
if( $this->request->is('ajax') ) {
$this->request->allowMethod('ajax');
$foo = $this->request->getQuery('data');
// data is a stringified array
$mailer = new Mailer("default");
$mailer->viewBuilder()->setTemplate('default','default');
$mailer
->setEmailFormat('html')
->setFrom(['email#email.com' => 'Comparaciones'])
->setTo('email#email.com')
->setSubject('About')
>setViewVars($foo)
->send();
// ->deliver() doesn't work either
}
}
My template:
// standard cakephp default template
$content = explode("\n", $content);
foreach ($content as $line) :
echo '<p> ' . $line . "</p>\n";
endforeach;
I'm probably tripping up with something simple, I just can't get the array into the template. Any help much appreciated!!!
I've developed a CakePHP plugin that allows the site administrator to define custom reports as a list of SQL queries that are executed and the results displayed by a .ctp template.
Now I need to allow the administrator to edit the template, stored in the DB together with the report.
Therefore I need to render a template that is inside a string and not in a .ctp file and I could not find anything in the core that helps.
I considered initially the approach to write the templates in .ctp files and load them from there, but I suspect this solution is rigged with flaws re: the location of the files and related permissions.
A better solution seems to override the View class and add a method to do this.
Can anyone suggest a better approach ?
P.S. Security is not a concern here, since the administrator is basically a developer without access to the code.
In CakePHP 2.0:
The View::render() method imports the template file using
include
The include statement includes and evaluates the specified file.
The evaluated template is immediately executed in whatever scope it was included. To duplicate this functionality, you would need to use
eval()
Caution: The eval() language construct is very dangerous because it
allows execution of arbitrary PHP code. Its use thus is discouraged.
If you have carefully verified that there is no other option than to
use this construct, pay special attention not to pass any user
provided data into it without properly validating it beforehand.
(This warning is speaking to you, specifically)
...if you wish to continue... Here is a basic example of how you might achieve this:
$name = 'world';
$template = 'Hello <?php echo $name ?>... <br />';
echo $template;
// Output: Hello ...
eval(' ?>' . $template . '<?php ');
// Output: Hello world...
Which is (almost) exactly the same as:
$name = 'world';
$template = 'Hello <?php echo $name ?>... <br />';
file_put_contents('path/to/template.php', $template);
include 'path/to/template.php';
Except people won't yell at you for using eval()
In your CakePHP application:
app/View/EvaluatorView.php
class EvaluatorView extends View
{
public function renderRaw($template, $data = [])
{
if (empty($data)) {
$data = $this->viewVars;
}
extract($data, EXTR_SKIP);
ob_start();
eval(' ?>' . $template . '<?php ');
$output = ob_get_clean();
return $output;
}
}
app/Controller/ReportsController.php
class ReportsController extends AppController
{
public function report()
{
$this->set('name', 'John Galt');
$this->set('template', 'Who is <?php echo $name; ?>?');
$this->viewClass = 'Evaluator';
}
}
app/View/Reports/report.ctp
// Content ...
$this->renderRaw($template);
Alternatively, you may want to check out existing templating engines like: Mustache, Twig, and Smarty.
Hmmm.. Maybe create a variable that will store the generated code and just 'echo' this variable in ctp file.
I had similar problem (cakephp 3)
Controller method:
public function preview($id = null) {
$this->loadModel('Templates');
$tempate = $this
->Templates
->findById($id)
->first();
if(is_null($template)) {
$this->Flash->error(__('Template not found'));
return $this->redirect($this->referer());
}
$html = $template->html_content;
$this->set(compact('html'));
}
And preview.ctp is just:
<?= $html
I'm fairly new to certain programming techniques. Very new to OOP and MVC in general. And I'm pretty sure this is my first StackOverflow question!
I've just downloaded CodeIgniter and have a little project for myself.
I have a list of files and folders on the server and would like to use opendir, readdir and closedir etc to list out them out on a web page in ul's and li's - I've done this in procedural before in a function but have no idea where to even begin with CodeIgniter.
Is there a Helper or Library that already does this? If not, what is the best method? Should I put my code in the model folder?
So confused!
I hope you have learned about MVC architecture already in past year :)
Now about your question. This helper or library you have asked for really exists. For the very same "problem" I have used directory helper and its function directory_map('relative/path/to/your/directory'). This function gets recursively content from your directory and sorts it into array like this
Array
(
[banner] => Array
(
[0] => banner1.jpg
[1] => banner2.jpg
[2] => banner3.jpg
[3] => banner4.jpg
)
[galerie] => Array
(
[0] => 0-PB083393.JPG
[1] => DSCN2897.JPG
[2] => DSCN2908.JPG
[3] => DSCN2917.JPG
[thumb] => Array
(
[0] => 0-PB083393_thumb.JPG
[1] => DSCN2897_thumb.JPG
[2] => DSCN2908_thumb.JPG
)
)
[0] => mapa.jpg
)
which is quite neat and you can use it in - for example - foreach cycle and add ul/li tags.
Probably this question is not relevant after one year, but I hope it could help others.
Ha. This is funny. I was looking for something else and stumbled on to my first ever CI question without realising it was me :D
I've come so far with CI in just less than a month.
I found Directory Helper - directory_map that basically puts your folder structure in to an array of arrays.
I them created a recursive function in the model that turns it in to a proper drop down menu... And when it's a file, it adds in an a href link to that file.
http://ellislab.com/codeigniter/user-guide/helpers/directory_helper.html
If I were doing this, I would:
(1) Create a Library class with a method that takes a directory name and returns an
array of files.
(2) In my controller, I would then load the library and use it to get the list of files for the folder of interest.
(3) I would then load a view while passing the array of file names to the view where
I would assemble the list.
Start by learning how to use the controller to load a view with data (start with a static array). Then learn how to create the library and integrate with your controller.
You might also read up about CodeIgniter's File Helper library unless you want to use the native PHP functions.
Also, learn about PHP unit testing.
I tend to use models for dealing with data from MySQL databases. In your case, you are dealing with information about your file system.
Good luck, CI is a good choice for a PHP/MySQL framework!
First, welcome to CodeIgniter. It rules. Now...
You need a controller function to actually process the directory, similar to this:
public function dir_to_array($dir, $separator = DIRECTORY_SEPARATOR, $paths = 'relative')
{
$result = array();
$cdir = scandir($dir);
foreach ($cdir as $key => $value)
{
if (!in_array($value, array(".", "..")))
{
if (is_dir($dir . $separator . $value))
{
$result[$value] = $this->dir_to_array($dir . $separator . $value, $separator, $paths);
}
else
{
if ($paths == 'relative')
{
$result[] = $dir . '/' . $value;
}
elseif ($paths == 'absolute')
{
$result[] = base_url() . $dir . '/' . $value;
}
}
}
}
return $result;
}
Now you need to call that function to return the results, similar to:
$modules['module_files'] = $this->dir_to_array(APPPATH . 'modules');
This will put the results in a variable called $modules, which you can use in whichever way you want, typically put it in a view like this:
$this->load->view('folder/file', $modules);
If you provide an optional third parameter of TRUE to the load->view function, the result of that view will again be returned for you to use anywhere you like, otherwise it will be echoed out where you call it. The view may look something like this:
<?php
if (isset($module_files) && !empty($module_files))
{
$out = '<ul>';
foreach ($module_files as $module_file)
{
if (!is_array($module_file))
{
// the item is not an array, so add it to the list.
$out .= '<li>' . $module_file . '</li>';
}
else
{
// Looping code here, as you're dealing with a multi-level array.
// Either do recursion (see controller function for example) or add another
// foreach here if you know exactly how deep your nested list will be.
}
}
$out .= '</ul>';
echo $out;
}
?>
I have not checked this for syntax errors, but it should work fine. Hope this helps..
I searched a lot but I couldn't find on How to use the find('all') in Views as used in Rails, but here I'm getting the error "Undefined property: View::$Menu [APP\Lib\Cake\View\View.php, line 804]"
'Menu' is the model which I'm using to fetch data from the menus table.
I'm using the below code in views:
$this->set('test',$this->Menu->find('all'));
print_r($test);
Inside your Menu model create a method, something like getMenu(). In this method do your find() and get the results you want. Modify the results as you need and like to within the getMenu() method and return the data.
If you need that menu on every page in AppController::beforeFilter() or beforeRender() simply do
$this->set('menu', ClassRegistry::init('Menu')->getMenu());
If you do not need it everywhere you might go better with using requestAction getting the data using this method from the Menus controller that will call getMenu() from the model and return the data. Setting it where you need it would be still better, if you use requestAction you also want to cache it very likely.
TRY TO NOT RETRIEVE DATA WITHIN VIEW FILE. VIOLATION OF MVC RULE
try this in view file:
$menu = ClassRegistry::init('Menu');
pr($menu->find('all'));
In AppHelper ,
Make a below function
function getMenu()
{
App::import('Model', 'Menu');
$this->Menu= &new Menu();
$test = array();
$test = $this->Menu->find('all');
return $test;
}
Use above function in view like :
<?php
$menu = $html->getMenu();
print_r($menu);
?>
Cakephp not allow this .
First create the reference(object) of your model using ClassRegistry::init('Model');
And then call find function from using object
$obj = ClassRegistry::init('Menu');
$test = $obj->find('all');
echo ""; print_r($test); `
This will work.
I'm using CakePHP 2.1.0 and I noticed that if you want to access a controller's action then it doesn't matter what casing you use for the action name; you will always hit that action in the controller. However, the action will expect the view file to be named with the same casing that you used to access the action. So if I were to go to http://example.com/users/aDd, I would hit the code in the "Users" controller's "add" action as expected, but it would look for aDd.ctp, which doesn't exist. Is there a way to make it so that action names can only be accessed if they're lowercase or else they're considered a bad URL?
UPDATE: I think it's safest to do this on the CakePHP level rather than on the web server level. This way, if, for whatever reason, you want to have http://example.com/FoO be valid regardless of the casing but you want http://example.com/bar and http://example.com/users/add to only be accessible if lowercase, you can do that.
Does anybody see a flaw in adding this to the "App" controller's "beforeFilter" method?:
if ($this->request->params['controller'] != strtolower($this->request->params['controller']) || $this->action != strtolower($this->action)) {
$redirect = Router::url(array(
'controller' => strtolower($this->request->params['controller']),
'action' => strtolower($this->action)
) + $this->request->params['pass']);
foreach ($this->request->params['named'] as $key => $value) {
$redirect .= "/$key:$value";
}
$this->redirect($redirect);
}
Well. How about these lines in your AppController:
public function beforeFilter() {
$this->view = strtolower($this->view);
}