I'm trying to export data to ms excel, I have Office 2010 student edition for my application by following Pablo Viquez's post http://www.pabloviquez.com/2009/08/export-excel-spreadsheets-using-zend-framework/.
However I can't get it working the following happens
1.On entering reports/report/todaysappointmentsreport/format/excel into the address bar the workbook attempts to save as excel.xls
2.When I open the file Excel gives me the following warning: The file you are trying to open 'excel.xls', is in a different format than specified by the file extension verify the file is not corrupt and is from a trusted source before opening the file.
On opening the file all that is shown is the code in my todaysappointmentsreport.export.phtml file
Can anyone tell me where I'm going wrong, as I need to get this working.
I can verify that the query works and the data appears in my todaysappointmentsreport.phtml file on screen. I can also verify that the component is installed in pear along with the OLE component that it is dependent on.
My Controller code
class Reports_ReportController extends Zend_Controller_Action
{
public function init()
{
// Excel format context
$excelConfig =
array('excel' => array
('suffix' => 'excel',
'headers' => array(
'Content-type' => 'application/vnd.ms-excel')),
);
//initalise context switch
$contextSwitch = $this->_helper->contextSwitch();
// Add the new context
$contextSwitch->setContexts($excelConfig);
// Set the new context to the reports action
$contextSwitch->addActionContext('todaysappointmentsreport', 'excel');
$contextSwitch->initContext();
}
// action to redirect user straight to login page
public function preDispatch()
{
// set admin layout
// check if user is authenticated
// if not, redirect to login page
$url = $this->getRequest()->getRequestUri();
if (!Zend_Auth::getInstance()->hasIdentity()) {
$session = new Zend_Session_Namespace('petmanager.auth');
$session->requestURL = $url;
$this->_redirect('/login');
}
}
// report to print todays appointments
public function todaysappointmentsreportAction()
{
$t=date('y-m-d');
$q = Doctrine_Query::create()
->from('PetManager_Model_Groomappointments g')
->leftJoin('g.PetManager_Model_Clients c')
->leftJoin('g.PetManager_Model_Pets p')
->leftJoin('g.PetManager_Model_Users u')
->leftJoin('g.PetManager_Model_Groomservices s')
->leftJoin('s.PetManager_Model_Groomprocedures r')
->where('g.gapmtStatus = 1 AND g.gapmtDate = ?',$t)
->orderBy('g.gapmtSTime,g.gapmtSTime,u.name');
$result = $q->fetchArray();
if (count($result) >= 1) {
$this -> view -> records = $result;
}
}
My todaysappointmentsreport.excel.phtml code as I said this is what appears in the excel file when I open it.
// Change error reporting for compatibility
// Spreadsheet Excel Writter was built using PHP4,
// so there's a lot of DEPRECATED notices
error_reporting(E_ERROR | E_WARNING | E_PARSE);
/**
* PEAR package
*
* #link http://pear.php.net/package/Spreadsheet_Excel_Writer
* #see PEAR/Spreadsheet/Excel/Writer.php
*/
require_once 'Spreadsheet/Excel/Writer.php';
// Lets define some custom colors codes
define('CUSTOM_DARK_BLUE', 20);
define('CUSTOM_BLUE', 21);
define('CUSTOM_LIGHT_BLUE', 22);
define('CUSTOM_YELLOW', 23);
define('CUSTOM_GREEN', 24);
// First, we create a Workbook
$workbook = new Spreadsheet_Excel_Writer();
// Add one sheet, called: Users Report
$worksheet = &$workbook->addWorksheet('Todays Grooming Appointments Report');
// Create the custom colors on our new workbook
// This function takes 4 params:
// - Code index [1 to 64]
// - RGB colors (0-255)
$workbook->setCustomColor(CUSTOM_DARK_BLUE, 31, 73, 125);
$workbook->setCustomColor(CUSTOM_BLUE, 0, 112, 192);
$workbook->setCustomColor(CUSTOM_LIGHT_BLUE, 184, 204, 228);
$workbook->setCustomColor(CUSTOM_YELLOW, 255, 192, 0);
$workbook->setCustomColor(CUSTOM_GREEN, 0, 176, 80);
// Lets hide gridlines
//$worksheet->hideScreenGridlines();
// Lets create some custom styles
$formatHeader = &$workbook->addFormat();
$formatHeader =
&$workbook->addFormat(
array('Size' => 16,
'VAlign' => 'vcenter',
'HAlign' => 'center',
'Bold' => 1,
'Color' => 'white',
'FgColor' => CUSTOM_DARK_BLUE));
$formatReportHeader =
&$workbook->addFormat(
array('Size' => 9,
'VAlign' => 'bottom',
'HAlign' => 'center',
'Bold' => 1,
'FgColor' => CUSTOM_LIGHT_BLUE,
'TextWrap' => true));
$formatData =
&$workbook->addFormat(
array(
'Size' => 8,
'HAlign' => 'center',
'VAlign' => 'vcenter'));
/**
* First, format the worksheet, adding the headers
* and row/columns custom sizes
*/
// Create a nice header with a dark blue background
// The function setRow takes 3 parameters:
// - row index
// - row height
// - Format to apply to row [Optional]
$worksheet->setRow(0, 11, $formatHeader);
$worksheet->setRow(1, 46, $formatHeader);
$worksheet->setRow(2, 11, $formatHeader);
$worksheet->setRow(3, 11, $formatHeader);
$worksheet->setRow(4, 11, $formatHeader);
// Set the size of the columns
// The function setColumn takes 5 params:
// - First column
// - Last column
// - Column Width
// - Format [Optional, default = 0]
// - Hidden [Optional, default = 0]
$worksheet->setColumn(0, 0, 7); // shrink it to 7
$worksheet->setColumn(1, 1, 12); // set the width to 12
$worksheet->setColumn(1, 1, 15); // set the width to 15
$worksheet->setColumn(1, 1, 15); // set the width to 15
$worksheet->setColumn(1, 1, 15); // set the width to 15
/**
*
* Once we have the format ready, add the text to the spreadsheet
*
*/
// Write a text header
$worksheet->write(1, 1, 'Todays Grooming Appointments Report', $formatHeader);
// Create the header for the data starting # row 6
$indexCol = 0;
$indexRow = 6;
$worksheet->write($indexRow, $indexCol++, 'Scheduled Time', $formatReportHeader);
$worksheet->write($indexRow, $indexCol++, 'Client', $formatReportHeader);
$worksheet->write($indexRow, $indexCol++, 'Pet', $formatReportHeader);
$worksheet->write($indexRow, $indexCol++, 'Procedure', $formatReportHeader);
$worksheet->write($indexRow, $indexCol++, 'Groomer', $formatReportHeader);
$indexRow++; // Advance to the next row
$indexCol = 0; // Start # column 0
// Print the report data
if(count($this->records) == 0) {
// No data
$worksheet->write(
$indexRow,
$indexCol,
'No Appointments',
$formatData);
} else {
// Write the data
foreach ($this->records as $r) {
$worksheet->write(
$indexRow,
$indexCol++,
$this->$r['gapmtSTime'] - $this->substr$r['gapmtETime'],
$formatData);
$worksheet->write(
$indexRow,
$indexCol++,
$this->$r['PetManager_Model_Clients']['firstName'] $this->$r ['PetManager_Model_Clients']['lastName'],
$formatData);
$worksheet->write(
$indexRow,
$indexCol++,
$this->$r['PetManager_Model_Pets']['name'],
$formatData);
$worksheet->write(
$indexRow,
$indexCol++,
$this->$r['PetManager_Model_Groomservices']['PetManager_Model_Groomprocedures']['groomprocedure'],
$formatData);
$worksheet->write(
$indexRow,
$indexCol++,
$this->$r['PetManager_Model_Users']['name'],
$formatData);
// Advance to the next row
$indexRow++;
}
}
/**
*
* Response with the excel file
*
*/
// Sends HTTP headers for the Excel file.
$workbook->send('todaysappointmentsreport.xls');
// Calls finalization methods.
// This method should always be the last one to be called on every workbook
$workbook->close();
Ensure the content of your "todaysappointmentsreport.excel.phtml" view file is enclosed in php opening and closing tags.
public function indexAction()
{
$this->filename = "/excel-" . date( "m-d-Y" ) . "-".mt_rand(10000,20000).".xls";
$realPath = realpath($this->filename);
if (false === $realPath )
{
touch($this->filename);
chmod($this->filename, 0777);
}
$this->filename = realpath( $this->filename );
$this->handle = fopen( $this->filename, "w" );
$projectsModul = new Model_DbTable_Projects();
$projects = $projectsModul->fetchProjects();
foreach ($projects->toArray() as $row)
{
$this->finalData[] = array(
$row['id'],
$row['company'],
$row['project'],
$row['start'],
$row['end']
);
}
foreach ( $this->finalData AS $finalRow )
{
fputcsv( $this->handle, $finalRow, "\t" );
}
fclose( $this->handle );
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
$this->getResponse()->setRawHeader( "Content-Type: application/vnd.ms-excel; charset=UTF-8")
->setRawHeader("Content-Disposition: attachment; filename=excel.xls")
->setRawHeader("Content-Transfer-Encoding: binary")
->setRawHeader("Expires: 0")
->setRawHeader("Cache-Control: must-revalidate, post-check=0, pre-check=0")
->setRawHeader("Pragma: public")
->setRawHeader("Content-Length: " . filesize($this->filename))
->sendResponse();
readfile($this->filename);
exit();
}
I'm working on a similar example for my own project so if I discover a resolution I'll update this thread with any results.
There's a helpful article on the contextSwitch view helper here (maltblue) which explains the helper in more depth.
contextswitch view helper
I managed to export to csv ok in the end by putting the headers in the controller action directly as follows.
in my action...
//create the csv file header and filename based on the action name
$actionName = $this->getRequest()->getActionName();
new Admin_Model_Resource_csvFileHeader( $actionName );
rest of code here to get the data to pass to the view file...
the admin model resource is as follows so it can be used by any controller acton...
class Admin_Model_Resource_csvFileHeader
{
private $_csvFileNameFromAction = null;
/**
* Create the first part of the csv file name from the action name
* #param <string> $actionName - name of the controller action for the report
*/
public function __construct( $actionName )
{
$this->_csvFileNameFromAction = $actionName;
$this->generateCsvHeader();
}
/**
* Method is called direct from the constructor
* to centralise and make consistent the csv file header
* so it maximises code re-use
* #return null - just generate the csv header
*/
public function generateCsvHeader()
{
$dateSuffix = date('d-m-Y', time());
$csvFileName = $this->_csvFileNameFromAction.'_'.$dateSuffix;
header('Content-Type: text/x-csv; name="'.$csvFileName.'.csv"');
header('Content-Disposition: inline; filename="'.$csvFileName.'.csv"');
header('Pragma: public');
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: pre-check=0, post-check=0, max-age=0');
header('Content-Transfer-Encoding: none');
}
}
Related
I'm working on a project that uses the Spotify API. I get all the top tracks and top artists from users. I save the information into my database, the image that I get from Spotify is a URL image. Like this https://i.scdn.co/image/ab67616d0000b27300d5163a674cf57fe79866a6
In my CMS I want to be able to change the image of an artist or track. For this, I copied the code from the docs https://backpackforlaravel.com/docs/4.1/crud-fields#image-1 "public function setImageAttribute($value) and put this in my model. Everything is working fine for this part, I can upload a new image and it saves into my public folder and gets displayed in my table.
The problem that I have is that when a new user logs in and the artist/track data needs to be saved in the database it goes through this setImageAttribute($value) in the model and doesn't add the URL into the database column.
Is there a way that I can add the URL image without going through the setImageAttribute function in the model?
The controller:
//get Top Artists
$client = new Client([]);
$topartists = $client->get('https://api.spotify.com/v1/me/top/artists?time_range=medium_term&limit=25&offset=5', [
'headers' => [
'Authorization' => 'Bearer ' . $token,
],
]);
$listtopartists = json_decode($topartists->getBody(), true);
$p = 25;
foreach ($listtopartists['items'] as $topartist) {
$artist = TopArtist::where('artist_id', $topartist['id'])->first();
$artist_genre = json_encode($topartist['genres']);
if ($artist === null) {
$new_artist = TopArtist::create([
'artist_id' => $topartist['id'],
'name' => $topartist['name'],
'genres' => $artist_genre,
'users_popularity' => $p,
'popularity' => $topartist['popularity'],
'image' => $topartist['images'][0]['url'],
'url' => $topartist['external_urls']['spotify'],
]);
$spotify_user->topArtists()->attach($new_artist->id);
} else {
$exists = $spotify_user->topArtists()->where('spotify_user_id', $spotify_user->id)->where('top_artist_id', $artist->id)->get();
if ($exists->isEmpty()) {
$spotify_user->topArtists()->attach($artist->id);
}
}
$p--;
}
The Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
class TopArtist extends Model
{
use \Backpack\CRUD\app\Models\Traits\CrudTrait;
use HasFactory;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'artist_id',
'name',
'popularity',
'users_popularity',
'url',
'image',
'genres',
'status',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'id' => 'integer',
'status' => 'boolean',
];
public function setImageAttribute($value)
{
$attribute_name = "image";
// or use your own disk, defined in config/filesystems.php
$disk = config('backpack.base.root_disk_name');
// destination path relative to the disk above
$destination_path = "public/storage/artists";
// if the image was erased
if ($value==null) {
// delete the image from disk
\Storage::disk($disk)->delete($this->{$attribute_name});
// set null in the database column
$this->attributes[$attribute_name] = null;
}
// if a base64 was sent, store it in the db
if (Str::startsWith($value, 'data:image'))
{
$image = \Image::make($value)->encode('jpg', 90);
$filename = md5($value.time()).'.jpg';
\Storage::disk($disk)->put($destination_path.'/'.$filename, $image->stream());
\Storage::disk($disk)->delete($this->{$attribute_name});
$public_destination_path = Str::replaceFirst('public/', '', $destination_path);
$this->attributes[$attribute_name] = $public_destination_path.'/'.$filename;
}
}
public function spotifyUsers()
{
return $this->belongsToMany(\App\Models\SpotifyUser::class);
}
}
I fixed it, I had to add an else statement after
if (Str::startsWith($value, 'data:image'))
in the model where I set $this->attributes[$attribute_name] = $value;.
I have a script which adds a product in cart with custom option image and it was working perfect till CE 1.9.2.1 but after up gradation to latest version it troughs exception that Please specify the product's required option(s).
Below is code, please guide me if something has to change for newer version .
<?php
$productId = xxx;
$image = 'path to image(tested image exists)';
$product = Mage::getModel('catalog/product')->load($product_id);
$cart = Mage::getModel('checkout/cart');
$cart->init();
$params = array(
'product' => $productId,
'qty' => 1,
'options' => array(
$optionId3inmycase => array(
'type' => 'image/tiff',
'title' => $image,
'quote_path' => '/media/custom/' . $image,
'order_path' => '/media/custom/' . $image,
'fullpath' => Mage::getBaseDir() . '/media/custom/' . $image,
'secret_key' => substr(md5(file_get_contents(Mage::getBaseDir() . '/media/custom/' . $image)), 0, 20)),
)
);
$request = new Varien_Object();
$request->setData($params);
$cart->addProduct($product, $request);
$cart->save();
if ($itemId > 0) {
$cartHelper = Mage::helper('checkout/cart');
$cartHelper->getCart()->removeItem($itemId)->save();
}
Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
$this->_redirect('checkout/cart/');
?>
One quick solution is to rewrite Mage_Catalog_Model_Product_Option_Type_File class and change validateUserValue() function.
around line 129, replace
$fileInfo = $this->_getCurrentConfigFileInfo();
with
$fileInfo = null;
if (isset($values[$option->getId()]) && is_array($values[$option->getId()])) {
// Legacy style, file info comes in array with option id index
$fileInfo = $values[$option->getId()];
} else {
/*
* New recommended style - file info comes in request processing parameters and we
* sure that this file info originates from Magento, not from manually formed POST request
*/
$fileInfo = $this->_getCurrentConfigFileInfo();
}
but its old code and will have APPSEC-1079 security issue.
and to download image this uploaded image in order detail etc. add this function in same model class.
/**
* changed the image save address as we are saving image in custom
* Main Destination directory
*
* #param boolean $relative If true - returns relative path to the webroot
* #return string
*/
public function getTargetDir($relative = false)
{
$fullPath = Mage::getBaseDir('media') . DS . 'custom';
return $relative ? str_replace(Mage::getBaseDir(), '', $fullPath) : $fullPath;
}
i'll try to upload a file (or later multiple files) in FE. This works, like my current code. But how can i get a file reference of this file now?
/**
*
* #var array $fileData
* #var integer $feUserId
* #return \TYPO3\CMS\Extbase\Domain\Model\FileReference
*/
private function uploadFile($fileData, $feUserId) {
$storageRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\StorageRepository');
$storage = $storageRepository->findByUid(1); # Fileadmin = 1
$saveFolder = $storage->getFolder($this->settings['uploadFolder']);
// Datei speichern
$fileObject = $storage->addFile($fileData['tmp_name'], $saveFolder, $feUserId.'_'.$fileData['name']);
// Dateiobjekt
$repositoryFileObject = $storage->getFile($fileObject->getIdentifier());
die(\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($repositoryFileObject));
#$newFileReference = $this->objectManager->get('TYPO3\CMS\Extbase\Domain\Model\FileReference');
#$newFileReference->setOriginalResource($repositoryFileObject);
return $newFileReference;
}
There should be something like »setFileReference« by now, but I can not find the like in the API http://typo3.org/api/typo3cms/class_t_y_p_o3_1_1_c_m_s_1_1_core_1_1_resource_1_1_file_reference.html
Well, you may wanna use the following script as temporary solution, which uses the datamap process to create file references.
$sys_file_uid = $file->getUid();
$tt_content_uid = 42;
$tt_content_pid = 1337;
// Do not directly insert a record into sys_file_reference, as this bypasses all sanity checks and automatic updates done!
$data = array();
$data['sys_file_reference']['NEW' . $sys_file_uid] = array(
'uid_local' => $sys_file_uid,
'table_local' => 'sys_file',
'uid_foreign' => $tt_content_uid,
'tablenames' => 'tt_content',
'fieldname' => 'image',
'pid' => $tt_content_pid,
);
$data['tt_content'][$tt_content_uid] = array('image' => 'NEW' . $sys_file_uid);
$tce = t3lib_div::makeInstance('t3lib_TCEmain'); // create TCE instance
$tce->start($data, array());
$tce->process_datamap();
if ($tce->errorLog) {
// Error - Reference not created
// t3lib_utility_Debug::viewArray($tce->errorLog);
}
else {
// Success - Reference created
}
after hitting google for a while i figured out a article that sounded quite well to me.. gonna examine it tomorrow:
http://insight.helhum.io/post/85015526410/file-upload-using-extbase-and-fal-in-typo3-6-2
(just in case somebody else needs this before i could test it)
I want to remove out the datagrid export option ('pdf', 'csv','excel','word' etc..) for some
specific table in the datagrid of zend framework . Its now by default coming for every
table attached to the project , How can i do this ? Thanks . posting the code of the datagrid
helper below
public function dataGrid($sql){
$this->view->headLink()->appendStylesheet($this->view->baseUrl('grid/styles/styles.css'));
$this->view->setEncoding('ISO-8859-1');
$config = new Zend_Config_Ini(APPLICATION_PATH. '/configs/grid.ini', 'production');
$grid = Bvb_Grid::factory('Table', $config, 'grid');
$grid->setExport(array());
$backendName = Zend_Cache::$standardBackends[0];
$frontendName = Zend_Cache::$standardFrontends[0];
$frontendOptions = array('automatic_serialization'=> true);
$backendOptions = array('auto_refresh_fast_cache'=> true);
$cache = Zend_Cache::factory($frontendName,
$backendName,$frontendOptions,$backendOptions);
$grid->setExport(array('pdf', 'csv','excel','word'));
$grid->addFiltersRenderDir(APPLICATION_PATH.'/views/helpers/Filters/', 'Filters');
$grid->setPaginationInterval(array(100 =>100, 200 => 200, 500 => 500, 1000 => 1000));
$grid->setUseKeyEventsOnFilters(true);
$grid->query($sql);
return $grid;
}
$grid->setGridColumns($grid_columns);
$grid->setExport(array());
$gd = $grid->deploy();
You can set the export option into null by passing a null array to the setExport function
In my custom plugin I am simply using three drop down and one text box. When I submit the form and validation($data) method is invoked I just get value of state drop down along with the textbox value.
Value of other two drop downs is not returned. I am not sure what I am missing.
Here is my code:
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
require_once($CFG->libdir.'/formslib.php');
class ohio_addconfiguration_form extends moodleform {
// Define the form
function definition() {
$id = optional_param('id', 0, PARAM_INT);
$countries = array();
$states = array();
$counties = array();
$cities = array();
$mform =& $this->_form;
// Creating hidden variable id
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);
// Creating header "Configuration"
$mform->addElement('header', 'configuration', get_string('ohio', 'local_ohio'));
/* Listing States */
$states_result = $this->get_states("", "1", "id, state_name", "state_name ASC");
if($states_result) {
foreach($states_result as $key=>$state){
$states[$state->id] = $state->state_name;
}
}
$states= count($states)?array(''=>get_string('select_state', 'local_ohio').'...') + $states :array(''=>get_string('select_state', 'local_ohio').'...');
$mform->addElement('select', 'state_id', get_string('select_state', 'local_ohio'), $states);
$mform->addRule('state_id', get_string('required'), 'required', null, 'client');
$mform->setType('state_id', PARAM_INT);
/* Listing Counties */
$counties= array(''=>get_string('select_county', 'local_ohio').'...');
$mform->addElement('select', 'county_id', get_string('select_county', 'local_ohio'), $counties);
$mform->addRule('county_id', get_string('required'), 'required', null, 'client');
$mform->setType('county_id', PARAM_INT);
/* Listing Cities */
$cities= array(''=>get_string('select_city', 'local_ohio').'...');
$mform->addElement('select', 'city_id', get_string('select_city', 'local_ohio'), $cities);
$mform->addRule('city_id', get_string('required'), 'required', null, 'client');
$mform->setType('city_id', PARAM_INT);
// Creating text box for School
$mform->addElement('text', 'school_name', get_string('school_name', 'local_ohio'), 'size="25"');
$mform->setType('school_name', PARAM_TEXT);
$mform->addRule('school_name', get_string('required'), 'required', null, 'client');
$mform->addRule('school_name', get_string('maximumchars', '', 100), 'maxlength', 100, 'client');
$this->add_action_buttons();
}
function validation($data) {
global $DB;
echo "<pre>";
print_r($data);
exit;
}
}
I'm not sure what are you looking for exactly, either form validation or data retrieval, but I'm assuming you're interested in data retrieval and the code you have provided above is written in 'filename_form.php'.
The validation() method is used to validate the data entered in the fields on the server side, and not to get the values of the fields.
To get the values of the fields, you need to create another file named 'filename.php', and include 'filename_form.php' in it for displaying the form.
You can refer here for using Formslib.