Hi have a function in app\code\core\Mage\Downloadable\Block\Adminhtml\Catalog\Product\Edit\Tab\Downloadable\Links.php
that its called when a user in admin panel enters in a downloadable product in catalog > product
The function its
public function getConvertPDF(){
$_prodId = $this->getProduct()->getId();
/*Validate if the product exist */
if ($_prodId){
$_proFile =$this->getLinkFile();
$product = Mage::registry('current_product');
if ($product->getTypeId() == 'downloadable') {
$table = Mage::getModel('downloadable/link');
$collection = $table->getCollection()->addProductToFilter($product->getId());
foreach ($collection as $downloadable){
$linkFile = $downloadable->getLinkFile();
break;
}
$_proFile = $linkFile;
}
$extencion = '.jpg';
$path= 'C:/wamp/www/magento/media/downloadable/files/links';
$pathout= 'C:/wamp/www/magento/media/catalog/product/small/';
$test ='/small/';
exec('convert '.$path.$_proFile.'[0] '.$pathout.$_prodId.$extencion);
/*-------------------------------------------------**/
$resource = Mage::getSingleton('core/resource');
$adapter = $resource->getConnection('write');
$bind = array(
'value' => $test.$_prodId.$extencion
);
$where = array(
'entity_id = ?' => $_prodId,
'attribute_id = ?' => 86
);
$adapter->update($resource->getTableName('catalog_product_entity_varchar'), $bind, $where);
}
}
I saw a tutorial and they dont recomend to edit the core ...
so my question its if there is way to make the same behavior , placing this function in other play ,
how should be the procedure?
Functions in magento can be override by creating the functionallity of core in local...
for example in these case
app\code\ local\Mage\Downloadable\Block\Adminhtml\Catalog\Product\Edit\Tab\Downloadable\Links.php
Update
The function should extends the core .. for example
extends Mage_Adminhtml_Block_Template
Related
I need to create a query log in my project. So I created a post_controller hook. It saves all the executed queries in both a text file and a database. But it works only for SELECT queries. I know it is repeated question, but after a lot of search, I couldn't find solution.
Here is my code:
config/hooks.php:
$hook['post_controller'] = array(
'class' => 'LogQueryHook',
'function' => 'log_queries',
'filename' => 'log_queries.php',
'filepath' => 'hooks'
);
hooks/log_queries.php
class LogQueryHook {
function log_queries() {
$CI =& get_instance();
$times = $CI->db->query_times;
//$dbs = array();
$output = NULL;
$queries = $CI->db->queries;
//print_r($queries);
if (count($queries) == 0){
$output .= "no queries\n";
}else{
foreach ($queries as $key=>$query){
$took = round(doubleval($times[$key]), 3);
$CI->db->query('INSERT INTO queryLog_tbl(`query`, `executedTime`, `timeTaken`, `executedBy`) VALUES ("'.$query.'", "'.date('Y-m-d h:i:s').'", "'.$took.'","'.$CI->session->userdata('UserID').'")');
$output .= $query . "\n";
$output .= "===[took:{$took}]\n\n";
}
}
$CI->load->helper('file');
if ( ! write_file(APPPATH . "/logs/queries.log.txt", $output, 'a+')){
log_message('debug','Unable to write query the file');
}
}
}
and hooks enabled in my config.php : $config['enable_hooks'] = TRUE;
You need to check your internal redirection after any modification query(Insert, Update or delete query) executed. If you put any redirect statement after modification query then it will overtake hook execution.
You can do it by overwriting the query() method in system/database/DB_driver.php
Or
Create library and call it from relevant controllers.
My code skipping all queries other than SELECT because of internal redirection. So I created a library for this. I am attaching my code here. It may help someone else
application/libraries/Querylog.php
class Querylog {
protected $CI;
public function __construct() {
$this->CI =& get_instance();
}
function save_query_in_db() {
$query = $this->CI->db->last_query();
$times = $this->CI->db->query_times;
$time = round(doubleval($times[2]), 5);
$this->CI->db->query('INSERT INTO queryLog_tbl(`query`, `executedTime`, `timeTaken`, `executedBy`) '
. 'VALUES ("'.$query.'", "'.date('Y-m-d h:i:s').'", "'.$time.'","'.$this->CI->session->userdata('UserID').'")');
}
}
load this library in your controller or autoload.php
and call save_query_in_db() where ever you want
eg: in model :
$this->db->set('status', 1);
$this->db->where('UserID', $this->session->userdata('UserID'));
$this->db->update('user_tbl');
$this->querylog->save_query_in_db();
I have a page called EventPage that I am managing via a Model admin. Also using Catalog manager: https://github.com/littlegiant/silverstripe-catalogmanager
Question is I need to be able to export all the expired events (And all of the fields).
I have an 'EndDate' => 'Date', field on the EventPage.
So I want to only show EventPages in my CSV export where the EndDate is GreaterThanOrEqual to todays date e.g Expired.
The following generates an CSV export button, but currently it is exporting all the fields, where as I want to filter it so we only show the expired events.
How do I go about this?
<?php
class EventAdmin extends CatalogPageAdmin {
public $showImportForm = false;
private static $managed_models = array(
'EventPage',
'EventCategory',
'EventSubmission',
);
private static $url_segment = 'events';
private static $menu_title = 'Events';
public function getEditForm($id = null, $fields = null) {
$form = parent::getEditForm($id, $fields);
$gridFieldName = 'EventPage';
$gridField = $form->Fields()->fieldByName($gridFieldName);
if ($gridField) {
$gridField->getConfig()->addComponent(new GridFieldExportButton());
}
return $form;
}
}
We can create a custom export button to filter the list of items before exporting them.
First we create a GridFieldExportExpiredEventsButton which extends GridFieldExportButton. This is a complete copy of the current SilverStripe 3.5 generateExportFileData function but with an added filterByCallback on the $items list to filter items that have an EndDate < date('Y-m-d').
class GridFieldExportExpiredEventsButton extends GridFieldExportButton {
public function getHTMLFragments($gridField) {
$button = new GridField_FormAction(
$gridField,
'export',
'Export expired events',
'export',
null
);
$button->setAttribute('data-icon', 'download-csv');
$button->addExtraClass('no-ajax action_export');
$button->setForm($gridField->getForm());
return array(
$this->targetFragment => '<p class="grid-csv-button">' . $button->Field() . '</p>',
);
}
public function generateExportFileData($gridField) {
$separator = $this->csvSeparator;
$csvColumns = $this->getExportColumnsForGridField($gridField);
$fileData = '';
$member = Member::currentUser();
if($this->csvHasHeader) {
$headers = array();
// determine the CSV headers. If a field is callable (e.g. anonymous function) then use the
// source name as the header instead
foreach($csvColumns as $columnSource => $columnHeader) {
$headers[] = (!is_string($columnHeader) && is_callable($columnHeader)) ? $columnSource : $columnHeader;
}
$fileData .= "\"" . implode("\"{$separator}\"", array_values($headers)) . "\"";
$fileData .= "\n";
}
//Remove GridFieldPaginator as we're going to export the entire list.
$gridField->getConfig()->removeComponentsByType('GridFieldPaginator');
$items = $gridField->getManipulatedList();
$items = $items->filterByCallback(function($item) {
// The following line modifies what items are filtered. Change this to change what items are filtered
return $item->EndDate < date('Y-m-d');
});
// #todo should GridFieldComponents change behaviour based on whether others are available in the config?
foreach($gridField->getConfig()->getComponents() as $component){
if($component instanceof GridFieldFilterHeader || $component instanceof GridFieldSortableHeader) {
$items = $component->getManipulatedData($gridField, $items);
}
}
foreach($items->limit(null) as $item) {
if(!$item->hasMethod('canView') || $item->canView($member)) {
$columnData = array();
foreach($csvColumns as $columnSource => $columnHeader) {
if(!is_string($columnHeader) && is_callable($columnHeader)) {
if($item->hasMethod($columnSource)) {
$relObj = $item->{$columnSource}();
} else {
$relObj = $item->relObject($columnSource);
}
$value = $columnHeader($relObj);
} else {
$value = $gridField->getDataFieldValue($item, $columnSource);
if($value === null) {
$value = $gridField->getDataFieldValue($item, $columnHeader);
}
}
$value = str_replace(array("\r", "\n"), "\n", $value);
$columnData[] = '"' . str_replace('"', '""', $value) . '"';
}
$fileData .= implode($separator, $columnData);
$fileData .= "\n";
}
if($item->hasMethod('destroy')) {
$item->destroy();
}
}
return $fileData;
}
}
The extra line that we have added that filters the export items is:
return $item->EndDate < date('Y-m-d');
Alter this to alter the list of items that are exported. I have set this to only return items which have an EndDate that is in the past. Change this as you need.
We then add this export button to our grid field in our event model admin:
class EventAdmin extends CatalogPageAdmin {
private static $managed_models = array(
'EventPage'
);
public function getEditForm($id = null, $fields = null) {
$form = parent::getEditForm($id);
if ($this->modelClass == 'EventPage') {
$gridField = $form->Fields()->fieldByName($this->modelClass);
$gridField->getConfig()->removeComponentsByType('GridFieldExportButton');
$gridField->getConfig()->addComponent(new GridFieldExportExpiredEventsButton('buttons-before-left'));
}
return $form;
}
}
This was originally two answers...
To limit the fields
Have you had a look at the GridFieldExportButton class ?
The constructor
/**
* #param string $targetFragment The HTML fragment to write the button into
* #param array $exportColumns The columns to include in the export
*/
public function __construct($targetFragment = "after", $exportColumns = null) {
$this->targetFragment = $targetFragment;
$this->exportColumns = $exportColumns;
}
So you should be able to pass $exportColumns as an argument.
in your code that would be
if ($gridField) {
$gridField->getConfig()->addComponent(new GridFieldExportButton("after", ["field1", "field2"]));
}
OR - EVEN BETTER SOLUTION
you can define your summary fields on EventPage as such
private static $summary_fields = ["FIeld1", "Field2"];
Then make sure your flush and it should use that as fields.
To filter which items to export in your CSV
So in this case, I think you should create a new class that extends GridFieldExportButton (maybe called EventPageCSVExportButton or something) and override the methods you want. In your case it would probably be generateExportFileData(), just do a check in the loop and exclude data you don't want.
Then use that new class in your EventAdmin.
Have you had a look at the GridFieldExportButton class ?
The constructor
/**
* #param string $targetFragment The HTML fragment to write the button into
* #param array $exportColumns The columns to include in the export
*/
public function __construct($targetFragment = "after", $exportColumns = null) {
$this->targetFragment = $targetFragment;
$this->exportColumns = $exportColumns;
}
So you should be able to pass $exportColumns as an argument.
in your code that would be
if ($gridField) {
$gridField->getConfig()->addComponent(new GridFieldExportButton("after", ["field1", "field2"]));
}
OR - EVEN BETTER SOLUTION
you can define your summary fields on EventPage as such
private static $summary_fields = ["FIeld1", "Field2"];
Then make sure your flush and it should use that as fields.
I am new to magento and I am not able to make out how one can remove the unwanted states from dropdown list in magento. I tried to edit my below function as per this link http://doejo.com/blog/magento-how-to-remove-certain-states-from-state-region-list-at-checkout-or-registration/ but it did not work. Below i sthe code for removing unwanted states but when I add to my class in local folder, not getting any results.
$excludeRegions = array('AE','AA');
foreach ($collection as $region) {
if (!$region->getRegionId()) {
continue;
}
***//Here is the code from the link given
//BOF Custom Logic Here***
$regionCode = $region->getCode();
$this->_select->from(array('region'=>$this->_regionTable),
array('region_id'=>'region_id', 'country_id'=>'country_id', 'code'=>'code', 'default_name'=>'default_name')
)->where('code NOT IN (?)', $exclude_regions);
_getRegions function edited as per above code and link respectively.
protected function _getRegions($storeId)
{
$countryIds = array();
$countryCollection = $this->getCountryCollection()->loadByStore($storeId);
foreach ($countryCollection as $country) {
$countryIds[] = $country->getCountryId();
}
/** #var $regionModel Mage_Directory_Model_Region */
$regionModel = $this->_factory->getModel('directory/region');
/** #var $collection Mage_Directory_Model_Resource_Region_Collection */
$collection = $regionModel->getResourceCollection()
->addCountryFilter($countryIds)
->load();
$regions = array(
'config' => array(
'show_all_regions' => $this->getShowNonRequiredState(),
'regions_required' => $this->getCountriesWithStatesRequired()
)
);
$excludeRegions = array('AE','AA');
foreach ($collection as $region) {
if (!$region->getRegionId()) {
continue;
}
***//Here is the code from the link given
//BOF Custom Logic Here***
$regionCode = $region->getCode();
$this->_select->from(array('region'=>$this->_regionTable),
array('region_id'=>'region_id', 'country_id'=>'country_id', 'code'=>'code', 'default_name'=>'default_name')
)->where('code NOT IN (?)', $exclude_regions);
//EOF Custom Logic Here
$regions[$region->getCountryId()][$region->getRegionId()] = array(
'code' => $region->getCode(),
'name' => $this->__($region->getName())
);
}
return $regions;
}
After making the above changes, I tried below steps as my code is in /app/code/core/Mage/Directory/Helper/Data.php
Create a module Vids_Directory in pool local like app/code/local/Vids/Directory
Create app/etc/modules/Vids_Directory.xml
Create app/code/local/Vids/Directory/etc/config.xml
create app/code/local/Vids/Helper/Data.php
Is it possible to get a record of my model by another field of my model?
The normal way
$model = Mage::getModel('foo_bar/baz');
$model->load($id);
// do something with the loaded record
But i need something like this
$model = Mage::getModel('foo_bar/baz');
$model->loadByAnotherFieldOfModel($value)
// do something with the loaded record
is that possible?
$model = Mage::getModel('foo_bar/baz');
$model->load('field_value', 'field_name');
use this
$_category = Mage::getModel('catalog/category')->loadByAttribute('name', 'computer');
$_product = Mage::getModel('catalog/product')->loadByAttribute('name', 'hp2312');
// Load by SKU
$_product = Mage::getModel('catalog/product')->loadByAttribute('sku', 'computer123');
Goto model file
NameSpace/Yourmodule/Model/YourModel.php
add below code
public function loadByField($fieldvalue)
{
$this->_getResource()->loadByField($this, $fieldvalue);
return $this;
}
AND
NameSpace/YourModule/Model/Resource/YourModel.php
and code is
public function loadByField(NameSpace_YourModule_Model_YourModel $Object, $fieldvalue)
{
$adapter = $this->_getReadAdapter();
$bind = array('fieldname' => $fieldvalue);
$select = $adapter->select()
->from($this->getMainTable(), 'tablePrimaryKey')
->where('fieldname = :fieldname');
$modelId = $adapter->fetchOne($select, $bind);
if ($modelId) {
$this->load($Object, $modelId );
} else {
$Object->setData(array());
}
return $this;
}
The Joomla com_content has small toggle button for the article's status "publish" to publish or unpublish the articles. So, I want to have same type of toggle button in my component also to approve or disapprove users.
Now, I want some advice from experts on how to go about. I have gone through com_content but I don't really understand that how should i begin. I can't understand com_content approach and code because I am not coding in line with Joomla 2.5.
How should I start with this ?
i made it work on my own. let me share the experience for those who will need it in future. my table field or database field is approved and its value is 0 initially (which means the record is unapproved by the admin)
in my layout/default page i have the code as below for the toggle button:
<?php
$k = 0;
for ($i=0, $n=count( $this->items ); $i < $n; $i++)
{
$row = &$this->items[$i];
..................
..................
?>
..................
<td align="center">
<?php echo JHtml::_('job.approve', $row->approved, $i); ?>
</td>
Note that i've $row->approved which is my field from db. then i've job.approve for which i have created a job.php file and placed in helpers directory. the code for job.php is:
<?php
// no direct access
defined('_JEXEC') or die;
/**
* #package Joomla.Administrator
* #subpackage com_content
*/
abstract class JHtmlJob
{
/**
* #param int $value The state value
* #param int $i
*/
static function approve($value = 0, $i)
{
// Array of image, task, title, action
$states = array(
0 => array('disabled.png', 'approve', 'Unapproved', 'Toggle to approve'),
1 => array('tick.png', 'unapprove', 'Approved', 'Toggle to unapprove'),
);
$state = JArrayHelper::getValue($states, (int) $value, $states[1]);
$html = JHtml::_('image', 'admin/'.$state[0], JText::_($state[2]), NULL, true);
//if ($canChange) {
$html = '<a href="#" onclick="return listItemTask(\'cb'.$i.'\',\''.$state[1].'\')" title="'.JText::_($state[3]).'">'
. $html.'</a>';
//}
return $html;
}
}
Then i've registered two tasks in controller as approve and unapprove along with approve function:
public function __construct($config = array())
{
parent::__construct($config);
$this->registerTask('unapprove', 'approve');
}
/**
* Method to toggle the featured setting of a list of articles.
*
* #return void
* #since 1.6
*/
function approve()
{
// Initialise variables.
$user = JFactory::getUser();
$ids = JRequest::getVar('cid', array(), '', 'array');
$values = array('approve' => 1, 'unapprove' => 0);
$task = $this->getTask();
$value = JArrayHelper::getValue($values, $task, 0, 'int');
if (empty($ids)) {
JError::raiseWarning(500, JText::_('JERROR_NO_ITEMS_SELECTED'));
}
else {
// Get the model.
$model = $this->getModel('jobs');
// Publish the items.
if (!$model->approve($ids, $value)) {
JError::raiseWarning(500, $model->getError());
}
}
$redirectTo = JRoute::_('index.php?option='.JRequest::getVar('option'));
$this->setRedirect($redirectTo);
}
Thereafter, i've added the following function in model to update the value to 0 or 1.
function approve($cid, $publish) {
if (count( $cid ))
{
JArrayHelper::toInteger($cid);
$cids = implode( ',', $cid );
$query = 'UPDATE #__tbljobs'
. ' SET approved = '.(int) $publish
. ' WHERE id IN ( '.$cids.' )';
$this->_db->setQuery( $query );
if (!$this->_db->query()) {
$this->setError($this->_db->getErrorMsg());
return false;
}
}
return true;
}
Please don't forget to include the job.php file in your view/view.html.php file as below:
<?php
defined('_JEXEC') or die('Restricted Access');
jimport('joomla.application.component.view');
require_once JPATH_COMPONENT .'/helpers/job.php';
Class JobsViewListJobs extends JView
{
And remember i am not using JForm nor my code is in joomla 1.7 style. But i am following the MVC architecture. So, i am not sure if my method will work for people who are coding in joomla 1.7 and above style.
You can use this to create publish button Read more-
JHtml::_('jgrid.published', $item->state, $i, 'articles.', $canChange);
Or this html-
<?php if($item->approve){?>
<td class="center">
<a class="jgrid hasTip" href="javascript:void(0);" onclick="return listItemTask('cb<?php echo $i?>','items.disapprove')" title=""><span class="state publish"><span class="text">Disapprove</span></span></a>
</td>
<?php }else{?>
<td class="center">
<a class="jgrid hasTip" href="javascript:void(0);" onclick="return listItemTask('cb<?php echo $i?>','items.approve')" title=""><span class="state unpublish"><span class="text">Approve</span></span></a>
</td>
<?php }?>
In items.approve and items.disapprove ,items is controller and approve and
disapprove is task of items controller.`
In your controller add these function-
public function __construct($config = array()){
parent::__construct($config);
$this->registerTask('unapproved', 'approved');
}
function approved() {
$ids = JRequest::getVar('cid', array(), '', 'array');
JArrayHelper::toInteger($ids );
$cids = implode( ',', $ids);
$values = array('approved' => 1, 'unapproved' => 0);
$task = $this->getTask();
$value = JArrayHelper::getValue($values, $task, 0, 'int');
$db =& JFactory::getDBO();
$query = 'UPDATE #__tbljobs' . ' SET approved = '.(int) $value . ' WHERE id IN ( '.$cids.' )';
$db->setQuery($query);
$result = $db->query();
$redirectTo = JRoute::_('index.php?option='.JRequest::getVar('option').'&task=display');
$this->setRedirect($redirectTo);
}
Read this - Joomla 2.5 extend jgrid.published column in custom component
Hope this will help.