Varien_File_Uploader is not uploading files in custom module in magento - magento

I am trying to save the images in my module but the images are not saving from the form.
$uploader = new Varien_File_Uploader('image'); this code is not working I dont know why. The loop breaks on this line and the control get out of the loop from here. How can I save the images.
Here is my save function in the controller
public function saveAction()
{
if ($this->getRequest()->getPost())
{
try
{
$postData = $this->getRequest()->getPost();
//echo "<pre>";print_r($postData); exit;
$articleModel = Mage::getModel('blog/article');
$imgFilename = NULL;
if($_FILES['image']['name'] != '')
{//echo "<pre>"; echo count($_FILES['image']['name']);
foreach($_FILES['image']['name'] as $_FILES['image']['name'])
{
//print_r($_FILES['image']['name']);
try
{ echo "1";
$uploader = new Varien_File_Uploader('image'); echo "hi";
//print_r($uploader);exit;
$uploader->setAllowedExtensions(array('jpg','jpeg','gif','png','flv'));
$uploader->setAllowRenameFiles(false);
$uploader->setFilesDispersion(false);
$uploader->setAllowCreateFolders(true);
// Set media as the upload dir
$media_path = Mage::getBaseDir('media') . DS . 'blog' . DS;
$imgFilename = time() . $postData['image'];
// Upload the image
//$uploader->save($media_path, $_FILES['image']['name']);echo "4";
$uploader->save($media_path, $imgFilename);
}
catch (Exception $e)
{
Mage::log($e);
$this->_redirectError(502);
}
$data['image'] = $imgFilename;
}
}
else
{
if(isset($data['image']['delete']) && $data['image']['delete'] == 1)
$data['image'] = '';
else
unset($data['image']);
}
//echo "out"; exit;
if( $this->getRequest()->getParam('id') <= 0 )
$articleModel->setCreatedTime(
Mage::getSingleton('core/date')
->gmtDate());
$articleModel
->addData($postData)
->setUpdatedTime(
Mage::getSingleton('core/date')
->gmtDate())
->setId($this->getRequest()->getParam('id'))
->save();
$lastid = $articleModel->getId();
if($data['image'] != '')
{
foreach($data['image'] as $img)
{
$imageModel=Mage::getModel('blog/image');
$imageModel->setArticleId($lastid)->setImage($data['image'])->save();
}
}
Mage::getSingleton('adminhtml/session')
->addSuccess('successfully saved');
Mage::getSingleton('adminhtml/session')
->setarticleData(false);
$this->_redirect('*/*/');
//return;
if ($this->getRequest()->getParam('back'))
{
$this->_redirect('*/*/edit',array('id' => $articleModel->getId()));
return;
}
}
catch (Exception $e)
{
Mage::getSingleton('adminhtml/session')
->addError($e->getMessage());
Mage::getSingleton('adminhtml/session')
->setarticleData($this->getRequest()
->getPost());
$this->_redirect('*/*/edit',
array('id' => $this->getRequest()
->getParam('id')));
return;
}
}
$this->_redirect('*/*/');
}
and here is my form for the image
<?php
class Vertax_Blog_Block_Adminhtml_Article_Edit_Tab_Image extends Mage_Adminhtml_Block_Widget_Form
{
protected function _prepareForm()
{
$form = new Varien_Data_Form();
$this->setForm($form);
$fieldset = $form->addFieldset('image_form',
array('legend'=>'image'));
//$fieldset->addType('image', Mage::getConfig()->getBlockClassName('blog/adminhtml_article_helper_image'));
$fieldset->addType('image', 'Vertax_Blog_Block_Adminhtml_Article_Helper_Image');
$fieldset->addField('image', 'image', array(
'label' => 'Image',
'required' => false,
'name' => 'image[]',
'multiple' => 'multiple',
'mulitple' => true,
));
if (Mage::getSingleton('adminhtml/session')->getBlogPostData()) {
$form->setValues(Mage::getSingleton('adminhtml/session')->getBlogPostData());
Mage::getSingleton('adminhtml/session')->setBlogPostData(null);
} elseif (Mage::registry('article_data')) {
$form->setValues(Mage::registry('article_data')->getData());
}
return parent::_prepareForm();
}
}
?>

$uploader = new Mage_Core_Model_File_Uploader(
array(
'name' => $_FILES['galleryImage']['name'][$i],
'type' => $_FILES['galleryImage']['type'][$i],
'tmp_name' => $_FILES['galleryImage']['tmp_name'][$i],
'error' => $_FILES['galleryImage']['error'][$i],
'size' => $_FILES['galleryImage']['size'][$i]
));

Waseem,please try code for upload image..
$uploader = new Mage_Core_Model_File_Uploader('image');
$uploader->setAllowedExtensions(array('jpg', 'jpeg', 'gif', 'png'));
$uploader->setFilesDispersion(true);
$media_path = Mage::getBaseDir('media') . DS . 'blog' . DS;
$imgFilename = time() . $postData['image'];
// Upload the image
//$uploader->save($media_path, $_FILES['image']['name']);echo "4";
$uploader->save($media_path, $imgFilename);

there was a problem in your code while adding fieldset
$fieldset->addField('image', 'image', array(
'label' => 'Image',
'required' => false,
'name' => 'image[]',
'multiple' => 'multiple',
'mulitple' => true,
));
here you had set the name to image[] which in turn will return the array as $_FILES['image][name][], $_FILES['image][tmp_name][].
If you want to upload single file then set 'name' = 'image' or see this question

Try to use
$uploader = new Varien_File_Uploader($_FILES['image']);
instead of what you use currently.

Related

Can Anyone Check This Image Upload Code In Laravel?

I wrote this Code For Image Upload but I do not know if it is secure, or not. Is There any issue or vulnerability in this code??
if($request->hasFile('image')){
$AllowedImages = ['jpeg', 'jpg', 'png'];
$AllowedImageTypes = ['image/jpeg', 'image/png'];
$image = $request->image;
$ImageNameWithExtension = $image->getClientOriginalName();
$ImageName = pathinfo($ImageNameWithExtension, PATHINFO_FILENAME);
$ImageExtension = $image->getClientOriginalExtension();
$ImageType = $image->getMimeType();
$ImageLocalPath = $image->getPathName();
$ImageSize = $image->getSize();
$ImageError = $image->getError();
$ImageNewName = sha1(md5($ImageName)).''.sha1(time()).'.'.$ImageExtension;
if(in_array($ImageType, $AllowedImageTypes) && in_array($ImageExtension, $AllowedImages) && getimagesize($ImageLocalPath) && ($ImageError === 0) && ($ImageSize <= 2000000)){
if($ImageType == 'image/jpeg' && ( $ImageExtension == 'jpeg' || $ImageExtension == 'jpg')){
$img = imagecreatefromjpeg($ImageLocalPath);
imagejpeg( $img, $ImageNewName, 100);
}
elseif($ImageType == 'image/png' && $ImageExtension == 'png'){
$img = imagecreatefrompng($ImageLocalPath);
imagepng( $img, $ImageNewName, 9);
}
imagedestroy($img);
try
{
$StoreImage = $image->storeAs('public/Upload/', $ImageNewName);
if(!$StoreImage){
throw new customException('File Upload Failed');
}
}
catch(customException $e){
session()->flash('File_Error', $e->errorMessage());
return back();
}
}
else{
session()->flash('File_Error', 'Image Validation Error Found');
return back();
}
}
else{
return back();
}
Consider this refactor for your code, it will help make your code cleaner.
public function store(Request $request)
{
$record = Model::create( $this->validateRequest() ); // this can insert other data into your database. In the db table, initially set the image related fields to nullable
$this->storeFile($record); // this will check if the request has a file and update the image related fields accordingly, else it will remain blank as it is nullable by default
return 'all data is saved';
}
private function validateRequest(){
return request()->validate([
'type' => 'nullable',
'image'=> request()->hasFile('image') ? 'mimes:jpeg,jpg,png|max:2000' : 'nullable', // 2000 means a maximum of 2MB
'other_field_1' => 'required',
'other_field_2' => 'required',
'other_field_3' => 'required'
]);
}
private function storeFile($record){
if( request()->hasFile('image') ){
$record->update([
'type' => request()->file->extension(),
'image' => request()->file->store('uploads/files', 'public') // The file will be hashed by default. public is used as second argument so you can access the uploaded file via your public folder
]);
}
}
This is check for file in the request, validate the file and other data, upload the file into storage folder.
You can use this code, for upload image :
In Request file :
public function rules()
{
return [
'image' => 'required|mimes:jpeg,jpg,png|max:50000'
],
}
And in your controller :
public function uploadImage(YourRequestClass $request){
$image = $request->file('image');
try{
$order=new Order();
if (!file_exists('upload/' . $image)) {
$currentDate = Carbon::now()->toDateString();
$imageName = $currentDate . '-' . uniqid() . '.' . $image->getClientOriginalExtension();
if (!file_exists('upload/')) {
mkdir('upload/', 0777, true);
}
$image->move('upload/', $imageName);
$order->image = $imageName;
}
$order->save();
return back();
} catche(\Exception $e){
Log::error($e);
return back();
}
}

getting an error Undefined property: stdClass::$id

I've issue with my CMS whenever I tried to Add new page with the following line of code
<?php echo form_open_multipart('admin/page/edit/'. $page->id); ?>
it gives me error
A PHP Error was encountered
Severity: Notice
Message: Undefined property: stdClass::$id
Filename: page/edit.php
Line Number: 5
my edit function is this which perform add & update functionality
public function edit($id = NULL) {
//Fetch a page or set new one
if ($id) {
$this->data['page'] = $this->page_m->get($id);
count($this->data['page']) || $this->data['errors'][] = 'Page Could not be found';
} else {
$this->data['page'] = $this->page_m->get_new();
}
$id == NULL || $this->data['page'] = $this->page_m->get($id);
//Pages for dropdown
$this->data['pages_no_parents'] = $this->page_m->get_no_parents();
//dump($this->data['pages_no_parents']);
//Setup form
$rules = $this->page_m->rules;
$this->form_validation->set_rules($rules);
//Process the form
if ($this->form_validation->run() == TRUE) {
$data = $this->page_m->array_from_post(array(
'title',
'slug',
'order',
'body',
'template',
'parent_id',
'filename'
));
/* * ***********WORKING FOR IMAGE UPLOAD AND SAVE PATH TO DATABASE*************** */
if (!empty($_FILES['filename'])) {
$fdata = $this->do_upload('filename'); /// you are passing the parameter here
$data['filename'] = base_url() . 'uploads/' . $fdata;
}
$this->page_m->save($data, $id);
// echo '<pre>' . $this->db->last_query() . '</pre>';
redirect('admin/page');
}
//Load the view
$this->data['subview'] = 'admin/page/edit';
$this->load->view('admin/_layout_main', $this->data);
}
public function do_upload($field_name) { // but not retriveing here do this
$field_name = 'filename';
$config = array(
'allowed_types' => '*',
'max_size' => '1024',
'max_width' => '1024',
'max_height' => '768',
'upload_path' => './uploads/'
);
$this->load->library('upload');
$this->upload->initialize($config);
if (!$this->upload->do_upload($field_name)) {
echo $this->upload->display_errors();
die();
$this->data['error'] = array('error' => $this->upload->display_errors());
//$this->data['subview'] = 'admin/page/edit';
//$this->load->view('admin/_layout_main', $this->data);
} else {
$fInfo = $this->upload->data();
//return $fInfo['file_path'].$fInfo['file_name'];
// $this->filename = $fInfo;
return $fInfo['file_name'];
}
}
<?php echo form_open_multipart('admin/page/edit/'. ((isset($page->id)) ? $page->id : '')); ?>
As I mentioned in my comment, if you are creating a new record (I assume:) your page object will not have an id yet, so you just have to do a quick check to make sure it exists and if not output an empty string.

Image doesn't upload in custom module magento

I have created custom module in magento with image upload attribute. Image name was successfully stored in DB table. But image doesn't upload to the target folder.
I have tried with this following code. please show me "what am i doing wrong here"
$uploader = new Varien_File_Uploader('fileinputname');
$uploader->setAllowedExtensions(array('jpg','jpeg','gif','png'));
$uploader->setAllowRenameFiles(false);
$uploader->setFilesDispersion(false);
$path = Mage::getBaseDir('media') .DS. 'foo'.DS ;
$uploader->save($path, $_FILES['fileinputname']['name']);
Last week I added the file upload option for my Magento app..Here is the code. This may help to you. This is the save action for your controller.
public function saveAction() {
$filedata = array();
$uploadedFile = 'uploaded_file';
$_helper = Mage::helper('fileuploader');
if (!empty($_FILES[$uploadedFile]['name'])) {
try {
$ext = $_helper->getFileExtension($_FILES[$uploadedFile]['name']);
$fname = 'File-' . time() . $ext;
$uploader = new Varien_File_Uploader($uploadedFile);
#$uploader->setAllowedExtensions(array("txt", "csv", "htm", "html", "xml", "css", "doc", "docx", "xls", "xlsx", "rtf", "ppt", "pdf", "swf", "flv", "avi", "wmv", "mov", "wav", "mp3", "jpg", "jpeg", "gif", "png","zip"));
$uploader->setAllowRenameFiles(true);
$uploader->setFilesDispersion(false);
$path = Mage::getBaseDir('media') . DS . 'custom' . DS . 'upload' . DS;
$uploader->save($path, $fname);
$filedata[$uploadedFile] = 'custom/upload/' . $fname;
} catch (Exception $e) {
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
$this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
return;
}
}
if ($data = $this->getRequest()->getPost()) {
$products = array();
$availProductIds = Mage::getModel('fileuploader/fileuploader')->getAllAvailProductIds();
parse_str($data['fileuploader_products'], $products);
foreach ($products as $k => $v) {
if (preg_match('/[^0-9]+/', $k) || preg_match('/[^0-9]+/', $v)) {
unset($products[$k]);
}
}
$productIds = array_intersect($availProductIds, $products);
$data['product_ids'] = implode(',', $productIds);
if (!empty($filedata[$uploadedFile])) {
$data[$uploadedFile] = $filedata[$uploadedFile];
} else {
if (isset($data[$uploadedFile]['delete']) && $data[$uploadedFile]['delete'] == 1) {
if ($data[$uploadedFile]['value'] != '')
$this->removeFile($data[$uploadedFile]['value']);
$data[$uploadedFile] = '';
}else {
unset($data[$uploadedFile]);
}
}
$model = Mage::getModel('fileuploader/fileuploader');
$model->setData($data)
->setId($this->getRequest()->getParam('id'));
try {
$model->save();
Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('fileuploader')->__('Item was successfully saved'));
Mage::getSingleton('adminhtml/session')->setFormData(false);
if ($this->getRequest()->getParam('back')) {
$this->_redirect('*/*/edit', array('id' => $model->getId()));
return;
}
$this->_redirect('*/*/');
return;
} catch (Exception $e) {
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
Mage::getSingleton('adminhtml/session')->setFormData($data);
$this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
return;
}
}
Mage::getSingleton('adminhtml/session')->addError(Mage::helper('fileuploader')->__('Unable to find item to save'));
$this->_redirect('*/*/');
}
Build form by add colomn function in grid.php
$this->addColumn('uploaded_file', array(
'header' => Mage::helper('fileuploader')->__('File'),
'align' => 'left',
'type' => 'file',
'escape' => true,
'sortable' => false,
'index' => 'uploaded_file',
));
And This is most important. Dont forgot to mention that your form enctype should be Multi/part in form.php file. I guess you missed it. Please check this.
protected function _prepareForm() {
$form = new Varien_Data_Form(array(
'id' => 'edit_form',
'action' => $this->getUrl('*/*/save', array('id' => $this->getRequest()->getParam('id'))),
'method' => 'post',
'enctype' => 'multipart/form-data'
)
);
Thats it..!!
Hi Elavarasan i can't seem to figure out what is wrong in what i did, or if i actually have done something. I used magento-module-creator you suggested and then added all the code above that you give under helper/data.php. Nothing happens. Appreciate your help as i am new in magento.

Magento Invoice sendEmail() with PDF attachment

I use the following code to load an invoice and send email programatically:
<?php
$invoice = Mage::getModel('sales/order_invoice')
->loadByIncrementId($invoice_queue['increment_id']);
if (null !== $invoice->getId()){
$invoice->sendEmail();
echo "- Done Invoice #". $invoice_queue['increment_id'] ."\r\n";
}
$invoice = null;
?>
This appears to be sending the invoice email correctly. However, the PDF attachment of the invoice isn't there in the email.
If I were to send the email via magento, it works.
Any idea how to get the PDF to be attached, when calling sendEmail() function?
For sending invoice email you need to overwrite
In mage/core/model/email/template.php add this method at the end of the file:
public function addAttachment(Zend_Pdf $pdf){
$file = $pdf->render();
$attachment = $this->getMail()->createAttachment($file);
$attachment->type = 'application/pdf';
$attachment->filename = 'test.pdf';
}
2 In sales/model/order/Invoice.php add the code between comments(2 lines of code) to the function sendEmail like this:
<?php
public function sendEmail($notifyCustomer=true, $comment='')
{
if (!Mage::helper('sales')->canSendNewInvoiceEmail($this->getOrder()->getStore()->getId())) {
return $this;
}
$currentDesign = Mage::getDesign()->setAllGetOld(array(
'package' => Mage::getStoreConfig('design/package/name', $this->getStoreId()),
'store' => $this->getStoreId()
));
$translate = Mage::getSingleton('core/translate');
/* #var $translate Mage_Core_Model_Translate */
$translate->setTranslateInline(false);
$order = $this->getOrder();
$copyTo = $this->_getEmails(self::XML_PATH_EMAIL_COPY_TO);
$copyMethod = Mage::getStoreConfig(self::XML_PATH_EMAIL_COPY_METHOD, $this->getStoreId());
if (!$notifyCustomer && !$copyTo) {
return $this;
}
$paymentBlock = Mage::helper('payment')->getInfoBlock($order->getPayment())
->setIsSecureMode(true);
$mailTemplate = Mage::getModel('core/email_template');
if ($order->getCustomerIsGuest()) {
$template = Mage::getStoreConfig(self::XML_PATH_EMAIL_GUEST_TEMPLATE, $order->getStoreId());
$customerName = $order->getBillingAddress()->getName();
} else {
$template = Mage::getStoreConfig(self::XML_PATH_EMAIL_TEMPLATE, $order->getStoreId());
$customerName = $order->getCustomerName();
}
// attachment here
$pdf = Mage::getModel('sales/order_pdf_invoice')->getPdf(array($this));
$mailTemplate->addAttachment($pdf);
if ($notifyCustomer) {
$sendTo[] = array(
'name' => $customerName,
'email' => $order->getCustomerEmail()
);
if ($copyTo && $copyMethod == 'bcc') {
foreach ($copyTo as $email) {
$mailTemplate->addBcc($email);
}
}
// enter code here
}
if ($copyTo && ($copyMethod == 'copy' || !$notifyCustomer)) {
foreach ($copyTo as $email) {
$sendTo[] = array(
'name' => null,
'email' => $email
);
}
}
foreach ($sendTo as $recipient) {
$mailTemplate->setDesignConfig(array('area'=>'frontend', 'store'=>$order->getStoreId()))
->sendTransactional(
$template,
Mage::getStoreConfig(self::XML_PATH_EMAIL_IDENTITY, $order->getStoreId()),
$recipient['email'],
$recipient['name'],
array(
'order' => $order,
'invoice' => $this,
'comment' => $comment,
'billing' => $order->getBillingAddress(),
'payment_html'=> $paymentBlock->toHtml(),
)
);
}
$translate->setTranslateInline(true);
Mage::getDesign()->setAllGetOld($currentDesign);
return $this;
} ?>
Now when you create an invoice from the back office and you select to notify customer a pdf attachment should be sent as well.

Make an error message on Magento checkout page (Shipping Method stage)

I developed a Magento shipping method module and it works fine.
I can retrieve the list of available shipping methods from my remote service but I want to have an error message if something will be wrong with connection to the srvice or etc.
The code of collectRates carrier class is listed below.
public function collectRates(Mage_Shipping_Model_Rate_Request $request) {
if (!$this->getConfigFlag('active')) {
return false;
}
require_once Mage::getBaseDir() . '/app/code/local/Citymail/CitymailDeliveryOption/lib/syvo_service_connect.php';
$citymail_service_url = $this->getConfigData('service_url') . '/syvo_service';
$connection = new syvo_service_connect($citymail_service_url);
if($connection->connect()) {
$handling = Mage::getStoreConfig('carriers/'.$this->_code.'/handling');
$rate_result = Mage::getModel('shipping/rate_result');
$product_qty = 0;
$products_data = array();
$currency = Mage::app()->getStore()->getCurrentCurrencyCode();
$quote = Mage::getSingleton('checkout/session')->getQuote();
foreach($quote->getAllVisibleItems() as $cartItem) {
$product_qty += $cartItem->getQty();
$products_data[$cartItem->getId()] = array(
'length_units' => 'cm',
'length' => 0,
'width' => 0,
'height' => 0,
'weight_units' => 'kg',
'weight' => $cartItem->getProduct()->getWeight(),
'shippable' => 'a',
'sell_price' => $cartItem->getProduct()->getPrice(),
'currency' => $currency,
);
}
$shipping_address = Mage::getModel('checkout/cart')->getQuote()->getShippingAddress();
$password = md5($this->getConfigData('service_password'));
$params = array(
'passw=' . $password,
'login=' . $this->getConfigData('service_login'),
'action=get_shipping_options',
'product_qty=' . $product_qty,
'products_data=' . json_encode($products_data),
'country=' . $shipping_address->getCountryId(),
'postal_code=' . $shipping_address->getPostcode(),
);
$response = $connection->send(implode('&', $params), 0, 30);
$response_status_line = $connection->getResponseStatusLine();
if((int)$response_status_line[1] == 403) {
//Access denied message
}
else {
$response_array = json_decode($response);
$citymail_service_points_data = array();
if($response_array->syvo_service_responce->type == 'success') {
$options = array();
foreach($response_array->syvo_service_responce->data->syvo_shipping_methods as $key_method => $shipping_method) {
$method_key = 'opt--' . $shipping_method->type . '--' . $shipping_method->distributor;
if($shipping_method->type == 'DHL_SERVICE_POINT') {
$citymail_service_points_data['service_points'][$shipping_method->id] = array(
'dhl_service_point_postcode' => $shipping_method->postcode,
'dhl_service_point_address' => $shipping_method->address,
);
$method_key .= '--' . $shipping_method->id;
}
$method = Mage::getModel("shipping/rate_result_method");
$method->setCarrier($this->_code);
$method->setCarrierTitle(Mage::getStoreConfig('carriers/' . $this->_code . '/title'));
$method->setMethod($method_key);
$method->setMethodTitle($shipping_method->text);
$method->setCost($shipping_method->rate);
$method->setPrice($shipping_method->rate + $handling);
$rate_result->append($method);
}
$street = $shipping_address->getStreet();
$citymail_temporary_order_data = array(
'login' => $this->getConfigData('service_login'),
'password' => $password,
'country_id' => $shipping_address->getCountryId(),
'company_name' => $shipping_address->getCompany(),
'name' => trim($shipping_address->getFirstname() . ' ' . $shipping_address->getLastname()),
'postal_code' => $shipping_address->getPostcode(),
'phone_number' => $shipping_address->getTelephone(),
'email' => $shipping_address->getEmail(),
'street' => $street[0],
'city' => $shipping_address->getCity(),
'matrix_id' => $response_array->syvo_service_responce->data->matrix_id,
'service_url' => $citymail_service_url,
);
$citymail_temporary_order_data = $citymail_service_points_data + $citymail_temporary_order_data;
Mage::getSingleton('core/session')->setCitymailTemporaryOrderData($citymail_temporary_order_data);
}
else {
//Some error handler
$error = Mage::getModel("shipping/rate_result_error");
$error->setCarrier('citymaildeliveryoption');
$error->setErrorMessage('sasasas');
$rate_result->append($error);
}
}
}
else {
}
return $rate_result;
}
This code has to return an error message if the module couldn't retrieve the list of shipping methods:
$error = Mage::getModel("shipping/rate_result_error");
$error->setCarrier('citymaildeliveryoption');
$error->setErrorMessage('sasasas');
$rate_result->append($error);
But the error is not displaying.
I checked an existing (core) Magento modules which use error handlers too (Ups, Usps modules) and error handlers of these modules also do not work, error message is not displaying.
Could you please advice some solution of this problem.
Tnank you!
Your code is good. You just need a little bit configuration for your carrier to always displays its methods.
Has shown in Mage_Shipping_Model_Shipping->collectCarrierRates() (line 176), Magento checks for 'showmethod' in your carrier config if a result is in error (and discard it, if it evaluates to 0) :
if ($carrier->getConfigData('showmethod') == 0 && $result->getError()) {
return $this;
}
So you just have to add this in your config.xml :
<?xml version="1.0" encoding="UTF-8"?>
<config>
<default>
<carriers>
<citymaildeliveryoption>
<showmethod>1</showmethod>
</citymaildeliveryoption>
</carriers>
</default>
</config>

Resources