Is Zend\Mail\Storage\Imap.php hanging up my server? - php

I am trying to learn/understand Zend Framework for retrieving e-mail messages via IMAP. Our web host doesn't have the IMAP extension enabled on our web server and I have osTicket installed. I want to replace the IMAP function references in osTicket with correlating Zend_Mail references, but to do that I need to understand Zend_Mail a little better.
I have the Zend Framework 2.2.5 and have done my best to read through the documentation, but most of the documentation is really directed at prior versions and while I am doing my best to adjust to read for the updated version, there are some things I am just not understanding.
I have created a test script to get me started, but I'm not understanding what is really happening here and am hoping for a little direction. Here's my script (personal details have been obviously modified for anonymity sake):
<?php
/*******************************************************
* simple php script to verify zend mail functionality *
* *
********************************************************/
define('ROOT_DIR',$_SERVER['DOCUMENT_ROOT'].'/');
define('SUPPORT_DIR',ROOT_DIR.'support/');
define('INCLUDE_DIR',SUPPORT_DIR.'include/');
define('ZEND_DIR',INCLUDE_DIR.'zend/library/'); //ZendFramework-2.2.5
$root = ROOT_DIR;
$support = SUPPORT_DIR;
$incl = INCLUDE_DIR;
$zendir = ZEND_DIR;
var_dump($root);
echo "\n";
var_dump($support);
echo "\n";
var_dump($incl);
echo "\n";
var_dump($zendir);
echo "\n";
echo "Include Imap... ";
include_once(ZEND_DIR.'Zend/Mail/Storage/Imap.php');
if ((include_once(ZEND_DIR.'Zend/Mail/Storage/Imap.php')) !== 1)
{
echo 'Include Imap failed.';
echo "<br>";
}
chdir($zendir);
echo getcwd() . "\n";
$mail_config = array(
'host' => 'imap.gmail.com',
'user' => 'support#gmail.com',
'password' => 'password',
'ssl' => 'SSL',
'port' => 993
);
var_dump($mail_config);
echo "\n";
$mail = new Zend_Mail_Storage_Imap($mail_config);
var_dump($mail);
echo "\n";
var_dump($count = $mail->countMessages());
?>
This appears to run without any errors, except nothing happens after the include_once statement. This is what gets returned to my screen:
string(57) "/usr/home/username/public_html/domain.com/"
string(65) "/usr/home/username/public_html/domain.com/support/"
string(73)
"/usr/home/username/public_html/domain.com/support/include/"
string(86)
"/usr/home/username/public_html/domain.com/support/include/zend/library/"
Include Storage\Imap...
It doesn't show the getcwd(), or the var_dump's for either the array or the count of messages. I even tried changing my if statement verifying the include_once worked to echo a statement if it was successful and that didn't display.
Is the script getting hung up in zend\mail\storage\imap.php? What am I not doing correctly here? Like I said, I'm trying to learn it and have been searching high and low for code examples that use v2.2.5, but I obviously missing something. What is it?
EDIT:
phpinfo() did not show a location for my error logs, so I added the following to the beginning my test script:
ini_set('track_errors', 1);
error_reporting(E_ALL|E_STRICT);
error_log($php_errormsg,3,"/usr/home/username/public_html/domain.com/support/test/error_log.log");
It created the "error_log.log" file, right where it was supposed to, but it's empty and Runscope didn't see the script run?

It looks like you're trying to follow a ZF1 example but using ZF2, which is understandable, but unfortunately won't work.
Firstly, install Composer - http://getcomposer.org/ - it just makes everything easier. I'd recommend going for the 'global' installation option (which the rest of this answer will assume you've done).
In the root folder of your project, create a composer.json file (which lists the project's dependencies). In it, put:
{
"require": {
"php": ">=5.3.3",
"zendframework/zend-mail": "2.*"
}
}
this lists Zend Mail as a dependency and also PHP 5.3.3 (which ZF2 requires as a minimum).
Run composer install to install these. You'll see some output as it downloads the files. Once it's done, it should have created a folder called vendor into which it's installed the ZF2 mail class.
Your whole script can then be simplified to this:
<?php
require 'vendor/autoload.php';
$mail_config = array(
'host' => 'imap.gmail.com',
'user' => 'support#gmail.com',
'password' => 'password',
'ssl' => 'SSL',
'port' => 993
);
$mail = new \Zend\Mail\Storage\Imap($mail_config);
$count = $mail->countMessages();
var_dump($count);
You can remove the copy of ZF2 you put in zend/library/ (assuming you're not using it for anything else).

Related

Apache2 configuration only execute PHP partially

I am experiencing trouble while installing Apache2 on my Debian 8 VPS (jessie).
I installed the website correctly on Hostinger, it works perfectly, but knowing Hostinger was a free plan, I moved to a sufficient VPS so I could get my hands dirty and do the job my myself. I now can handle everything, but the truth is, it's been a long time since I didn't use a debian server, and installing Apache seems harder than I thought.
So, I secured my VPS as I wanted, that's not the problem, the site works correctly, but partially.
I mean, on somes pages, the PHP code executes very well, it works with my database without any problem. I have a utils.php file that contains a getBDD() function like this one :
return new PDO("mysql:host=localhost;dbname=name;charset=utf8", "user", "password");
And it works on my main pages, I can request everything. You can see it here : http://mdjfeelzor.ovh/petiteancienne.php (the website is french).
But I also have an ajax chat that needs a bit of PHP to work properly. Aaaand I don't understand why, but when I initialize my $conn with getBDD(), I am experiencing an issue further in the code.
Look at that code :
include '../utils.php';
session_start();
if(isset($_POST['enter'])){
if($_POST['name'] != ""){
$_SESSION['name'] = stripslashes(htmlspecialchars($_POST['name']));
try {
$conn = getBDD();
$answer = $conn->prepare('SELECT * FROM openchats WHERE ip=? AND name=?');
$answer->execute(array(stripslashes(htmlspecialchars($_SERVER['REMOTE_ADDR'])),
stripslashes(htmlspecialchars($_SESSION['name']))));
if (!($data = $answer->fetch())) {
$req = $conn->prepare('INSERT INTO openchats (ip, name) VALUES (:ip, :name)');
$req->execute(array(
'ip' => stripslashes(htmlspecialchars($_SERVER['REMOTE_ADDR'])),
'name' => stripslashes(htmlspecialchars($_SESSION['name']))));
}
}
catch(PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
}
}
It works correctly, right ? (it's supposed to work correctly on your machine) But the thing is, the code starts showing on my web page on the first call of prepare() as you can see here : http://mdjfeelzor.ovh/chat
So, I was wondering, what do you think is the problem ? Is it my way of programming that isn't working ? By the way, I'm using PHP5. I also tried the code <?php phpinfo(); ?> it works perfectly.
Thanks for your help !
EDIT : By the way, the code is shown but it is not supposed to enter in the condition, as $_POST['enter'] doesn't exist on the first load, the code really works on my computer and on Hostinger so I think that the problem comes from Apache configuration ^^' and the AJAX code is not running at that point.

Smarty: Call of unknown method 'display'

this must be a very stupid question, but i have been searching it's answer and can't find the problem... I've got some trouble while trying to display a smarty template, i was using an older version of smarty and everything worked fine, yet i updated to smarty 3 and i got an exception, it's message saying:
Call of unknown method 'display'.
This is my code:
Index.php
require_once './GeneralFunctions.php';
$smartyVariables = getSmartyVariablesToAssign();
tryToDisplaySmartyTemplate('Index.tpl', $smartyVariables);
function getSmartyVariablesToAssign() {
$userAndOrPasswordError = $_GET['userAndOrPasswordError'];
return array(
'userAndOrPasswordError' => $userAndOrPasswordError
);
}
GeneralFunctions.php
require_once './smarty/libs/Smarty.class.php';
function tryToDisplaySmartyTemplate($templateName, $variablesToAssign = null) {
try {
$mySmarty = callSmarty();
assignSmartyVariables($mySmarty, $variablesToAssign);
$mySmarty->display($templateName);
} catch (Exception $exc) {
showCatchedExceptionTraceAndMessage($exc);
}
}
function callSmarty() {
$mySmarty = new Smarty();
$mySmarty->template_dir = 'smarty/templates';
$mySmarty->compile_dir = 'smarty/templates_c';
$mySmarty->config_dir = 'smarty/config';
$mySmarty->cache_dir = 'smarty/cache';
return $mySmarty;
}
function assignSmartyVariables($mySmarty, $variablesToAssign) {
foreach ($variablesToAssign as $key => $value) {
$mySmarty->assign($key, $value);
}
}
function showCatchedExceptionTraceAndMessage(Exception $exc) {
echo "OcurriĆ³ un error desconocido, por favor, notifique al departamento de sistemas.",
"<br>",
"<br>",
$exc->getTraceAsString(),
"<br>",
"<br>",
$exc->getMessage();
}
I've been investigating, and all i know until now is the existence of a smarty method: testInstall()
Which gives the following info:
Smarty Installation test... Testing template directory...
C:\xampp\htdocs\develop\Registro_de_Tramites\smarty\templates is OK.
Testing compile directory...
C:\xampp\htdocs\develop\Registro_de_Tramites\smarty\templates_c is OK.
Testing plugins directory...
C:\xampp\htdocs\develop\Registro_de_Tramites\smarty\libs\plugins is
OK. Testing cache directory...
C:\xampp\htdocs\develop\Registro_de_Tramites\smarty\cache is OK.
Testing configs directory...
C:\xampp\htdocs\develop\Registro_de_Tramites\smarty\config is OK.
Testing sysplugin files... FAILED: files missing from libs/sysplugins:
smarty_internal_extension_codeframe.php,
smarty_internal_extension_config.php,
smarty_internal_extension_defaulttemplatehandler.php,
smarty_internal_filter_handler.php,
smarty_internal_function_call_handler.php,
smarty_internal_get_include_path.php.
Testing plugin files... ... OK
Tests complete.
I've separated the only FAILED i've got from the rest. It seems libs/sysplugins folder is missing some php files, but downloading it all over again from smarty releases, just gives the same files i have...
To install it, i just copy libs folder into my project, inside "smarty" folder.
Hope to get some help :/
I knew it was a stupid question... by reinstalling smarty 3 it all worked, you see, it seems there was a problem with tortoiseSVN which (who knows why) didn't upload all smarty files properly the first time.
Strange though, that the files missing weren't the ones testInstall() was talking about...
Anyway, if any of you guys have the same problem, try reinstalling smarty first.

Cannot send mail using Zend library

require_once does not seem to work. I am trying to use Zend libraries to send mail but something does not work. I am using my web hosting server provider so I have to put the libraries in a subdirectory (without installing any framework).
// $path= dirname(__FILE__)."/ZendLibrary:".get_include_path() ;
$path= "./ZendLibrary".PATH_SEPARATOR.get_include_path() ;
set_include_path($path);
//echo $path ;
echo "Spot 0" ;
require_once 'Zend/Mail.php';
echo "Spot 1" ;
I got the "Spot 0" message but I don't get the "Spot 1" message. I have selected only two Zend libraries:
ZendLibrary/Zend/Mail/* (directory)
ZendLibrary/Zend/Mime/* (directory)
ZendLibrary/Zend/Mail.php (script)
ZendLibrary/Zend/Mime.php (script)
ZendLibrary is a folder in the same directory where my script is. What could happening?
UPDATE#1:
My problem is that the code stops working right when I run require_once. It does not echo "Spot 1" message. I have tried absolute paths for set_include_path, I have tried to load a .php library script without internal require_once statements, but nothing makes it work. As my test is run from a web hosting site in the Internet I don't have access to logs!.. or do I?
$path= realpath(dirname(__FILE__).'/ZendLibrary').PATH_SEPARATOR.get_include_path() ;
// $path= "./ZendLibrary".PATH_SEPARATOR.get_include_path() ;
set_include_path($path);
Zend Mail has some dependencies.
Hard dependencies
Zend_Exception
Zend_Loader
Zend_Mime
Zend_Validate
Soft
Zend_Locale
Zend_Date
Zend_Filter
Zend_Registry
The best is to add all Zend library to the include path in PHP and all components will load the dependencies automatically.
You havent met all the dependencies... At the minimum you also need Zend_Exception (all component specific exceptions in the framework extend form this) but im pretty sure there are others that Mail and Mime depend on. Just to make it easy on myself i would also grab Zend/Loader and use it for autoloading.
Update:
I took a look and it seems as though you will also need Zend/Validate and Zend/Loader which is required by one of the classes in Validate component - though Mail only uses Zend/Validate/Hostname (which does depend on the abstract classes and interfaces for Validate as well as Zend_Validate_Ip) so you might be able to get away with not grabbing Zend/Loader, but you might as well jsut make use of it for general purpose autoloading.
As a suggestion you could use [Swift Mailer]1 instead... youll be bale to avoid dependency hell and i like it a lot better anyhow. Only down side is its for Sending mail, while Zend_Mail will also let you read a mail store on a local or remote server.
I used Zend_Mail with SMTP standalone before, here are the files I needed. I also reduced it down to what you need if you only want to use sendmail also.
If you want to use Sendmail, that is the easiest. Your dependencies are:
Zend/Exception.php
Zend/Mail.php
Zend/Mime.php
Zend/Mail/Exception.php
Zend/Mail/Transport/Abstract.php
Zend/Mail/Transport/Exception.php
Zend/Mail/Transport/Sendmail.php
Zend/Mime/Exception.php
Zend/Mime/Message.php
Zend/Mime/Part.php
And with those files, here is an example use:
<?php
// optionally
// set_include_path(get_include_path() . PATH_SEPARATOR . '/path/to/Zend');
require_once 'Zend/Mail.php';
require_once 'Zend/Mail/Transport/Sendmail.php';
$transport = new Zend_Mail_Transport_Sendmail();
$mail = new Zend_Mail();
$mail->addTo('user#domain')
->setSubject('Mail Test')
->setBodyText("Hello,\nThis is a Zend Mail message...\n")
->setFrom('sender#domain');
try {
$mail->send($transport);
echo "Message sent!<br />\n";
} catch (Exception $ex) {
echo "Failed to send mail! " . $ex->getMessage() . "<br />\n";
}
If you need SMTP, then you have a few more dependencies as prodigitalson showed. In addition to the above you need at least:
Zend/Loader.php
Zend/Registry.php
Zend/Validate.php
Zend/Mail/Protocol/Abstract.php
Zend/Mail/Protocol/Smtp.php
Zend/Mail/Transport/Smtp.php
Zend/Validate/Abstract.php
Zend/Validate/Hostname.php
Zend/Validate/Interface.php
Zend/Validate/Ip.php
Zend/Validate/Hostname/*
Zend/Mail/Protocol/Smtp/Auth/*
Then you can do something like this:
<?php
require_once 'Zend/Mail.php';
require_once 'Zend/Mail/Transport/Smtp.php';
$config = array(//'ssl' => 'tls',
'port' => '25', //465',
'auth' => 'login',
'username' => 'user',
'password' => 'password');
$transport = new Zend_Mail_Transport_Smtp('smtp.example.com', $config);
$mail = new Zend_Mail();
$mail->addTo('user#domain')
->setSubject('Mail Test')
->setBodyText("Hello,\nThis is a Zend Mail message...\n")
->setFrom('sender#domain');
try {
$mail->send($transport);
echo "Message sent!<br />\n";
} catch (Exception $ex) {
echo "Failed to send mail! " . $ex->getMessage() . "<br />\n";
}
Answer:
My ISP (web hosting too) has a setting to disable require_once. I was able to setup a Unbuntu virtual machine on VirtualBox and set up a web server. I copied the content of my test web site in my Unbuntu and find out that require_once does work as expected !!! That may explain why the server-side include did not work for me either. The following was a usefull check, that indicated me the file was in the expected place.
$file = 'ZendLibrary/Zend/Mail.php';
if ((!is_file($file)) or (!is_readable($file)))
die("File does not exists or is not readable.");
Now I have to find out why it is disabled, how to enable it, or just switch web hosting company. Update: I had to pay $20 dolars a year more for the provider to enable PHP (in this case to be able to include).
This site can tell you more about it.

Run W3 Total Cache Function with Crontab

Ok. I'm really stumped on this one.
Basically, I need to call a function for the Wordpress plugin W3 Total Cache as part of a cron job in crontab. I'd like to automatically clear the entire page cache nightly.
Here's the code that works fine within wordpress that I need to call:
if (function_exists('w3tc_pgcache_flush')) {
w3tc_pgcache_flush();
}
I'm currently using the following script:
#!/usr/bin/php
<?php
define('DOING_AJAX', true);
define('WP_USE_THEMES', false);
$_SERVER = array(
"HTTP_HOST" => "http://example.com",
"SERVER_NAME" => "http://example.com",
"REQUEST_URI" => "/",
"REQUEST_METHOD" => "GET"
);
require_once('/path-to-file/wp-load.php');
wp_mail('email#example.com', 'Automatic email', 'Hello, this is an automatically scheduled email from WordPress.');
if (function_exists('w3tc_pgcache_flush')) {
w3tc_pgcache_flush();
}
?>
and the command line:
php -q /path-to-file/flushtest.php
I used the wp_mail function to test and make sure I'm getting something.
The script is working fine except that the page cache is never flushed. I get the email and there aren't any errors in the log either.
Any ideas?
Thanks for your help.
The better version is now to use wp-cli. The latest version (0.9.2.8) is compatible with this plugin. Just run this command from anywhere in your wordpress directory :
wp w3-total-cache flush
Change the order a bit an try if it still works:
w3tc_pgcache_flush(); # let it crash here so that you won't get the mail
wp_mail('email#example.com', 'Automatic email', 'Hello, this is an automatically scheduled email from WordPress.');

code igniter and exec?

I have a script that, inserts into the database e.g. 20,000 users with email addresses in batches of 1000
(so two tables, emailParent, emailChild), there are 1000 rows in emailChild for every row in emailParent.
I want to run a script that sends these emails which basically says
//check_for_pending_parent_rows() returns the id of the first pending row found, or 0
while($parentId = check_for_pending_parent_row()){//loop over children of parent row}
Now because this is talking to the sendgrid servers this can take some time.
So I want to be able to hit a page and have that page launch a background process which sends the emails to sendgrid.
I thought I could use exec() but then I realized, I am using code igniter, which means the entry point MUST be index.php hence, I don't think exec() will work,
How can I launch a background process that uses code igniter?
This is not really an answer, Just something that is too long to post as a comment
#Frank Farmer: 70 lines seems a bit
excessive, this example from simple
test does it in pretty much half that,
What is the difference?
<?php
//---------------------------
//define required constants
//---------------------------
define('ROOT', dirname(__file__) . '/');
define('APPLICATION', ROOT . 'application/');
define('APPINDEX', ROOT . 'index.php');
//---------------------------
//check if required paths are valid
//---------------------------
$global_array = array(
"ROOT" => ROOT,
"APPLICATION" => APPLICATION,
"APPINDEX" => APPINDEX);
foreach ($global_array as $global_name => $dir_check):
if (!file_exists($dir_check)) {
echo "Cannot Find " . $global_name . " File / Directory: " . $dir_check;
exit;
}
endforeach;
//---------------------------
//load in code igniter
//---------------------------
//Capture CodeIgniter output, discard and load system into $ci variable
ob_start();
include (APPINDEX);
$ci = &get_instance();
ob_end_clean();
//do stuff here
Use exec to run a vanilla CLI PHP script to calls the page via cURL
See http://php.net/manual/en/book.curl.php for info on cURL
This is what I have had to do with some of my codeigniter applications
(Also make sure you set time out to 0)
And doing it this way, you are still able to debug it in the browser
Petah suggested cURL, but recently (since 2.0), CodeIgniter now permits calls to your controllers through the CLI:
This should be easier than cURL.

Categories