I am trying to convert HTML 2 PDF with this library and its converting fine as per my expectations.
However, When I convert with more data, its giving me an error saying 504 Gateway Timeout. Here is the error screenshot what I am getting.
In local server its working fine. I have the same server in my local and my live (Linux). The only problem is I am getting when I try to produce PDF with long data on live server.
I researched and found out that to increase php execution time and other settings. Hence I try to put below code in my .php file.
ini_set('max_execution_time', 60000);
ini_set('post_max_size','128M');
ini_set('upload_max_filesize','128M');
I even try to set max_execution_time to 0 and -1 but yet its not working for me. After setting this values, I even printed the updated values with phpinfo(), the values are overwriting but I am having the same 502 Gateway timeout error. Here is small chunk of code just in case you want to see.
<?php
ini_set('max_execution_time', 60000);
ini_set('post_max_size','20M');
ini_set('upload_max_filesize','8M');
require_once dirname(__FILE__) . '/vendor/autoload.php';
require_once dirname(__FILE__) . '/templateInfo.php';
use Spipu\Html2Pdf\Html2Pdf;
use Spipu\Html2Pdf\Exception\Html2PdfException;
use Spipu\Html2Pdf\Exception\ExceptionFormatter;
use technobrave\brochuresettings\Models\Brochuresettings as BS;
use Technobrave\Transactions\Models\Transactions as TR;
use Technobrave\Offices\Models\Offices;
use technobrave\themesettings\Models\ThemeSetting as TS;
use Technobrave\Team\Models\Team;
class generateTemplate {
public $theme = "";
public $theme_settings = array();
public function __construct($templateId, $resolution , $theme ,$pdf_sections = array(),$openFile = false, $finalPdfFile = null) {
$this->getBrochureTransactionData = BS::first();
$this->getPdfSection = $pdf_sections;
$this->theme_settings = TS::first();
$this->theme = $theme;
$this->baseUrl = url(Config::get('cms'));
$this->teamPageName = $this->baseUrl . '/our-team';
$this->capabilitiesPageName = $this->baseUrl . '/capabilities';
$this->getFooterText = $this->getFooterText();
$getTeamId = (isset($_GET['teamId']) && !empty($_GET['teamId'])) ? $_GET['teamId'] : "";
$this->uniquePath = __DIR__ . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR;
$templatePath = __DIR__ . DIRECTORY_SEPARATOR . 'regency_template' . DIRECTORY_SEPARATOR . $getTeamId . DIRECTORY_SEPARATOR . $templateId . '.php';
$templateInfoText = new templateInfo($templateId, $this->uniquePath, $getTeamId);
$this->customImagePath = $this->uniquePath;
foreach ($templateInfoText->defaultValues as $key => $value) {
$this->{$key} = $value;
}
$template = file_get_contents($templatePath);
try
{
$html2pdf = new Html2Pdf('L','A4', 'en', true, 'UTF-8', array(0, 0, 0, 0));
$html2pdf->Addfont('perpetua');
$html2pdf->Addfont('montserratbold');
$html2pdf->Addfont('montserratmedium');
$html2pdf->Addfont('montserratregular');
$html2pdf->Addfont('montserratsembold');
$html2pdf->Addfont('montserratitalic');
$html2pdf->writeHTML($template, false);
$html2pdf->Output('regency_corporate_brochure.pdf', 'D');
} catch (Html2PdfException $e) {
$formatter = new ExceptionFormater($e);
echo $formatter->getHtmlMessage();
}
}
}
I tried to preview how my HTML is generating and its generating without any error.
$html2pdf->writeHTML($template, true);
So basically I am facing server issue here as per my understanding so far.
Can someone guide me what should I do from here on to solve this issue.
After a hard debugging I found that my problem was that I was including an external image in the PDF and the server can't reach the server image (server access only trough white-list IP).
I asked a similar question previously, but didn't know how to quite ask before. Below I created a new directory based on the username I grabbed from a signup form. I just need the inclusion of the template file copied over to the new directory that was just made. The outcome I'm getting is an inclusion of the file in the directory that's up one level. The new directory is created with the username but doesn't contain the template file in its directory. I spent hours on this so I wouldn't have to bother you guys again. What am I doing wrong?
$folder = DIRECTORY_SEPARATOR; // adds the forward slash
$name = $user->username; // included from a login script I purchased
$thisdir = "../associate"; // desired directory
$folderPath = $thisdir . $folder . $name;
$file = copy('../associate/joshua/career.php', $folderPath.'.php'); // copy this file into new directory
if(!file_exists($folderPath)){
mkdir($folderPath);
chmod($folderPath,0777);
}
file_put_contents(realpath($folderPath) .'/'. $folderPath, $file);
});
If I understand you well, you want to copy career.php template from /associates/ folder to /associates/username/ folder
$rootfolder = $_SERVER['DOCUMENT_ROOT'];
$name = $user->username;
$thisdir = "/associate/";
$folderPath = $rootfolder.$thisdir.$name."/"; // desired directory
if(!is_dir($folderPath)){
mkdir($folderPath, 0777, true);
}
$currentfile = $rootfolder.$thisdir.'joshua/career.php';
$destination = $folderPath.'career.php';
copy($currentfile, $destination); // copy this file into new directory
I am trying to create a new XenForo user in PHP.
I am using this example code:
$newusername = "Joseph";
$newpassword = "12345";
$newemail = "joseph#yahoo.com";
$fileDir = "/home/myfullpath/public_html/members/xenforo";
require( $fileDir . '/library/XenForo/Autoloader.php');
XenForo_Autoloader::getInstance()->setupAutoloader($fileDir . '/library');
$startTime = microtime(true);
XenForo_Autoloader::initialize($fileDir . '/library', $fileDir);
XenForo_Autoloader::set('page_start_time', $startTime);
// XenForo_Application::disablePhpErrorHandler();
// create new user
$writer = XenForo_DataWriter::create('XenForo_DataWriter_User');
// set all the values
$writer->set('username', $newusername);
$writer->set('email', $newemail);
$writer->setPassword($newpassword, $newpassword);
$writer->set('user_group_id', XenForo_Model_User::$defaultRegisteredGroupId);
// save user
$result = $writer->save();
echo $result;
The problem is, I get this error:
Fatal error: Call to undefined method XenForo_Autoloader::initialize() in /home/myfullpath/public_html/members/signup/create-user.php on line 13
Line 13 is:
XenForo_Autoloader::initialize($fileDir . '/library', $fileDir);
I checked the Autoloader.php file and couldn't find the initialize method so I don't doubt what PHP is telling me.
How are you meant to load the XenForo environment so you can create a new user? Did they update it in a recent version update or something?
I found the problem with the code...
I should be targeting the XenForo_Application method not XenForo_Autoloader...
require( $fileDir . '/library/XenForo/Autoloader.php');
XenForo_Autoloader::getInstance()->setupAutoloader($fileDir . '/library');
XenForo_Application::initialize($fileDir . '/library', $fileDir);
XenForo_Application::set('page_start_time', $startTime);
XenForo_Application::setDebugMode(true);
XenForo_Application::disablePhpErrorHandler();
I have gcm in folder (dirC)...here the paths
index.php
dirA/
dirB/
dirC/GCM.php
----/config.php
----/sendMsg.php
dirD/
dirE/dirE1/test.php //send from here
dirF/
gcm.php have code bellow
class GCM {
function __construct() {
}
/**
* Sending Push Notification
*/
public function send_notification($registatoin_ids, $message) {
// include config
include_once './config.php';
//other code here
echo 'test';
}
}
and i successfull send message from sendMsg.php,here the code
include_once './GCM.php';
$message="hello word";
$gcm = new GCM();
$registatoin_ids = array("SEJFOJOEUJFPUWPJR0923740JEU092308UPUPUAUOJLJLJJVPW634");
$message = array($message);
$result = $gcm->send_notification($registatoin_ids, $message);
echo $result;
my question is how to set the path to communicate with GCM.php using include_once from test.php ?
here test.php code
include_once './GCM.php'; //my proble is here ???????????
$message="hello word";
$gcm = new GCM();
$registatoin_ids = array("SEJFOJOEUJFPUWPJR0923740JEU092308UPUPUAUOJLJLJJVPW634");
$message = array($message);
$result = $gcm->send_notification($registatoin_ids, $message);
echo $result;
thanks in advance..
When you want to get to your desired directory, you need to use ../, which means 'move one directory up'.
Example:
we have a directory structure:
/website
/website/include
/website/template
Imagine we are in /website/template directory.
If we want to include /website/include/GCM.php
We can do it with an absolute path, / means the root directory:
include_once '/website/include/GCM.php';
We can do it with a relative path:
include_once '../include/GCM.php';
../ means 'move 1 directory up'.
For more information: http://www.geeksengine.com/article/absolute-relative-path.html
The question is not really clear. But i think the problem is that you make a folder, from which you include and you dont know what folder that is?
For that you have magic constants in php:
http://php.net/manual/en/language.constants.predefined.php
From php documentation you can do something like that :
$path = '/dirC';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
In your index.php (if it's your controller), or in a conf/prepend file, which is included in all your script.
Then a simple include('GCM.php'); will work.
I know about CRON and how to create/manage it. But this issue was different.
I want to develop a module to delete any (unpaid) order that exceeds the time frame given.
Ex: I want to delete any unpaid order that has not been paid for 2 days after the order was placed.
I want to use existed model in opencart (and not use a new one). Let's say the module URL would be: http://www.yourstore.com/admin/index.php?route=module/modulename/function
And will be called from CRON, and then all any unpaid order will be disappeared.
But the main problem is: when CRON wants to access that URL, it needs a security token or it will never be executed.
My question is: how to execute that module from CRON without security token (in case just for that module)?
Please help me, if you have a better idea or a more clean way, I would say many thanks to you.
Updated : For Opencart versions <= 1.5.6.4
For admin related cron jobs, Do like this.
Copy the admin/index.php to admin/index_for_cron.php
Now, in the admin/index_for_cron.php, search for these 2 lines and comment them out which are responsible for the login & the permissions.
// Login
// $controller->addPreAction(new Action('common/home/login'));
// Permission
// $controller->addPreAction(new Action('common/home/permission'));
Now use this url for your cron job.
http://www.yourstore.com/admin/index_for_cron.php?route=module/modulename/function
NOTE: it is highly recommended to changes the name of index_for_cron.php into an ugly, unpredictable name for the security reasons.
Hope this helps :)
I've done something similar to IJas. Adjacent to admin and catalog, I've created a new folder called "cli".
This folder contains a php file for a specific function to be performed by cli (executing scripts via crontab on a set schedule, or manually in the command line), as well as a "bootstrap" of sorts for these types of scripts. The bootstrap is essentially a copy of the "index" found in catalog or admin, and includes some checks and removes the permission checking and some other unnecessary items. It calls whatever controller/action is set forth in the calling specific function script (in the example below, it calls the index method of the class defined in /admin/controller/common/cli_some_function.php).
Function-Specific Script:
<?php
$cli_action = 'common/cli_some_function';
require_once('cli_dispatch.php');
?>
CLI "Bootstrap"/Dispatcher:
<?php
// CLI must be called by cli php
if (php_sapi_name() != 'cli') {
syslog(LOG_ERR, "cli $cli_action call attempted by non-cli.");
http_response_code(400);
exit;
}
// Ensure $cli_action is set
if (!isset($cli_action)) {
echo 'ERROR: $cli_action must be set in calling script.';
syslog(LOG_ERR, '$cli_action must be set in calling script');
http_response_code(400);
exit;
}
// Handle errors by writing to log
function cli_error_handler($log_level, $log_text, $error_file, $error_line) {
syslog(LOG_ERR, 'CLI Error: ' . $log_text . ' in ' . $error_file . ': ' . $error_line);
echo 'CLI Error: ' . $log_text . ' in ' . $error_file . ': ' . $error_line;
}
set_error_handler('cli_error_handler');
// Configuration not present in CLI (vs web)
chdir(__DIR__.'/../admin');
set_include_path(get_include_path() . PATH_SEPARATOR . realpath(dirname(__FILE__)) . '../admin/');
$_SERVER['HTTP_HOST'] = '';
// Version
define('VERSION', '1.5.1');
// Configuration (note we're using the admin config)
require_once('../admin/config.php');
// Configuration check
if (!defined('DIR_APPLICATION')) {
echo "ERROR: cli $cli_action call missing configuration.";
$log->write("ERROR: cli $cli_action call missing configuration.");
http_response_code(400);
exit;
}
// Startup
require_once(DIR_SYSTEM . 'startup.php');
// Application Classes
require_once(DIR_SYSTEM . 'library/currency.php');
require_once(DIR_SYSTEM . 'library/user.php');
require_once(DIR_SYSTEM . 'library/weight.php');
require_once(DIR_SYSTEM . 'library/length.php');
// Registry
$registry = new Registry();
// Loader
$loader = new Loader($registry);
$registry->set('load', $loader);
// Config
$config = new Config();
$registry->set('config', $config);
// Database
$db = new DB(DB_DRIVER, DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
$registry->set('db', $db);
// Settings
$query = $db->query("SELECT * FROM " . DB_PREFIX . "setting WHERE store_id = '0'");
foreach ($query->rows as $setting) {
if (!$setting['serialized']) {
$config->set($setting['key'], $setting['value']);
} else {
$config->set($setting['key'], unserialize($setting['value']));
}
}
// Url
$url = new Url(HTTP_SERVER, HTTPS_SERVER);
$registry->set('url', $url);
// Log
$log = new Log($config->get('config_error_filename'));
$registry->set('log', $log);
function error_handler($errno, $errstr, $errfile, $errline) {
global $log, $config;
switch ($errno) {
case E_NOTICE:
case E_USER_NOTICE:
$error = 'Notice';
break;
case E_WARNING:
case E_USER_WARNING:
$error = 'Warning';
break;
case E_ERROR:
case E_USER_ERROR:
$error = 'Fatal Error';
break;
default:
$error = 'Unknown';
break;
}
if ($config->get('config_error_display')) {
echo "\n".'PHP ' . $error . ': ' . $errstr . ' in ' . $errfile . ' on line ' . $errline."\n";
}
if ($config->get('config_error_log')) {
$log->write('PHP ' . $error . ': ' . $errstr . ' in ' . $errfile . ' on line ' . $errline);
}
return true;
}
set_error_handler('error_handler');
$request = new Request();
$registry->set('request', $request);
$response = new Response();
$response->addHeader('Content-Type: text/html; charset=utf-8');
$registry->set('response', $response);
$cache = new Cache();
$registry->set('cache', $cache);
$session = new Session();
$registry->set('session', $session);
$languages = array();
$query = $db->query("SELECT * FROM " . DB_PREFIX . "language");
foreach ($query->rows as $result) {
$languages[$result['code']] = $result;
}
$config->set('config_language_id', $languages[$config->get('config_admin_language')]['language_id']);
$language = new Language($languages[$config->get('config_admin_language')]['directory']);
$language->load($languages[$config->get('config_admin_language')]['filename']);
$registry->set('language', $language);
$document = new Document();
$registry->set('document', $document);
$registry->set('currency', new Currency($registry));
$registry->set('weight', new Weight($registry));
$registry->set('length', new Length($registry));
$registry->set('user', new User($registry));
$controller = new Front($registry);
$action = new Action($cli_action);
$controller->dispatch($action, new Action('error/not_found'));
// Output
$response->output();
?>
Using this scheme, I can ensure the script won't be called from the web, and I can have it fired off automatically from the server itself using a cron job (eg: 0 1 0 0 0 /path/to/php /path/to/opencart/cli/cli_some_function.php)
Note that the error_handler function is using some config options that aren't out-of-the-box. You can either set those up or put your own check there.
EDIT made some changes for the error handling
In 2.3.0.2 a very simple way I found was to add your controller function path into the ignored paths settings for login and permission restrictions. Then just add a url password or other check in that controller function to lock it down.
So first in admin/controller/startup/login.php add your controller function path to both $ignore arrays, eg 'common/cron/action'
And then in admin/controller/startup/permissions.php you want just the controller path, eg 'common/cron'
And then finally at start of your action() function do like:
if(!isset($_GET['pass']) || $_GET['pass'] != 'secretpassword')return;
Then i just added this to my cron:
php-cli -r 'echo file_get_contents("https://www.website.com/admin/index.php?route=common/cron/action&pass=secretpassword");'
As I had a similar requirement several times, I put my ideas into a lightweight commandline tool called OCOK.
Especially the Cli Task Command allows you to call Opencart controllers via the commandline and thus lets you call them as cron jobs. Simply create a controller like this and save it as admin/controller/task/example.php:
class ControllerTaskExample extends Controller {
public function index() {
if (isset($this->is_cli) && $this->is_cli === true) {
// work done by the controller
if (isset($this->request->get['param1'])) {
echo "param1 is " . $this->request->get['param1'] . "\n";
}
if (isset($this->request->get['param2'])) {
echo "param2 is " . $this->request->get['param2'] . "\n";
}
}
}
}
Via the commandline it can be called with parameters:
ocok run task/example param1=foo param2=bar
The above stated command would output:
param1 is foo
param2 is bar
Adding this to crontab is as easy as adding the following line to your cron file:
* * * * * (cd /path/to/opencart/folder; /path/to/ocok run task/example param1=foo param2=bar)
the respective paths need to be set correctly of course.
Installation available with composer. All further documentation can be found inside the docs: OCOK
By default opencart doesn't allow to access admin pages without login. The login and token validations are checked in login() method in admin/controller/common/home.php.
it cant be set on frontend coz the model is in admin area. - You may create a new controller and model for frontend with the same functionality in admin panel and use it for cronjob.
Opencart has got usergroups which sets access rights for the users. So the admin pages will not get loaded for the users without permission. Hence you may need to modify the core files very much for setting cronjob in admin panel which may lead to severe security issues.
I suggest a frontend controller and model file for cronjob. For additional security you can pass a particular key parameter in url and write a condition to verify it.
Have a nice day !!
I know this is a very old question, but I spent quite a long time trying to figure how to do the same in opencart version 2.x which works different. So I share here my solution.(based on Mike T approach)
1 - Create cli folder adjacent to admin and catalog.
2 - In this same folder create a file which you will run via cron or comandline, for example runcron.php
#!/usr/bin/php
<?php
require_once('cli_dispatch.php');
3 - In the same folder create the cli_dispatch.php file which is a copy of the index.php file in admin folder with some changes (Note in this is installation there is VQMOD activated, which may not be your case)
<?php
// CLI must be called by cli php
if (php_sapi_name() != 'cli') {
syslog(LOG_ERR, "cli $cli_action call attempted by non-cli.");
http_response_code(400);
exit;
}
// Ensure $cli_action is set
if (!isset($cli_action)) {
echo 'ERROR: $cli_action must be set in calling script.';
syslog(LOG_ERR, '$cli_action must be set in calling script');
http_response_code(400);
exit;
}
// Handle errors by writing to log
function cli_error_handler($log_level, $log_text, $error_file, $error_line) {
syslog(LOG_ERR, 'CLI Error: ' . $log_text . ' in ' . $error_file . ': ' . $error_line);
echo 'CLI Error: ' . $log_text . ' in ' . $error_file . ': ' . $error_line;
}
set_error_handler('cli_error_handler');
// Configuration (note we're using the admin config)
require_once __DIR__.('/../admin/config.php');
// Configuration not present in CLI (vs web)
chdir(__DIR__.'/../admin');
set_include_path(get_include_path() . PATH_SEPARATOR . realpath(dirname(__FILE__)) . '../admin/');
$_SERVER['HTTP_HOST'] = '';
if (!defined('DIR_APPLICATION')) {
echo "ERROR: cli $cli_action call missing configuration.";
http_response_code(400);
exit;
}
// Version
define('VERSION', '2.3.0.3_rc');
// Configuration
if (is_file('config.php')) {
require_once('config.php');
}
// Install
if (!defined('DIR_APPLICATION')) {
header('Location: ../install/index.php');
exit;
}
//VirtualQMOD
require_once('../vqmod/vqmod.php');
VQMod::bootup();
// VQMODDED Startup
require_once(VQMod::modCheck(DIR_SYSTEM . 'startup.php'));
start('cli');
4 - Now create the file upload/system/config/cli.php which will be the one that opencart will use to read the configuration of your new cli bootrasp from file upload/system/framework.php
<?php
// Site
$_['site_base'] = HTTP_SERVER;
$_['site_ssl'] = HTTPS_SERVER;
// Database
$_['db_autostart'] = true;
$_['db_type'] = DB_DRIVER; // mpdo, mssql, mysql, mysqli or postgre
$_['db_hostname'] = DB_HOSTNAME;
$_['db_username'] = DB_USERNAME;
$_['db_password'] = DB_PASSWORD;
$_['db_database'] = DB_DATABASE;
$_['db_port'] = DB_PORT;
// Session
//$_['session_autostart'] = true;
// Autoload Libraries
$_['library_autoload'] = array(
'openbay'
);
// Actions
$_['action_pre_action'] = array(
'startup/startup',
'startup/error',
'startup/event',
'startup/sass',
// 'startup/login',
// 'startup/permission'
);
// Actions
$_['action_default'] = 'sale/croninvoices';
// Action Events
$_['action_event'] = array(
'view/*/before' => 'event/theme'
);
As you can see there i've commented all the Session and Actions lines related to permissions.
You will ave to edit the line
$_['action_default'] = 'sale/yourscript';
changing 'sale/yourscript' with the path and filename of your controller.
In the example, runnunig the runcron.php file will execute the index funcion in
upload/admin/controller/sale/yourscript.php file
In opencart 2.1.0.2.
If you need db in cron job, but DONT need any opencart models.
You can create file system/mycron/cron_task.php.
And add such code to this file:
// CLI
include_once 'config.php';
include_once DIR_SYSTEM.'library/db/mysqli.php';
include_once DIR_SYSTEM.'helper/general.php';
mb_internal_encoding('UTF-8');
if (php_sapi_name() != 'cli') { error_log('NOT CLI CALL');print 'NOT CLI CALL';http_response_code(400);exit; }
$db = new DB\MySQLi(DB_HOSTNAME,DB_USERNAME,DB_PASSWORD,DB_DATABASE,DB_PORT);
// END CLI
// Your actual code, and you CAN use opencart DB!
foreach ($db->query("SELECT * FROM oc_product")->rows as $row) {
//...
}
Now you can run this from your cron job:
12 7 * * * cd /path/to/opencart/root/folder && php system/mycron/cron_task.php
"I want to develop a module to delete any (unpaid) order that exceed the time frame given. Ex : I want to delete any unpaid order that has not been paid for 2 days after the order was placed."
"I want to use existed model in opencart (and not use a new one)."
So, as I'm sure you know, the problem is that you have to be logged in to the admin to access it's controllers and models, but a cron job will not be logged in when it runs.
You could see if the catalog model will do what you need, in which case no problem:
catalog/model/checkout/order.php
You could follow other answers here - i.e. find some way around logging in.
Or you could just write a stand-alone PHP script that runs a simple SQL query.
You're right that it's usually the correct thing to do to use the models of the system BUT OpenCart is so simple that it should be a pretty simple query (just a few lines) that does what you need so that is also an acceptable option in my opinion in this case.
include_once($_SERVER['DOCUMENT_ROOT'].'/admin/model/module/ModelYourModel.php');
$mym = new ModelYourModel($this->registry);
$mym->yourFunction();
For version 2.1, possibly higher. Use the model from the admin folder in the catalog folder.