I recently needed to build an asterisk based IVR for an application built using cakePHP.
I wanted to use cakes' (fat) models, so I wouldn't have to re-write business logic.
I wanted to create a cakePHP shell which would be called from the asterisk dialplan.
Here's what I did.
Downloaded phpagi to vendors/phpagi.
Modified phpagi.php from
function AGI($config=NULL, $optconfig=array())
to:
function AGI($config=NULL, $optconfig=array(), $stdin, $stdout)
so I can set stdin and stdout. Around line 167 I changed
$this->in = defined('STDIN') ? STDIN : fopen('php://stdin', 'r');
$this->out = defined('STDOUT') ? STDOUT : fopen('php://stdout', 'w');
To
$this->in = $stdin;
$this->out = $stdout;
In my shell in vendors/shells I added
App::import('Vendor', 'AGI', array('phpagi/phpagi.php'));
I also added
var $agi;
//redirect output through agi conlog
function err($message,$newlines = 1){
$this->agi->conlog($message);
}
function out($message, $newlines =1){
$this->agi->conlog($message);
}
//disable default message
function startup(){
}
and the application code is in
function main(){
$this->agi = new AGI(NULL, array(), $this->Dispatch->stdin,$this->Dispatch->stdout);
$this->agi->answer();
//do stuff here
}
and to run this in the dialplan all you need to do is
exten => s,n,AGI(${full/path/to/cake.php},${shellname},-app,${var/www/html/{appname}/app},-console,var/www/html/{appname}/cake/console/)
Make sure to fix permissions on the cake dirs.
I was wondering if anyone had any other ways to do this?
Here is a class that will handel all the work for you. It is maintained by FreePBX - the most popular Asterisk GUI, and used extensively throughout FreePBX.
Related
In an unrelated, vanilla PHP project, I simply have this:
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'vendor/autoload.php';
It pulls in just fine. Following CakePHP 2.10's standards, I put all associated (composer'd) files in the app/Vendor folder and try this in my controller:
public function index($load = null) {
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
include(APP . 'Vendor' . DS.'autoload.php');
I get:
syntax error, unexpected 'use' (T_USE)
Any attempts to move the use around end up not working, so I ignore them and try to get it to work without namespaces.
require_once(APP . 'Vendor' . DS.'autoload.php');
require_once(APP . 'Vendor' . DS.'phpmailer\phpmailer\src\PHPMailer.php');
I know it's loading the PHP file via require_once, and that file includes the PHPMailer class. I get this error:
Error: Class 'PHPMailer' not found
But I know that class has to be present somewhere, because I loaded it. Code looks like this, to call it:
$mail = new PHPMailer(true);
try {
//Server settings
$mail->SMTPDebug = 3; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.zoho.com'; // Specify main and backup SMTP servers
etc. So I'm not sure if this version of PHPMailer refuses to work without namespaces, which CakePHP 2 doesn't support? All other questions on Google do not seem to help me.
You're putting the use statements in the wrong place; they need to go at the top of your file (after any namespace declaration) as they are not block-scoped. Read the PHP docs.
You can mix namespaced and non-namespaced code, you just need to be aware that it's going on.
I use html2pdf, which is based on TCPDF, in CakePhp to render Views in PDF.
However, sometimes the generation hangs, I mean the browser freezes and never receives data.
There is a way to debug such a behavior? In apache logs I do not see any kind of error...
$this->set(compact('quotation','company','user'));
$view = new View(null, false);
$view->set(compact('quotation','company','user'));
$view->viewPath = 'Quotations';
$view->layout = 'preventivo';
if ($quotation['Quotation']['quotation_type'] == SERVICE)
{
$content = $view->render('print_s_template');
$this->set(compact('content'));
$this->response->type('pdf');
$this->render('print');
the print.ctp has
App::import('Vendor', 'HTML2PDF', array('file' => 'html2pdf'.DS.'html2pdf.class.php'));
$html2pdf = new HTML2PDF('P','A4','it');
$html2pdf->WriteHTML($content);
$html2pdf->Output('exemple.pdf');
and the html is in print_s_template.ctp.
I found a solution myself. The problem is that I forgot to pass some variables to the View $view. And I suppose cake throw an error which, next, html2pdf cannot "render".
So: double check that all the variables in the view do exist!
When running a feeds importer using Cron, the importer times out resulting in an incomplete import. I'm trying to use a script to execute the importer and I've come across this code a few times:
<?php
function MODULE_NAME_cron() {
$name = 'FEED_NAME';
$source = feeds_source($name);
$source->import();
}
?>
However, when executing this I get an error saying there's no feeds_source() function, which leads me to believe that I just don't know where to put this code (a separate php file just isn't working for me). Can anyone help me out here? Thanks in advance!
I think you need to call $source->startImport(); method instaed of $source->import();
I just posted an answer to a similar question over here: https://drupal.stackexchange.com/questions/90062/programmatically-execute-feed-import/153434#153434 , which might help. in short, in the a form submit hook if your using the batch api, or dont use the batch api if you're doing it non browser (install hook , install profile)
so in your case
function load_data(){
// Files to import in specific order.
$files = array(
'challenge_importer' => 'data/challenges.csv',
);
$file_location_base = drupal_get_path('module', 'challenge');
foreach ($files as $feed => $file) {
$feedSource = feeds_source($feed);
// Set the file name to import
$filename = $file_location_base.'/' . $file;
if (!file_destination($filename, FILE_EXISTS_ERROR)) {
$config = $feedSource->getConfig();
$config['FeedsFileFetcher']['source'] = $filename;
$feedSource->setConfig($config);
$feedSource->save();
while (FEEDS_BATCH_COMPLETE != $feedSource->import());
}
}
}
could be called from the cron , or use the scheduled execution from the feeds importer
I know that in folder config are file called core.php which I can configure application options as a debug mode, session, cache etc.
But I want do configure file for my application. I want for example configure how many post can be displayed in main page, thubnails size etc.
I think that the best place in config folder but where and when parse thos file in application (bootstrap, AppController another mechanism ?) and what is the best extension .ini or PHP array (for performance reason too). What is the best practice to do this ?
DEFINE OWN CONSTANT FILE
Create a file lets suppose 'site_constants.php' containing some constant variables in app/Config folder. Define the following constants into it:
<?php
define('HTTP_HOST', "http://" . $_SERVER['HTTP_HOST'].'/');
if(HTTP_HOST == 'localhost' || HTTP_HOST == '127.0.0.1')
{
define('SITE_URL', HTTP_HOST.'app_folder_name/');
}
else
{
define('SITE_URL', HTTP_HOST);
}
Include it in app/Config/bootstrap.php
require_once('site_constants.php');
Now you can use it anywhere into your website. And this is also a dynamic.
DEFINE OWN CONFIGURATION FILE
Create a file lets suppose 'my_config.php' containing some constant variables in app/Config folder. Define the constant in the following way:
<?php
$config['PageConfig'] = array('PostPerPage' => 5, 'UserPerPage' => 15);
Then in your app/Controller/AppController.php write the following line in beforeFilter() method:
function beforeFilter()
{
Configure::load('my_config');
}
Now in your controller's method, where you want to access the page number to be listed in your pagination list. You can use it by following code:
$page_config = Configure :: read('PageConfig');
$user_per_page = $page_config['UserPerPage'];
//or
$post_per_page = $page_config['PostPerPage'];
This might looks long process to handle this task, but once done, it will help you in many senses.
Here are the advantages:
you can easily define some more constants (like any file path etc).
you can put all your ajax code into external JS files.
you can directly deploy it onto any server without changing in constants as well as work perfectly onto your localhost.
following standard conventions etc.
CakePHP provides the Configure class for this purpose. See the documentation.
You can use Configure::write($key,$value) in your own config file, and then read the values elsewhere in your application through Configure::read($key). It also allows you to use readers that automate the process and read in external configuration files. CakePHP provides a PHPreader and an INIreader by default and you can create readers to extend it.
Create a new file with configuring variables, like:
Configure::write('Twitter', array(
'consumer_key' => "OTh1sIsY0urC0n5um3rK3Y4T878676",
'consumer_secret' => "OTh1sIsY0ur53cReT76OTIMGjEhiWx94f3LV",
'oauth_access_token' => "12345678-OTh1sIsY0urAcc355K3YT878676Y723n4hqxSyI4",
'oauth_access_token_secret' => "OTh1sIsY0urACC355T0KEnsdjh4T878676FPtRRtjDA29ejYSn"
));
save this file in app/Config/twitter.php
Include that file in app/Config/bootsrap.php:
require_once('twitter.php');
In the Controller (this example 'app/Controller/TwitterController.php'), you can use that like:
$settings = Configure :: read('Twitter');
I have problem with cakephp's Session->write method.
If I set a value like $_SESSION['..'] i'm able to read it back. But if I use the write method it's not working.
My problem is same as here: http://www.nabble.com/Session-problem-td16684956.html
The same code was working in windows but it's not working after I moved to linux.
Any permission problem would be the reason? (but i have given rw permission fully for the cake app directory).
code sample: in the link: http://www.nabble.com/Session-problem-td16684956.html
Configure::write('Session.save', 'php');
Configure::write('Session.cookie', 'CAKEPHP');
Configure::write('Session.start', true);
Configure::write('Session.checkAgent', false);
Configure::write('Security.level', 'medium');
cake version: 1.2.3.8166
Some steps to ensure it's not you:
clear the cache in your /app/tmp
check and recheck that your /app/tmp is world-writable recursively (that means drwxrwxrwx for all folders inside)
use Firebug to check your session cookie, maybe something has gone wrong with it
Last but not least, try to move your session persistence to your database (see: Session.save), just to test things out that way, you never know what you'll find.
Hopefully you'll find something if you try all these.
You should also try to use Cache::read and Cache::write
if (($session = Cache::read('session')) === false)
{
$session = 'some values';
Cache::write('session', $session);
}
Firstly, it will try to initialize Cache::read. If it returns false, Cache::write
will take part to store the values in sessions.
Prabu,
While I suspect the Configure::write() call will sometimes correctly set the session information (at least it looks like it might work), the Cake convention (aka the CakeWay) is to use the Session helper. I believe it is included by default in all Cake controllers; if not, you can always declare your controller as such:
class UsersController extends AppController {
...
var $helpers = array( 'Session', ... )
...
}
Then, when you want to write info to the session, just call:
$this->Session->write( 'checkAgent', false );
To read back values, use:
$this->Session->read( 'checkAgent');
For more information on the Session helper, check out the CakeBook # http://book.cakephp.org/view/484/Session