I would like to know if magento logs the error rows anywhere when doing an import.
If so, where are the logs files, and how do I turn it on?
Looking at the method definition in app/Mage.php
you will find
/**
* log facility (??)
*
* #param string $message
* #param integer $level
* #param string $file
* #param bool $forceLog
*/
public static function log($message, $level = null, $file = '', $forceLog = false)
{
if (!self::getConfig()) {
return;
}
try {
$logActive = self::getStoreConfig('dev/log/active');
if (empty($file)) {
$file = self::getStoreConfig('dev/log/file');
}
}
catch (Exception $e) {
$logActive = true;
}
if (!self::$_isDeveloperMode && !$logActive && !$forceLog) {
return;
}
static $loggers = array();
$level = is_null($level) ? Zend_Log::DEBUG : $level;
$file = empty($file) ? 'system.log' : $file;
try {
if (!isset($loggers[$file])) {
$logDir = self::getBaseDir('var') . DS . 'log';
$logFile = $logDir . DS . $file;
if (!is_dir($logDir)) {
mkdir($logDir);
chmod($logDir, 0777);
}
if (!file_exists($logFile)) {
file_put_contents($logFile, '');
chmod($logFile, 0777);
}
$format = '%timestamp% %priorityName% (%priority%): %message%' . PHP_EOL;
$formatter = new Zend_Log_Formatter_Simple($format);
$writerModel = (string)self::getConfig()->getNode('global/log/core/writer_model');
if (!self::$_app || !$writerModel) {
$writer = new Zend_Log_Writer_Stream($logFile);
}
else {
$writer = new $writerModel($logFile);
}
$writer->setFormatter($formatter);
$loggers[$file] = new Zend_Log($writer);
}
if (is_array($message) || is_object($message)) {
$message = print_r($message, true);
}
$loggers[$file]->log($message, $level);
}
catch (Exception $e) {
}
}
so logging to your own code, logging becomes as easy as
Mage::log($variable, null, 'yourfile.log', 1);
The 1 as the fourth option is completely option and supersedes the option of turning the logging off in the admin and will always force the system to write to your log. Everything for logging is done in HTTP_ROOT/var/log/
Logging is turned on by default, but if you are using a custom extension and need to insert logging, you can do the above. Any logging by Magento will always be in var/log/exception.log or var/log/system.log but most things will go to system.log unless it is something that uses throwException(), which goes to exception.log
Use direct import of products you will see error row no if any error exists on your screen..
Its fast method to import products
You can active the Exception.log file through Developer config menu.
In magento two file generated for log system.log file and exception.log file both file you find in var/log folder
I tried setting $_debugMode = true in the Mage_ImportExport_Model_Abstract model but it didn't create any logs in my case. I was uploading products using DataFlow method.
Then what I did was to change the Mage_Adminhtml_System_Convert_ProfileController a litte bit. Inside batchRunAction() it generates the errors as
try {
$importData = $batchImportModel->getBatchData();
$adapter->saveRow($importData);
} catch (Exception $e) {
$errors[] = $e->getMessage();
continue;
}
I logged the $errors array along with the current product sku to get what I needed, i.e.,
Mage::log($importData['sku'].' - '.$e->getMessage())
Related
I noticed that joomla tag input field is quite stupid. It loads everything from db, in this case 9K tags. Obviously ui becomes so slow.
Any ideas how to fix it? it seems there is already an ajax functionality present, so why not rely on that completely? J ways are crazy.
1 idea is to modify getOption method, and load only the tags that are related to current article editor is editing.
But in this context I don't seem to have article id.
Any ideas how to solve situation? I'm sure some of you've run into this :S
/**
* Method to get a list of tags
*
* #return array The field option objects.
*
* #since 3.1
*/
protected function getOptions()
{
$published = $this->element['published']? $this->element['published'] : array(0,1);
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('DISTINCT a.id AS value, a.path, a.title AS text, a.level, a.published, a.lft')
->from('#__tags AS a')
->join('LEFT', $db->qn('#__tags') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt');
// Filter language
if (!empty($this->element['language']))
{
$query->where('a.language = ' . $db->q($this->element['language']));
}
$query->where($db->qn('a.lft') . ' > 0');
// Filter on the published state
if (is_numeric($published))
{
$query->where('a.published = ' . (int) $published);
}
elseif (is_array($published))
{
JArrayHelper::toInteger($published);
$query->where('a.published IN (' . implode(',', $published) . ')');
}
$query->order('a.lft ASC');
// Get the options.
$db->setQuery($query);
try
{
$options = $db->loadObjectList();
}
catch (RuntimeException $e)
{
return false;
}
// Block the possibility to set a tag as it own parent
if ($this->form->getName() == 'com_tags.tag')
{
$id = (int) $this->form->getValue('id', 0);
foreach ($options as $option)
{
if ($option->value == $id)
{
$option->disable = true;
}
}
}
// Merge any additional options in the XML definition.
$options = array_merge(parent::getOptions(), $options);
// Prepare nested data
if ($this->isNested())
{
$this->prepareOptionsNested($options);
}
else
{
$options = JHelperTags::convertPathsToNames($options);
}
return $options;
}
So I've modified list that gets preloaded, only to load tags that are present in the article (saved as belonging to article). Autocomplete still works with ajax so no loss of functionality there.
I'm creating a folder (New Folder) inside a given one (FooFolder).
If I use "writer" as permission role everything is ok.
My Drive
|->FooFolder
|->NewFolder
I have this three functions:
function fileCreation($service, $fileName, $emailToOwn, $type )
{
//Create the file
$file = new Google_Service_Drive_DriveFile();
$file->setTitle($fileName);
$file->setMimeType($type);
$file = $service->files->insert( $file );
$permission = insertPermission($service, $file->getId(),$emailToOwn,"user","writer");
return $file;
}
function insertPermission($service, $fileId, $value, $type, $role) {
$newPermission = new Google_Service_Drive_Permission();
$newPermission->setValue($value);
$newPermission->setType($type);
$newPermission->setRole($role);
return $service->permissions->insert($fileId, $newPermission, array(NULL,false));
}
function insertFileIntoFolder($service, $folderId, $fileId) {
$newChild = new Google_Service_Drive_ChildReference();
$newChild->setId($fileId);
try {
return $service->children->insert($folderId, $newChild);
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
return false;
}
When I change permission role to "Owner" the new folder is both created correctly in the parent directory and displayed in the root folder.
A link to a picture of my drive after the call of
$service->permissions->insert($fileId, "owner");
A link to a picture of my drive after the call of
$service->permissions->insert($fileId, "writer");
I found a solution
It worked to remove the parent folder from each folder I create (I got the code from Drive-Api documentation)
/**
* Remove a root from a folder.
*
* #param Google_Service_Drive $service Drive API service instance.
* #param String $folderId ID of the folder to remove the file from.
* #param String $fileId ID of the file to remove from the folder.
*/
function removeRootFromFolder($service, $fileId) {
try {
$parents = $service->parents->listParents($fileId);
foreach ($parents->getItems() as $parent) {
if ($parent->getIsRoot())
{
$service->parents->delete($fileId, $parent->getId());
}
}
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
and updated the method to put a file in a folder
/**
* Insert a file into a folder.
*
* #param Google_Service_Drive $service Drive API service instance.
* #param String $folderId ID of the folder to insert the file into.
* #param String $fileId ID of the file to insert.
* #return Google_Service_Drive_ChildReference The inserted child. NULL is
* returned if an API error occurred.
*/
function insertFileIntoFolder($service, $folderId, $fileId) {
$newChild = new Google_Service_Drive_ChildReference();
$newChild->setId($fileId);
try {
$r = $service->children->insert($folderId, $newChild);
removeRootFromFolder($service, $fileId);
return $r;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
return false;
}
I'm creating Magento attribute options via a script, but I need to then be able to get the new ID and use it straight away in the same script.
At the moment it's not pulling the id through - if I kill the script and re-start it it picks up the created option and returns the ID, but not as part of the same script.
Here is the code I am using:
$attr = Mage::getModel('catalog/product')->getResource()->getAttribute($key);
if ($attr->usesSource()) {
$vattr_id = $attr->getSource()->getOptionId($value);
}else{
echo "No Source";
$vattr_id = false;
}
if($vattr_id){
return $vattr_id;
}else{
$attr_model = Mage::getModel('catalog/resource_eav_attribute');
$attr = $attr_model->loadByCode('catalog_product', $key);
$attr_id = $attr->getAttributeId();
$option['attribute_id'] = $attr_id;
$option['value'][$value][0] = $value;
$option['value'][$value][1] = $value;
$setup = new Mage_Eav_Model_Entity_Setup('core_setup');
$setup->addAttributeOption($option);
$attr = Mage::getModel('catalog/product')->getResource()->getAttribute($key);
if ($attr->usesSource()) {
$vattr_id = $attr->getSource()->getOptionId($value);
echo "AttrID: $vattr_id";
}
}
Running this (with the required Mage::app() etc), creates the option, you can see it in the Magento back end, but the $vattr_id is NULL. If I reload the script, then it finds the attribute option in that first block as it should.
I guess it's something to do with how Magento is caching the models, but not sure where I need to look to clear these?
function getAttributeOptionId($attributeName, $attributeValue) {
/* #var $attribute Mage_Eav_Model_Entity_Attribute */
$attribute = Mage::getModel("eav/entity_attribute")->loadByCode("catalog_product", $attributeName);
// checking attribute code
if ($attribute->getId()) {
$source = $attribute->getSource();
$options = $source->getAllOptions();
// looking for existing id
foreach ($options as $optionValue) {
if ($attributeValue == $optionValue["label"]) {
return $optionValue["value"];
}
}
// making new option
$addOptionData = array(
"attribute_id" => $attribute->getId(),
"value" => array(array($attributeValue))
);
$setup = new Mage_Eav_Model_Entity_Setup('core_setup');
$setup->addAttributeOption($addOptionData);
// getting new id
$attribute = Mage::getModel("eav/entity_attribute")->loadByCode("catalog_product", $attributeName);
$source = $attribute->getSource();
$options = $source->getAllOptions();
foreach ($options as $optionValue) {
if ($attributeValue == $optionValue["label"]) {
return $optionValue["value"];
}
}
}
return null;
}
echo getAttributeOptionId("brand", "Intel");
I want to check the from the controller if I am rendering an add form or just a view. I want to do something like this..
public function clients()
{
try{
if ($_SERVER["REQUEST_URI"] == "/data/clients")
{
$data['client'] = $this->db->query("select * from clients");
$this->load->view('cview/client',$data);
}
else
{
$crud = new grocery_CRUD();
//$crud->set_theme('datatables');
$crud->set_table('clients');
$crud->set_subject('Clients');
crud->required_fields('city');
//$crud->columns('city','country','phone','addressLine1','postalCode');
$output = $crud->render();
$this->load->view('/crud/users',$output);
}
}catch(Exception $e){
show_error($e->getMessage().' --- '. $e->getTraceAsString());
}
}
This would work well except I'm using an Iframe and this doesn't work if the url doesn't change :P
$state = $this->grocery_crud->getState();
this will get the what state it is in.
if (($state == "list" || $state == "success"))
{
$data['client'] = $this->db->query("select * from clients");
$this->load->view('cview/client',$data);
}
else
{
$crud = new grocery_CRUD();
//$crud->set_theme('datatables');
$crud->set_table('clients');
$crud->set_subject('Clients');
$crud->required_fields('city','phone');
//$crud->columns('city','country','phone','addressLine1','postalCode');
$output = $crud->render();
$this->load->view('/crud/users',$output);
}
In this example above "list" will work on cancel button and "success" works on save and update button on the add screen or edit screen.
I am making an application in which i am uploading file from my custom tab as follows
i created a observer for event called catalog_product_save_after. In the particular function, i am uploading those files to catalog/product folder and its get uploaded to those folder without any error.
But when i am trying to assign those images to that particular product, i got the following error.
File was not uploaded at file E:\xampp\htdocs\magento\lib\Varien\File\Uploader.php on line 152
If i check system.log then i see the 2012-08-24T11:33:15+00:00 ERR (3): User Error: Some transactions have not been committed or rolled back in E:\xampp\htdocs\magento\lib\Varien\Db\Adapter\Pdo\Mysql.php on line 3645 this error.
My observer function is as follows
public function Savedata($observer)
{
$params = Mage::app()->getRequest()->getParams();
$product = $observer->getEvent()->getProduct();
$product_id = $product->getId();
$filesData = array();
$keysData = array_keys($_FILES);
foreach($keysData as $keys)
{
$uploader = new Varien_File_Uploader("$keys");
$uploader->setAllowedExtensions(array('jpeg', 'jpg', 'png', 'tiff'));
$uploader->setAllowRenameFiles(true);
$uploader->setFilesDispersion(false);
$path = Mage::getBaseDir('media') . DS . "catalog" . DS . "product";
if(!is_dir($path))
{
mkdir($path);
}
$extension = pathinfo($_FILES["$keys"]['name'], PATHINFO_EXTENSION);
$date = new DateTime();
$file_name = $keys . "_" . $product_id . "." . $extension;
$_FILES["$keys"]['name'] = $file_name;
$uploader->save($path, $_FILES["$keys"]['name']);
$filesData[] = $path .DS. $_FILES["$keys"]['name'];
}
print_r($filesData);
///till this works file.. when i add following code, program dies.
try
{
$productData = Mage::getModel('catalog/product')->load($product_id);
print_r($productData->getData());
foreach($filesData as $file)
{
$productData->addImageToMediaGallery($file, "image" ,false, false);
}
$productData->save();
$productData = Mage::getModel('catalog/product')->load($product_id);
print_r($productData->getData());
}
catch (Exception $e)
{
echo $e->getMessage() . "||" . $e->getCode() . "||" . $e->getFile() . "||" . $e->getLine();
}
exit();
}
any suggestion where i am going wrong? why this error occur?
i am using magento 1.7
I see that you're going to update your catalog/product object when you're saving it.
You are using event catalog_product_save_after.
Inside the observer, you call:
$productData = Mage::getModel('catalog/product')->load($product_id);
...
$productData->save();
$productData is catalog/product object -> you saved it.
You can guess what will happen, it will trigger event catalog_product_save_after and so on, looping forever.
I see that you call $productData->save(); because in this event, the value has been saved and can not be changed.
So instead of using catalog_product_save_after, you can use catalog_product_save_before.
The same like your code, but remove $productData->save(); because it will automatically call save.
Mage_Core_Model_Abstract
public function save()
{
/**
* Direct deleted items to delete method
*/
if ($this->isDeleted()) {
return $this->delete();
}
if (!$this->_hasModelChanged()) {
return $this;
}
$this->_getResource()->beginTransaction();
$dataCommited = false;
try {
$this->_beforeSave();
if ($this->_dataSaveAllowed) {
//see this line below, it will call save, so you don't need to call save in your `catalog_product_save_before` (no looping forever)
$this->_getResource()->save($this);
$this->_afterSave();
}
$this->_getResource()->addCommitCallback(array($this, 'afterCommitCallback'))
->commit();
$this->_hasDataChanges = false;
$dataCommited = true;
} catch (Exception $e) {
$this->_getResource()->rollBack();
$this->_hasDataChanges = true;
throw $e;
}
if ($dataCommited) {
$this->_afterSaveCommit();
}
return $this;
}