Not long ago I started receiving this strange error with mail sending in my Laravel application, error is:
ErrorException in EsmtpTransport.php line 55:
Argument 1 passed to Swift_Transport_EsmtpTransport::__construct() must implement interface Swift_Transport_IoBuffer, none given
Interesting thing is that my mailing system worked just fine for about a year, nothing has been updated (just server and domain paid again few weeks back), so I presume that code isn't the problem, I double checked information in mail authentication system, those are right too.
I followed exception stack trace, and found that in Swift_SmtpTransport::__construct() parameters are sent right, but from there Swift_EsmtpTransport::__construct() is called without parameters (which is actually error shown)
Also I updated all my libraries (with "composer update" command). I have no idea what can be wrong, and couldn't find anything that helps online, so any help will be great
Current versions are:
"laravel/framework": "5.2.*" // from "composer.json"
"swiftmailer/swiftmailer": "~5.1" (v5.4.6 after update) // from "laravel/framework/composer.json"
--- Edit ---
I found somewhere that this is some kind of loading (Dependency Injection) problem, so I executed this line of code:
var_dump(Swift_DependencyContainer::getInstance()->createDependenciesFor('transport.smtp'));
And got this as result array(0) { }
If anyone is interested, I found answer (with friends help). Problem is incompatibility with PHP version, apparently SwiftMailer library doesn't work on newer versions of PHP (>5.5.9, maybe few versions up, not sure from which version it start failing).
Fail is because of some auto-loading conflicts. Solution to this problem is reverting from lazy load to preload, that will slow down a little bit response time, but in most cases you won't even notice that (in my case, I don't see any decline in performance).
Concrete solution:
Find %APP%/vendor/swiftmailer/swiftmailer/lib/swift_requied.php and change it to look like this
<?php
/*
* This file is part of SwiftMailer.
* (c) 2004-2009 Chris Corbyn
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/*
* Autoloader and dependency injection initialization for Swift Mailer.
*/
if (class_exists('Swift', false)) {
return;
}
// Load Swift utility class
require __DIR__.'/classes/Swift.php';
if (!function_exists('_swiftmailer_init')) {
function _swiftmailer_init()
{
require __DIR__.'/swift_init.php';
}
}
// Start the autoloader and lazy-load the init script to set up dependency injection
// Swift::registerAutoload('_swiftmailer_init');
_swiftmailer_init();
Difference is in last line, Swift::registerAutoload('_swiftmailer_init'); is commented out, and _swiftmailer_init method is called directly.
Hope this helps someone, because I lost about 2 days trying to fix this.
Related
I get results from a jQuery Survey in JSON within my Typo3 Extension. Now I want to send these results with the Typo3 Mail API to my Inbox. According to the documentations following shoud do the work
$mail = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
$mail->from(new \Symfony\Component\Mime\Address('john.doe#example.org', 'John Doe'));
$mail->to(
new \Symfony\Component\Mime\Address('receiver#example.com', 'Max Mustermann'),
new \Symfony\Component\Mime\Address('other#example.net')
);
$mail->subject('Your subject');
$mail->text('Here is the message itself');
$mail->html('<p>Here is the message itself</p>');
$mail->attachFromPath('/path/to/my-document.pdf');
$mail->send();
so my code looks like this:
namespace TYPO3\CMS\Core\Mail;
if (!file_exists( dirname(__DIR__, 2).'/vendor/autoload.php' )) {
throw new \RuntimeException(
'Could not find vendor/autoload.php, make sure you ran composer.'
);
} else {
require dirname(__DIR__, 2).'/vendor/autoload.php';
}
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MailUtility;
$mail = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
$mail->from(new \Symfony\Component\Mime\Address('john.doe#example.org', 'John Doe'));
$mail->to(
new \Symfony\Component\Mime\Address('receiver#example.com', 'Max Mustermann'),
new \Symfony\Component\Mime\Address('other#example.net')
);
$mail->subject('Your subject');
$mail->text('Here is the message itself');
$mail->html('<p>Here is the message itself</p>');
$mail->attachFromPath('/path/to/my-document.pdf');
$mail->send();
I just getting errors. Does anyone know how i can achieve this?
Following error i get
Notice: Undefined index: TYPO3_CONF_VARS in /var/www/html/local_packages/ext_sitepackage/public/typo3/sysext/core/Classes/Mail/Mailer.php on line 170
Apparently this is the same question as you already posted here.
This will never work like this. You need to either build a fully fledged TYPO3 extension or a standalone application using symfony/mailer directly.
Your script is missing $GLOBALS['TYPO3_CONF_VARS']['MAIL'].
You stumble over the fact that you're programming past the conventions and requirements of TYPO3, but then you're surprised that the framework's functions don't work...
Create a middleware in your sitepackage, and register it correctly. Check for a special route and let the rest run. If handling, use the code there.
You need to run the mailing code in a (full) bootstrapped Typo3 context:
in a middleware
extbase plugin registered with pageNum directly
Your pasted code looks weired in a lot of ways. Just putting a file in a extension folder do not mean that is correctly a typo3 extension.
Maybe you want to start and have a proper extension setup first, with the corresponding readings:
ext_emconf.php / composer.json as a minimum
code files in 'Classes/' subfolders
then decide with which way you want to handle the "ajax" call and send the email, there are several possibilities (as already mentioned above) .. than read and implement that solution the proper and correct way.
Just having a php file directly referenced/called and just bootstpping the composer autoloader do not and never will be bootstrapping Typo3 with all needed configuration bootstrapping (gathering confings from extensions, Local/AdditionalConfiguration, siteconfig and and and).
And generally a package/extension should have a namespace something like following (as a convention):
<extensionname.....
an thus registered as psr-4 autoloading in your extension composer.json ..
Starting to implement the peaces to simulate a Typo3 bootstpraping in that file is not good and will make a lot of headache ... it's easier to have a proper sitepacke/extension structure.
I'm in the process of trying to make a laravel compatible composer/packagist package. I'm using Laravel 5.5.
I've created a package : floor9design/machine-identifier. Composer downloads this to vendors/floor9design fine, but despite reading/googling how to do this, I'm unsure of how to include this in my laravel projects.
PHP Storm is correctly picking up the class, auto-completing as expecting.
I have not modified any files so far. If I add the following to a controller:
use Floor9design\MachineIdentifier\MachineIdentifier;
(alongside some class usage on the page).
PHP storm autocompletes this (as it does with other classes validly called).
When I try to load this, the following error comes:
Class 'Floor9design\MachineIdentifier\MachineIdentifier' not found
I've had a look round plenty of tutorials, and this final step seems to be missing from a lot of information.
I realise there are three approaches:
Firstly:
Direct include_once, which while working, is not the normal approach
Secondly:
Pre-laravel 5.5 approach (add something to app.php)
Thirdly
Laravel 5.5 approach and up, autodetection of something.
I've deliberately said something as the documentation seems to speak about ServiceProviders, and I simply don't get how they work.
Let me rephrase this into a question and a follow up question:
Question: apart from include_once, how do I load the MachineIdentifer class from floor9design/machine-identifier in Laravel.
Question 2: If the answer is via a service provider, can you simply explain how they relate to one another.
Thanks
Answer (as accepted below)
On the composer repo I was incorrectly specifying the PSR4 namespace, which is now corrected to:
"autoload": {
"psr-4": {
"Floor9design\\MachineIdentifier\\": "src"
}
}
The previous namespace had a -, which is an illegal character. Many thanks to lawrence-cherone.
Your PSR4 is wrong in the package
floor9design\\machine-identifier\\": "src"
Will cause the composer/autoload_psr4.php to map to:
'floor9design\\machine-identifier\\' => array($vendorDir . '/floor9design/machine-identifier/src'),
Which is not a valid class namespace.
You should change the PSR4 to match your class namespace:
Floor9design\\MachineIdentifier\\": "src"
Once you fix that you will be able to use it like normal from anywhere in your project.
I'm attempting to implement https://github.com/PHP-FFMpeg/PHP-FFMpeg
I copied the src/FFMpeg folder to my includes folder and made sure my autoloader knows where to find everything.
as a test I made a script that simply does:
$ffmpeg = FFMpeg\FFMpeg::create();
$video = $ffmpeg->open('video.mpg');
I get:
Fatal error: Class 'Doctrine\Common\Cache\ArrayCache' not found in /var/www/php/include/FFMpeg/FFProbe.php on line 203
My question is: does PHP-FFMPeg require Doctrine, because that is not stated in the documentation. What version do I need? Are there other prerequisites?
I could create a new question for this, but I'm not sure if I should. I now have PHP-ffmpeg implemented. I'm using Laravel, however that should be irrelevant for this question. I'm trying to enable progress monitoring. It works, however I need to pass in an ID so I can update the correct key in memcache.
$id = 12345;
$format->on('progress', function ($audio, $format, $percentage) {
//this works perfect, but doesn't tell me which item is being updated
Cache::put("progress", $percentage, .25);
//this does not work as I am unable to pass in $id, if I add it as the 4th argument above it will display the number of threads or something
//Cache::put("{$id}_progress", $percentage, .25);
});
I need clarification on the "on" method. I looked through https://ffmpeg-php.readthedocs.org/en/latest/_static/API/ and was not able to figure out how this method works. Any help would be appreciated.
You should follow the recommended instructions in the README.
Composer is the easiest way to install PHP-FFMpeg dependencies
The "on" method called on the format is an implementation of EventEmitter.
As you can see here : https://ffmpeg-php.readthedocs.org/en/latest/_static/API/FFMpeg/Format/ProgressableInterface.html it extends the EventEmitterInterface of https://github.com/igorw/evenement.
If you're really interested about how it works under the hood, have a look at here :
The progress listener is created here : https://github.com/PHP-FFMpeg/PHP-FFMpeg/blob/master/src/FFMpeg/Format/Audio/DefaultAudio.php#L96 and added at execution here https://github.com/PHP-FFMpeg/PHP-FFMpeg/blob/master/src/FFMpeg/Media/Video.php#L151
This is actually possible because FFMpegDriver extends the Driver provided by https://github.com/alchemy-fr/BinaryDriver
Hope this helps :)
I have quite an interesting (and annoying) problem here. For some reason, the PHP method ReflectionClass::getDocComment() is returning false on my production environment (while there actually is a block comment in the class of course...).
Causing the Doctrine AnnotationReader / DocParser to fail:
(Doctrine\Common\Annotations\AnnotationReader.php:143)
public function getClassAnnotations(ReflectionClass $class)
{
$this->parser->setTarget(Target::TARGET_CLASS);
$this->parser->setImports($this->getImports($class));
$this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
return $this->parser->parse($class->getDocComment(), 'class ' . $class->getName());
}
I've looked around and haven't seen very much about this problem, so I'm wondering why this is happening on my Production server when it does not on my Local environment.
Would it be because of some PHP config??
Would it be because of some read / write / file access rights (chown, etc...)??
Would it be because of some caching configuration??
I must say I am running out of ideas.
Any help is much appreciated.
Thanks.
Ok. This appeared to be linked to some strange behavior of eAccelerator stripping all the comments when caching the byte code...
http://wildlyinaccurate.com/eaccelerator-and-doctrine-2/
(Re-)Quoting beberlei from the Doctrine team:
This premature optimization to remove the docblocks should be
reverted. Docblocks are a PHP Token for a reason, they are part of the
language and should be used that way. Please revise your stand on this
otherwise projects must suggest NOT to use eAccelerator by default.
Solution is either to disable eAccelerator OR to reconfigure it with the option:
--with-eaccelerator-doc-comment-inclusion
(Source: https://eaccelerator.net/ticket/229)
So I recently discovered that the log4* package was available for PHP and upon seeing this eagerly downloaded the latest from the log4php website and followed the installation instructions. The instructions indicate that one is to download the tar package, untar, and place the following directory in a place of one's choosing: log4php/src/main/php
Therefore I copied the contents of log4php/src/main/php into my lib dir under lib/log4php.
In my script, as required, I required the 'Logger.php' class and indicated a properties file to manage my appenders. The properties file, log4php.properties, is located on my filesystem at "/home1/ioforgec/www/devlab/pnotes/config/log4php.properties".
Here is the logfile content:
#
# Example Logger
#
log4php.appender.EA1 = LoggerAppenderConsole
log4php.appender.EA1.target = STDOUT
log4php.appender.EA1.layout = LoggerLayoutPattern
log4php.appender.EA1.ConversionPattern = "%m"
log4php.appender.EA1.threshold = FATAL
log4php.exampleLogger = FATAL, EA1
So here is a copy of my script that implements (more or less 'wraps' the log4php functionality):
<?php
require_once('/home1/ioforgec/www/devlab/pnotes/lib/log4php/Logger.php');
class LogUtil
{
public $logger;
public $properties_file = "/home1/ioforgec/www/devlab/pnotes/config/log4php.properties";
public static function logExample($msg)
{
Logger::configure($properties_file);
$logger = Logger::getLogger("example");
$logger->debug("Shouldnt see this print because of config max level FATAL");
$logger->fatal($msg);
}
}
?>
In order to test that this is working properly, the following script calls the LogUtil.php shown above:
#!/usr/bin/php
<?php
require_once("lib/utils/LogUtil.php");
LogUtil::logExample("example message");
?>
So, despite configuring the example logger to format the messages as the plain message, despite setting the level of the logger to a max of FATAL, not only in the logger declaration but also in the threshold command, the print to the console looks to me like the default root logger:
Mon Oct 18 20:30:05 2010,705 [827] DEBUG example - Shouldnt see this print because of config max level FATAL
Mon Oct 18 20:30:05 2010,711 [827] FATAL example - example message
I see the print statement without the plain formatting as specified, and I see two print statements, the debug print (which should never have printed due to the setting of FATAL on the logger config - FATAL is MUCH higher than DEBUG)
What on earth am I doing wrong? Ive tried every combination of setup I can possibly think of. Does anyone have any suggestions?
Edit - Update - This is still an issue. No progress.
Edit2 - Really? Has no one on this forum tried to use this very popular logging package and its incarnation as a PHP module?
I have tried every conceivable avenue to try and get my question answered, including the log4php user's mailing list.
After many many more hours of manipulating the configuration file I have discovered a small, yet critically important factoid. In order to specify a 'logger' you must name it under the 'logger' hierarchy and its appenders under the 'appender' hierarchy, etc etc. For example:
# for the 'console' logger named 'example' we first define the appender:
log4php.appender.consoleAppender = LoggerAppenderConsole
log4php.appender.consoleAppender.target = STDOUT
log4php.appender.consoleAppender.layout = LoggerLayoutSimple
# we then assign the appender and the minimum log level to the logger:
log4php.logger.example = WARN, consoleAppender
My mistake was in seeing the root logger hierarchy name 'log4php.rootLogger' and assuming that in order to assign a logger one need only name a value for 'log4php.lognameLogger'. Sadly this is no excuse as there was an example, buried, in the documentation. I suppose finding it at 9+ hours is better than not at all :)
Thanks to those who reminded me that there was more debugging work to be done, I appreciated the reminder to keep trying