PHPExcel error when opening downloaded file error "incorrect file format" - zend-framework

I'm creating an Excel report containing UTF-8 encoded data using PHPExcel on Zend. When I'm downloading and trying to open it in Excel it works on local environment but I'm getting the following Error: "Incorrect file format" from live sever/production. Any help / references would be appreciated.
here is a code i used to download xls file:
public function getCsv($data, $filename = false)
{
/**
* generate a file name using unixTimeStamp
* #var string $tmpfname
*/
if ($filename)
{
$tmpfile = "/tmp/".$filename. "-". date('Y-m-d_H:i:s') . ".csv";
$name = str_replace(' ','',$filename)."-".date('Y-m-d_H:i:s') . ".xls";
}
else
{
$tmpfile = "/tmp/report". "_". date('Y-m-d_H:i:s') . ".csv";
$name = "report-".date('Y-m-d_H:i:s') . ".xls";
}
/**
* open Temporary file name in write mode
* #var object $fp
*/
$fp = fopen($tmpfile, "w");
/**
* foreach datas write to csv
*/
foreach ($data as $fields)
fputcsv($fp, $fields, ',', '"');
/**
* close file
*/
fclose($fp);
try
{
$objReader = PHPExcel_IOFactory::createReader('CSV');
$objPHPExcel = $objReader->load($tmpfile);
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
//set Header Content Type as application/csv
header("Content-Type: application/vnd.ms-excel; charset=utf-8");
header("Content-Disposition: attachment; filename=$name");
$objWriter->save('php://output');
}
catch (Exception $e)
{
echo $e->getMessage();
}
exit;
}

You must use this line before saving :
ob_end_clean();

Related

Codeigniter 3 | Copy zip file and extract

I've function for demo import database:
/**
* Demo importer post [Template 01 - Fashion / Clothing]
*/
public function demo_importer_post_template01()
{
$folder_name = 'template01';
$file_name = 'template01.sql';
$path = 'assets/backup_db/'; // Codeigniter application /assets
$file_restore = $this->load->file($path . $folder_name . '/' . $file_name, true);
$file_array = explode(';', $file_restore);
foreach ($file_array as $query)
{
$this->db->query("SET FOREIGN_KEY_CHECKS = 0");
$this->db->query($query);
$this->db->query("SET FOREIGN_KEY_CHECKS = 1");
}
$this->session->set_flashdata('success', trans("msg_updated"));
redirect($this->agent->referrer());
}
This function insert database from /assets/backup_db/template01/template01.sql
This working fine. Now I need with this function extract some static files from: /assets/backup_db/template01/template01.zip
Can anyone help me How to copy template01.zip to root public_html and then unzip files from template01.zip

Typo3 Scheduler - Command Controller: I can't execute a command that uses class repositories of my extension

Yesterday i finally got my Typo3 Scheduler working the way i want. Mostly it was the implementation of the CommandController into my extension that was a little bit "problematic".
Now i have another question regarding the Scheduler and the CommandController specifically. I have the following code. It's an Action i have implemented in the controller of a class of my extension:
public function simpleCommand()
{
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$apprep = $objectManager->get(\Cjk\Icingaconfgen\Domain\Repository\HostRepository::class);
$hosts = $apprep->findAll();
$objectManager2 = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$apprep2 = $objectManager2->get(\Cjk\Icingaconfgen\Domain\Repository\ServicesRepository::class);
$services = $apprep2->findAll();
foreach($hosts as $host)
{
$name = $host->getUid();
$address = $host->getIpv4();
$file = '/etc/icinga2/conf.d/hosts/' . $name . '.conf';
$code_a = 'object Host "';
$code_b = '" {
import "generic-host"
address = "';
$code_c = '"
vars.notification["mail"] = {
groups = [ "icingaadmins" ]
}
}';
$fp = fopen("{$file}", 'wb');
fwrite($fp, $code_a . $name . $code_b . $address . $code_c);
fclose($fp);
mkdir('/etc/icinga2/conf.d/hosts/' . $name);
foreach($services as $service)
{
if($service->getHost() == $name)
{
$name = $host->getUid();
$chkcmd = 'http';
$file = '/etc/icinga2/conf.d/hosts/'.$name.'/' . $name . '-service.conf';
$code_a = 'object Service "';
$code_b = '" {
import "generic-service"
host_name = "';
$code_c = '"
check_command = "http"
}';
$fp = fopen("{$file}", 'wb');
fwrite($fp, $code_a . $name.'-service'. $code_b . $name . $code_c);
fclose($fp);
}
}
exec('sudo /etc/init.d/icinga2 restart');
}
}
This is the way i implemented the code in the CommandController, but in a similar way it is also implementd in my Action in the Class Controller. Now, what this function does is simply generating a specific file i need to use in another application. The function gets the repsitory of the class "Host" and then finds all objects of it. Then it just uses the properties of each object to generate the beforementioned files. It does the same with the class "services".
In the frontend through the Action the code works perfectly and generates the files, but in the CommandController, executed automatically through the Scheduler it simply doesn't work.
Is there a missunderstanding on my side? Can't i access each class repository via a command or rather: "Are the repositories only accessable via an Action?"
Or is there another error?
I guess the reason here, is the difference between frontend and backend context.This answer here, from a different context, sums it up very nice and is worth a read
Basically, in the frontend context, you have the typoscript configuration, telling the repository where to store and find records. That is not present in the backend context. That is explained in the answer above with this code
module.tx_yourext.persistence < plugin.tx_yourext.persistence
As it didn't work with the CommandController for my specific case and i had no access to the persistence layer with with it, not even with dependency injection, i decided to not use CommandContoller tasks at all, but rather the normal Scheduler task for it. The biggest problem i encountered was to actually use the findAll() function for the repositories (it worked with findByUid(). This was because the repository expects a storage page by default. As i don’t have a module nor a plugin, my typoscript settings were ignored in that case.
So i had to set the repository to disrespect the storage page in my task. Here the code:
<?php
namespace Cjk\Icingaconfgen\Tasks;
class TestTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask
{
public function execute() {
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
/** #var CustomerRepository $apprep */
$apprep = $objectManager->get(\Cjk\Icingaconfgen\Domain\Repository\HostRepository::class);
/** #var Typo3QuerySettings $querySettings */
$querySettings = $objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Typo3QuerySettings');
$querySettings->setRespectStoragePage(FALSE);
$apprep->setDefaultQuerySettings($querySettings);
$hosts = $apprep->findAll();
/** #var CustomerRepository $apprep2 */
$apprep2 = $objectManager->get(\Cjk\Icingaconfgen\Domain\Repository\ServicesRepository::class);
/** #var Typo3QuerySettings $querySettings */
$querySettings = $objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Typo3QuerySettings');
$querySettings->setRespectStoragePage(FALSE);
$apprep2->setDefaultQuerySettings($querySettings);
$services = $apprep2->findAll();
foreach($hosts as $host)
{
$name = $host->getUid();
$address = $host->getIpv4();
$file = '/etc/icinga2/conf.d/hosts/' . $name . '.conf';
$code_a = 'object Host "';
$code_b = '" {
import "generic-host"
address = "';
$code_c = '"
vars.notification["mail"] = {
groups = [ "icingaadmins" ]
}
}';
$fp = fopen("{$file}", 'wb');
fwrite($fp, $code_a . $name . $code_b . $address . $code_c);
fclose($fp);
mkdir('/etc/icinga2/conf.d/hosts/' . $name);
foreach($services as $service)
{
if($service->getHost() == $name)
{
$name = $host->getUid();
$chkcmd = 'http';
$file = '/etc/icinga2/conf.d/hosts/'.$name.'/' . $name . '-service.conf';
$code_a = 'object Service "';
$code_b = '" {
import "generic-service"
host_name = "';
$code_c = '"
check_command = "http"
}';
$fp = fopen("{$file}", 'wb');
fwrite($fp, $code_a . $name.'-service'. $code_b . $name . $code_c);
fclose($fp);
}
}
exec('sudo /etc/init.d/icinga2 restart');
}
return TRUE;
}
}

Creating an attachment for MailMessage

From my extbase 6.2 extension I want to send different e-mails.
In a controller class I wrote a mail function that looks like this:
(notice no #param for $attachment - see my question at the end)
/**
*
* #param string $to
* #param string $subject
* #param string $email_prefix
* #param string $msg
* #param string $email_suffix
*/
public function mailAction($to, $subject, $email_prefix, $msg, $email_suffix, $attachment = null) {
try {
$from = \TYPO3\CMS\Core\Utility\MailUtility::getSystemFrom();
$body = $email_prefix
. PHP_EOL . PHP_EOL
. $msg
. PHP_EOL . PHP_EOL
. $email_suffix;
$htmlBody = nl2br($body);
$toEmail = $to;
$mail = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Mail\\MailMessage');
$mail->setFrom($from)
->setTo(array($toEmail))
->setSubject($subject)
->setBody($htmlBody, 'text/html');
$mail->addPart($body, 'text/plain');
if ($attachment) {
$mail->attach($attachment);
}
if (empty($toEmail) || strpos($toEmail, '#') === FALSE) {
$this->addFlashMessage('Die Mail konnte nicht verschickt werden! Keine Email-Adresse des Empfängers', '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR
);
} else {
if ($mail->send()) {
$this->addFlashMessage('Die Mail für wurde verschickt!', '');
} else {
$this->addFlashMessage('Die Mail konnte nicht verschickt werden!', '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR
);
}
}
$this->redirect('list');
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
}
In a function that calls the mail function I tried creating an attachment like this but it failed saying: Fatal error: Class 'Swift_Attachment' not found in.../...Controller.php
$attachment = \Swift_Attachment::newInstance()
->setFilename('Termine.html')
->setContentType('text/html')
->setBody($emailView->render());
Then I call the mail function like this:
$this->redirect('mail', null, null, array(
$to,
$subject,
$email_prefix,
$msg,
$email_suffix,
$attachment));
My questions:
How can I successfully create an object of type Swift_Attachment in a controller of my extbase extension (without creating a MailMessage object beforehand and creating the attachment inside of it)?
What should I put after #param as the type of my $attachment variable in my mail function for this to work?
-- EDIT --
Ok, so apparently no one does that because it's not meant to be.
I now used Rene's approach combining it with Dimitri's scalable answer for multiple attachments. My #param is now array because I have to create the actual attachment after instantiating MailMessage - thanks!
In my extension for 6.2.25 ist works without any including:
$email->attach(\Swift_Attachment::newInstance(
$emailView->render(),
'Termine.html',
'text/html'
));
So you should check why your autoload of classes don't work. Have you tried to clear the cache complete?
To your second question: the correct param declaration should be:
#param \Swift_Mime_Attachment $attachment
But I wouldn't make an redirect, but an $this->forward. You don't need an redirection on client side for this. If this action is only called by an other action I also recommend to make it an protected function an call it directly from your action:
$this->sendMail($to, $subject, $email_prefix, $msg, $email_suffix, $attachment)
-- EDIT --
I recommend to use bypass the attachment information to the function to create the attachment object after the SwitftMailer was initialized:
/**
*
* #param string $to
* #param string $subject
* #param string $email_prefix
* #param string $msg
* #param string $email_suffix
* #param array $attachment
*/
public function mailAction($to, $subject, $email_prefix, $msg, $email_suffix, $attachment = null) {
...
if (is_array($attachment) && array_key_exist('content', $attachment) && array_key_exist('filename', $attachment) && array_key_exist('mime', $attachment)) {
$mail->attach(\Swift_Attachment::newInstance($attachment['content'], $attachment['filename'], $attachment['mime']));
}
...
}
In \TYPO3\CMS\Core\Mail\MailMessage there is a require_once for the swiftmailer classes; they don't seem to be autoloaded. Maybe you can pass the attachment as rendered HTML and create the Swift_Attachment object after instantiating the MailMessage object?
If the solution in 1. works it would be a simple string.
As already stated by Jigal van Hemert you can only create the attachment objects after you create the MailMessage object because the class is not autoloaded. I would just pass the attachment as a filepath to your mail function and it should be handled there and not outside.
if ($attachment) {
$email->attach(\Swift_Attachment::fromPath($attachment));
}
In my opinion it makes more sense if you can pass multiple files instead of one, so the $attachment should be an $attachments array
if(count($attachments)) {
foreach ($attachments as $name => $file) {
if(file_exists($file)) {
if(trim($name) && !is_numeric($name)) {
$email->attach(\Swift_Attachment::fromPath($file)->setFilename($name));
} else {
$email->attach(\Swift_Attachment::fromPath($file));
}
}
}
}

How to inserting data from install.xml file into mysql database in moodle

In moodle site (use moodle Version 2.6.3), I have generated install.xml file by XMLDB editor, but it's use only to create table in database during plugin installation. I want to insert some default rows in the table also.
Any body can help me how to edit in install.xml file for insert data
To add data after an install, create a file called yourplugin/db/install.php with
UPDATE: added xml parser
defined('MOODLE_INTERNAL') || die;
require_once($CFG->libdir . '/xmlize.php');
function xmldb_yourpluginname_install() {
global $CFG, $OUTPUT, $DB;
// Your add data code here.
$xmltext = file_get_contents('import.xml');
$records = parse_xml($xmltext, 'records', 'record');
foreach ($records as $record) {
$DB->insert_record('yourtablename', $record);
}
}
/**
* Converts XML text into an array of stdclass objects.
*
* #param type $text - xmltext
* #param type $elementnames - plural name of elements
* #param type $elementname - name of element
* #return array|boolean - array of record objects
*/
function parse_xml($text, $elementnames, $elementname) {
// Seems that xmlize needs a lot of memory.
ini_set('memory_limit', '256M');
// Ensure content is UTF-8.
$content = xmlize($text, 1, 'UTF-8');
$records = array();
if (!empty($content[$elementnames]['#'][$elementname])) {
$rows = $content[$elementnames]['#'][$elementname];
foreach ($rows as $row) {
$fields = $row['#'];
$row = new stdClass();
foreach ($fields as $fieldname => $fieldvalue) {
$row->$fieldname = $fieldvalue[0]['#'];
}
$records[] = $row;
}
return $records;
}
return false;
}

Fatal error: Call to a member function prepare() on a non-object in mysqlicon.php on line 62 Help explain OOP mysqli classes and prepared statements [duplicate]

This question already has answers here:
Call to a member function on a non-object [duplicate]
(8 answers)
Closed 10 years ago.
I'm hesitant to post this, as I'd really prefer to figure this out myself, but I don't think I will. I'm just trying to set a class for mysqli stuff, to make it as dynamic as possible, and yes I'm newer to OOP, but have been using PHP and Mysql as a hobby, and more heavily lately, for quite some time. I figured it was time to switch, but there just isn't that much on oop classes with mysqli and prepared statements with a possibility of multiple results (yes I've check documentation, guess I'm just not getting it or something). After quite a few hours, this is what I have. I'm not necessarily looking for a "quick fix". I really want to understand this and learn, so please explain thoroughly.
I'm using a dbconfig.php file to store my database info at root/config/dbconfig.php
in root/classes/mysqlicon.php
<?php
/*
* class MYSQLIDB
* #param Host
* #param User
* #param Password
* #param Name
*/
class MYSQLIDB
{
private $host; //MySQL Host
private $user; //MySQL User
private $pass; //MySQL Password
private $name; //MySQL Name
private $mysqli; //MySQLi Object
private $last_query; //Last Query Run
/*
* Class Constructor
* Creates a new MySQLi Object
*/
public function __construct()
{
include('./config/dbconfig.php');
$this->host = $db_host;
$this->user = $db_user;
$this->pass = $db_pass;
$this->name = $db_name;
$this->mysqli = new mysqli($this->host, $this->user, $this->pass, $this->name);
if ($mysqli->connect_errno) {
return "Failed to connect to MySQLi: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
}
private function __destruct()
{
$mysqli->close();
}
public function select($fields, $from, $where, $whereVal, $type, $orderByVal, $ASDESC, $limitVal)
{
if (is_int($whereVal))
{
$bindVal = 'i';
} else {
$bindVal = 's';
}
switch($type)
{
case "regular":
$queryPre = "SELECT " . $fields;
$querySuff = " WHERE " . $where . " = ?";
break;
case "orderByLimit":
$queryPre = "SELECT " . $fields;
$querySuff = " ORDER BY " . $orderByVal . " " . $ASDESC . " LIMIT " . $limitVal;
break;
}
//$query = "SELECT * FROM news ORDER BY id DESC LIMIT 4";
if ($stmt = $mysqli->prepare('$queryPre . " FROM " . $from . " " . $querySuff'))
{
if ($type == 'regular') {
$stmt->bind_param($bindVal, $whereVal);
}
$stmt->execute();
$stmt->bind_result($values);
$stmt->store_result();
$sr = new Statement_Result($stmt);
$stmt->fetch();
// call by this style printf("ID: %d\n", $sr->Get('id') );
//$stmt->fetch();
//$stmt->close();
//return $value;
printf("ID: %d\n", $sr->Get_Array() );
} else return null;
}
//use to call $db = new MYSQLI('localhost', 'root', '', 'blog');
/*
* Function Select
* #param fields
* #param from
* #param where
* #returns Query Result Set
function select($fields, $from, $where, $orderBy, $ASDESC, $limit, varNamesSent)
{
if ($orderBy == null &&)
$query = "SELECT " . $fields . " FROM `" . $from . "` WHERE " . $where;
$result = $this->mysqli->query($query) or exit("Error code ({$sql->errno}): {$sql->error}");
$this->last_query = $query;
return $result;
}
/*
* Function Insert
* #param into
* #param values
* #returns boolean
*/
public function insert($into, $values)
{
$query = "INSERT INTO " . $into . " VALUES(" . $values . ")";
$this->last_query = $query;
if($this->mysqli->query($query))
{
return true;
} else {
return false;
}
}
/*
* Function Delete
* #param from
* #param where
* #returns boolean
*/
public function delete($from, $where)
{
$query = "DELETE FROM " . $from . " WHERE " . $where;
$this->last_query = $query;
if($this->mysqli->query($query))
{
return true;
} else {
return false;
}
}
}
//Hand arrays for multiple returned items from database
class Statement_Result
{
private $_bindVarsArray = array();
private $_results = array();
public function __construct(&$stmt)
{
$meta = $stmt->result_metadata();
while ($columnName = $meta->fetch_field())
$this->_bindVarsArray[] = &$this->_results[$columnName->name];
call_user_func_array(array($stmt, 'bind_result'), $this->_bindVarsArray);
$meta->close();
}
public function Get_Array()
{
return $this->_results;
}
public function Get($column_name)
{
return $this->_results[$column_name];
}
}
?>
And just as a test, I'm trying to pull all the news in my db by:
<?php
require_once('classes/mysqlicon.php');
$testing = new MYSQLIDB;
$testing->select('*','news',null,null,'orderByLimit','id','DESC',4);
?>
But what I really want is stuff that can do the equivalent of this:
<?php
/*
require('config/dbconfig.php');
$query = "SELECT * FROM news ORDER BY id DESC LIMIT 4";
if ($stmt = $mysqli->prepare($query)) {
// execute statement
$stmt->execute();
// bind result variables
$stmt->bind_result($idn, $titlen, $categoryn, $descn, $postdaten, $authorn);
// fetch values
while ($stmt->fetch()) {*/
//echo 'id: '. $id .' title: '. $title;
echo "<table border='0'>";
$shortDescLengthn = strlen($descn);
if ($shortDescLengthn > 106) {
$sDCutn = 106 - $shortDescLengthn;
$shortDescn = substr($descn, 0, $sDCutn);
} else {
$shortDescn = $descn;
}
echo "<h1>$titlen</h1>";
echo "<tr><td>$shortDescn...</td></tr>";
echo '<tr><td><a href="javascript:void(0);" onclick="'
. 'readMore(' . $idn . ',' . htmlspecialchars(json_encode($titlen)) . ','
. htmlspecialchars(json_encode($categoryn)) . ','
. htmlspecialchars(json_encode($descn)) . ',' . htmlspecialchars(json_encode($postdaten)) . ','
. htmlspecialchars(json_encode($authorn)) . ')">Read More</a></td></tr>';
echo "<tr><td>Written by: $authorn</td></tr>";
echo '<tr><td><img src="images/hardcore-games-newsbar-border.png" width="468px" /></td></tr>';
}
echo "</table><br />";
/* close statement */
$stmt->close();
}
/* close connection */
$mysqli->close();
?>
Again, please, please explain in detail. I'm a blockhead sometimes.
I'm assuming the error is coming from this line:
if ($stmt = $mysqli->prepare('$queryPre . " FROM " . $from . " " . $querySuff'))
$mysqli is not defined in the context of this function. You should be accessing $this->mysqli instead. The same applies to other references you have made such as here:
if ($mysqli->connect_errno)