Use Magento Cart Outside Magento - magento

I would like to get the cart Block outside of Magento. Here is my Code.
<?php
require_once ( $_SERVER['DOCUMENT_ROOT']."/app/Mage.php" );
umask(0);
Mage::app('base','website');
echo Mage::app()->getLocale()->getLocaleCode();
//Solution
Mage::getSingleton('core/translate')->setLocale('de_DE')->init('frontend', true);
Mage::getSingleton('core/session', array('name'=>'frontend'));
$block = Mage::getSingleton('core/layout')
->createBlock("checkout/cart_sidebar", "sidebar")
->setTemplate("checkout/cart/sidebar.phtml");
echo $block->toHtml();
?>
I have just the Problem that the output ist just english and translation doesn't work.
Thanks for Help

Any reason why you don't just specify a store code that has the german locale set in your call to Mage::app()?
Unrelated to your problem, but you may also be interested in a more solid approach of loading a block into another website.

Through this you can get all the cart details out side magneto. Now you can give any desired template to these elements.
umask(0);
Mage::app('default');
// This has to run to authenticate customer and checkout session calls.
Mage::getSingleton('core/session', array('name' => 'frontend'));
// Get any customer model you desire.
$oSession = Mage::getSingleton( 'customer/session' );
$oCustomer = $oSession->getCustomer();
$oCheckout = Mage::getSingleton( 'checkout/session' );
$oQuote = $oCheckout->getQuote();
var_dump( $oCustomer );
var_dump( $oSession );
var_dump( $oQuote );
var_dump( $oCheckout );
$oCart = $oQuote->getAllItems();
if( !empty( $oCart ) )
{
foreach ( $oCart as $oItem )
{
$sName = $oItem->getProduct()->getName();
$fPrice = $oItem->getProduct()->getPrice();
var_dump( $sName );
var_dump( $fPrice );
}
}
?>

namespace moduleName\addtobasket\Controller\Product;
class Index extends \Magento\Framework\App\Action\Action {
/**
* #var \Magento\Checkout\Model\Cart
*/
protected $cart;
/**
* #var \Magento\Catalog\Model\Product
*/
protected $product;
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory,
\Magento\Catalog\Model\Product $product,
\Magento\Checkout\Model\Cart $cart
) {
$this->resultPageFactory = $resultPageFactory;
$this->cart = $cart;
$this->product = $product;
parent::__construct($context);
}
public function execute()
{
try {
$params = array();
$params['qty'] = '1';//product quantity
/* Get product id from a URL like /addtobasket/product?id=1,2,3 */
$pIds = explode(',',$_GET['id']);
foreach($pIds as $value) {
$_product = $this->product->load($value);
if ($_product) {
$this->cart->addProduct($_product, $params);
$this->cart->save();
}
}
$this->messageManager->addSuccess(__('Add to cart successfully.'));
} catch (\Magento\Framework\Exception\LocalizedException $e) {
$this->messageManager->addException(
$e,
__('%1', $e->getMessage())
);
} catch (\Exception $e) {
$this->messageManager->addException($e, __('error.'));
}
/*cart page*/
$this->getResponse()->setRedirect('/checkout/cart/index');
}
}

Related

Issue in Create Order Pragmatically with multiple products

I am trying to create order with multiple products using below code. code work fine, but one issue is occurring. I don't know why that adding more than one product create an order with just one product and all quantity summed to this.
<?php
namespace Magecomp\Cenpos\Controller\Index;
use Magento\Framework\App\Action;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\Controller\ResultFactory;
class Display extends \Magento\Framework\App\Action\Action
{
protected $context;
protected $directory_list;
protected $cartRepositoryInterface;
protected $cartManagementInterface;
protected $_orderRepositoryInterface ;
/**
* #var \Magento\Sales\Model\Order\Email\Sender\OrderSender
*/
protected $orderSender;
/**
* #var \Magento\Checkout\Model\Session $checkoutSession
*/
protected $checkoutSession;
protected $_messageManager;
protected $_encryptor;
protected $_scopeConfig;
protected $logger;
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\App\Filesystem\DirectoryList $directory_list,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Catalog\Model\Product $product,
\Magento\Framework\Data\Form\FormKey $formkey,
\Magento\Quote\Model\QuoteFactory $quote,
\Magento\Quote\Model\QuoteManagement $quoteManagement,
\Magento\Customer\Model\CustomerFactory $customerFactory,
\Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
\Magento\Sales\Model\Service\OrderService $orderService,
\Magento\Customer\Model\Session $currentCustomer,
\Magento\Checkout\Model\Cart $cart,
\Magento\Quote\Api\CartRepositoryInterface $cartRepositoryInterface,
\Magento\Quote\Api\CartManagementInterface $cartManagementInterface,
\Magento\Checkout\Model\Session $checkoutSession,
\Magento\Sales\Model\Order\Email\Sender\OrderSender $orderSender,
\Magento\Framework\Encryption\EncryptorInterface $encryptor,
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
//\Magento\Sales\Api\OrderRepositoryInterface $orderRepositoryInterface
) {
$this->directory_list = $directory_list;
$this->_storeManager = $storeManager;
$this->_product = $product;
$this->_formkey = $formkey;
$this->quote = $quote;
$this->quoteManagement = $quoteManagement;
$this->customerFactory = $customerFactory;
$this->customerRepository = $customerRepository;
$this->orderService = $orderService;
$this->_currentCustomer = $currentCustomer;
$this->_cart = $cart;
$this->cartRepositoryInterface = $cartRepositoryInterface;
$this->cartManagementInterface = $cartManagementInterface;
$this->checkoutSession = $checkoutSession;
$this->orderSender = $orderSender;
$this->_encryptor = $encryptor;
$this->_scopeConfig = $scopeConfig;
//$this->_orderRepositoryInterface = $orderRepositoryInterface;
$this->_messageManager = $context->getMessageManager();
parent::__construct($context);
}
public function saveShipping() {
if(isset($_POST['carrier_code']))
{
$_SESSION['carrier_code'] = $_POST['carrier_code'];
}
return true;
}
public function execute()
{
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$cart = $objectManager->get('\Magento\Checkout\Model\Cart');
$shippingAddress = $cart->getQuote()->getShippingAddress();
$shippingAddressData = $shippingAddress->getData();
$Response = $_GET;
if($Response['message'] == "Approved" && $Response['result'] == "0") {
$store=$this->_storeManager->getStore();
$websiteId = $this->_storeManager->getStore()->getWebsiteId();
$customer=$this->customerFactory->create();
$customer->setWebsiteId($websiteId);
$customer->loadByEmail($shippingAddressData['email']);// load customet by email address
if(!$customer->getEntityId()){
//If not avilable then create this customer
$customer->setWebsiteId($websiteId)
->setStore($store)
->setFirstname($shippingAddressData['firstname'])
->setLastname($shippingAddressData['lastname'])
->setEmail($shippingAddressData['email'])
->setPassword($shippingAddressData['email']);
$customer->save();
$customer= $this->customerRepository->getById($customer->getEntityId());
}
//init the quote
$cart_id = $this->cartManagementInterface->createEmptyCart();
$cart = $this->cartRepositoryInterface->get($cart_id);
$cart->setStore($store);
// if you have already had the buyer id, you can load customer directly
$customer= $this->customerRepository->getById($customer->getEntityId());
$cart->setCurrency();
$cart->assignCustomer($customer); //Assign quote to customer
$productInfo = $this->_cart->getQuote()->getAllItems();
//add items in quote
foreach($productInfo as $item){
$product=$this->_product->load($item->getProductId());
$product->setPrice($item->getPrice());
$cart->addProduct(
$product,
intval($item->getQty())
);
}
$addressData = array(
'firstname' => $shippingAddressData['firstname'],
'lastname' => $shippingAddressData['lastname'],
'street' => $shippingAddressData['street'],
'city' => $shippingAddressData['city'],
'postcode' => $shippingAddressData['postcode'],
'telephone' => $shippingAddressData['telephone'],
'country_id' => $shippingAddressData['country_id'],
'region_id' => $shippingAddressData['region_id'],
'region' => $shippingAddressData['region'],
);
//set shipping and billing address
$quote = $this->quote->create();
$cart->getBillingAddress()->addData($addressData);
$cart->getShippingAddress()->addData($addressData);
if(isset($_SESSION['carrier_code'])) {
$shipping_method = $_SESSION['carrier_code'];
} else {
$session = $this->_objectManager->get('Magento\Checkout\Model\Session');
$shipping_method = $session->getQuote()->getShippingAddress()->getShippingMethod();
}
$shippingAddress = $cart->getShippingAddress();
$shippingAddress->setCollectShippingRates(true)
->collectShippingRates()
->setShippingMethod($shipping_method);
unset($_SESSION['carrier_code']);
$cart->setPaymentMethod('cenpos'); //payment method
//#todo insert a variable to affect the invetory
$cart->setInventoryProcessed(false);
$card_type_code = "VI";
$cart->getPayment()->importData(
[
'method' => 'cenpos',
'cc_type' => $card_type_code,
'cc_number' => '4893772408728522',
'cc_cid' => '341',
'cc_exp_month' => '02',
'cc_exp_year' => '2022'
]
);
// Collect total and save
$cart->collectTotals();
// Submit the quote and create the order
$cart->save();
$cart = $this->cartRepositoryInterface->get($cart->getId());
$order_id = $this->cartManagementInterface->placeOrder($cart->getId());
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$orderRepository = $objectManager->create('Magento\Sales\Model\Order')->load($order_id);
$orderRepository->save();
$orderRepository->setEmailSent(true);
$this->checkoutSession->setForceOrderMailSentOnSuccess(true);
$this->orderSender->send($orderRepository, true);
$resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
$resultRedirect->setUrl('http://m2gymtest.tpesonline.com/checkout/onepage/success');
return $resultRedirect;
}
}
}
Is there any problem in script? Or can it be server issue as the issue starts occurring after server changes.It was working properly before some days.
Use \Magento\Catalog\Model\ProductFactory $product instead of \Magento\Catalog\Model\Product $product in __construct() argument.
And Use
$product = $this->_product->create()->setStoreId($storeId)->load($item->getId());
to load the product instead of
$product=$this->_product->load($item->getProductId());
Hope this will help .

Programatically adding product to magento cart not working at the first time only

I'm creating custom functions for sign up and adding product to customer cart.
If user signed up using my function first product that he/she added will not be added to the cart unless he added another product after that everything working perfect and the first product also appear in the cart.
If user signed up by using magento sign up form then used my function to add product to the cart everything working.
Sign up code
public function signupAction() {
$email = $this->getRequest()->getPost('email');
$password = $this->getRequest()->getPost('password');
$firstName = $this->getRequest()->getPost('firstName');
$LastName = $this->getRequest()->getPost('LastName');
$session = Mage::getSingleton('customer/session');
$session->setEscapeMessages(true);
$websiteId = Mage::app()->getWebsite()->getId();
$store = Mage::app()->getStore();
$customer = Mage::getModel("customer/customer");
$customer->setWebsiteId($websiteId)
->setStore($store)
->setFirstname($firstName)
->setLastname($LastName)
->setEmail($email)
->setPassword($password);
try {
$customer->cleanPasswordsValidationData();
$customer->save();
$this->_dispatchRegisterSuccess($customer);
$this->_successProcessRegistration($customer);
} catch (Mage_Core_Exception $e) {
} catch (Exception $e) {
}
}
Add to cart code
public function addAction() {
$form_key = Mage::getSingleton('core/session')->getFormKey();
$json = $this->getRequest()->getPost('json');
$jsonObj = json_decode($json);
$cart = $this->_getCart();
$cart->init();
$response = array();
try {
foreach ($jsonObj as $data) {
$param = ['form_key' => $form_key,
'qty' => $data->qty, 'product' => $data->productId];
$product = $this->_initProduct($param['product']);
if ($data->type == 'simple') {
$cart->addProduct($product, $param);
}
}
$cart->save();
$this->_getSession()->setCartWasUpdated(true)
/**
* #todo remove wishlist observer processAddToCart
*/
Mage::dispatchEvent('checkout_cart_add_product_complete',
array('product' => $product,
'request' => $this->getRequest(),
'response' => $this->getResponse()));
if (!$cart->getQuote()->getHasError()) {
$response['status'] = 'SUCCESS';
} else {
$response['status'] = 'Error';
}
} catch (Mage_Core_Exception $e) {
$msg = "";
if ($this->_getSession()->getUseNotice(true)) {
$msg = $e->getMessage();
} else {
$messages = array_unique(explode("\n", $e->getMessage()));
foreach ($messages as $message) {
$msg .= $message . '<br/>';
}
}
$response['status'] = 'ERROR';
$response['message'] = $msg;
} catch (Exception $e) {
$response['status'] = 'ERROR';
$response['message'] = $this->__('Cannot add items.');
Mage::logException($e);
}
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($response));
return;
}
refresh the page is solution because magento use the form key to validate the data
so when login a customer then session is change according to that and it working
let me know if you have more Questions .

Object of class error in Codeigniter with loading function in array

On my Welcome controller I have a function called content_top which loads function $this->$part[0]($setting_info); in this case $this->slideshow($setting_info); Then it should display that slideshow functions view in that data array.
When I have refreshed my page I get a error
A PHP Error was encountered
Severity: 4096
Message: Object of class CI_Loader could not be converted to string
Filename: common/content_top.php
Line Number: 7
Backtrace:
File: C:\wamp\www\cms\application\views\common\content_top.php
Line: 7
Function: _error_handler
File: C:\wamp\www\cms\application\controllers\Welcome.php
Line: 51
Function: view
File: C:\wamp\www\cms\application\controllers\Welcome.php
Line: 19
Function: content_top
File: C:\wamp\www\cms\index.php
Line: 292
Function: require_once
And
A PHP Error was encountered
Severity: 4096
Message: Object of class CI_Loader could not be converted to string
Filename: common/welcome_message.php
Line Number: 3
Backtrace:
File: C:\wamp\www\cms\application\views\common\welcome_message.php
Line: 3
Function: _error_handler
File: C:\wamp\www\cms\application\controllers\Welcome.php
Line: 20
Function: view
File: C:\wamp\www\cms\index.php
Line: 292
Function: require_once
Question Is there any way to when I have a function in array to be able to make it display the view with out throwing error.
<?php
class Welcome extends CI_Controller {
public $data = array();
public function __construct() {
parent::__construct();
$this->load->model('design/model_layout');
$this->load->model('extension/model_module');
$this->load->model('design/model_banner');
$this->load->model('tool/model_image');
$this->load->library('image_lib');
}
public function index() {
$this->load->view('common/header');
$data['content_top'] = $this->content_top();
$this->load->view('common/welcome_message', $data);
$this->load->view('common/footer');
}
public function content_top() {
if ($this->uri->segment(1)) {
$route = $this->uri->segment(1) .'/'. $this->uri->segment(2);
} else {
$route = 'common/home';
}
$layout_id = $this->model_layout->get_layout($route);
$data['modules'] = array();
$modules = $this->model_layout->get_layout_modules($layout_id, 'content_top');
foreach ($modules as $module) {
$part = explode('.', $module['code']);
if (isset($part[1])) {
$setting_info = $this->model_module->get_module($part[1]);
if ($setting_info) {
$data['modules'][] = $this->$part[0]($setting_info);
}
}
}
return $this->load->view('common/content_top', $data);
}
public function slideshow($setting_info) {
static $module = 0;
$data['banners'] = array();
$results = $this->model_banner->get_banner($setting_info['banner_id']);
foreach ($results as $result) {
$data['banners'][] = array(
'banner_image' => $this->model_image->resize($result['banner_image'], $setting_info['width'], $setting_info['height'])
);
}
$data['module'] = $module++;
$data['resize_errors'] = $this->image_lib->display_errors();
return $this->load->view('module/slideshow', $data);
}
}
In the CI when you loading the view and printing as a string then need to pass the third parameter as 'TRUE'.
<?php echo $this->load->view('headers/menu', '', TRUE);?>
Solved
On the controller I had to change a couple things around
I also have had to use a template layout to minimize the views
But on content_top and sideshow function I had to use return and true
return $this->load->view('folder/name', $this->data, TRUE);
Controller
<?php
class Home extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->model('design/model_layout');
$this->load->model('extension/model_module');
$this->load->model('design/model_banner');
$this->load->model('tool/model_image');
$this->load->library('image_lib');
}
public function index() {
$this->data['title'] = 'Home';
$this->data = array(
'column_left' => $this->column_left(),
'column_right' => $this->column_right(),
'content_bottom' => $this->content_bottom(),
'content_top' => $this->content_top(),
'page' => 'common/home'
);
$this->load->view('common/template', $this->data);
}
public function column_left() {
$route = 'common/home';
$layout_id = $this->model_layout->get_layout($route);
$this->data['modules'] = array();
$modules = $this->model_layout->get_layout_modules($layout_id, 'column_left');
foreach ($modules as $module) {
$part = explode('.', $module['code']);
$setting_info = $this->model_module->get_module($part[1]);
$this->data['modules'][] = array (
'module_name' => $this->$part[0]($setting_info)
);
}
return $this->load->view('common/column_left', $this->data, TRUE);
}
public function column_right() {
$route = 'common/home';
$layout_id = $this->model_layout->get_layout($route);
$this->data['modules'] = array();
$modules = $this->model_layout->get_layout_modules($layout_id, 'column_right');
foreach ($modules as $module) {
$part = explode('.', $module['code']);
$setting_info = $this->model_module->get_module($part[1]);
$this->data['modules'][] = array (
'module_name' => $this->$part[0]($setting_info)
);
}
return $this->load->view('common/column_right', $this->data, TRUE);
}
public function content_bottom() {
$route = 'common/home';
$layout_id = $this->model_layout->get_layout($route);
$this->data['modules'] = array();
$modules = $this->model_layout->get_layout_modules($layout_id, 'content_bottom');
foreach ($modules as $module) {
$part = explode('.', $module['code']);
$setting_info = $this->model_module->get_module($part[1]);
$this->data['modules'][] = array (
'module_name' => $this->$part[0]($setting_info)
);
}
return $this->load->view('common/content_bottom', $this->data, TRUE);
}
public function content_top() {
$route = 'common/home';
$layout_id = $this->model_layout->get_layout($route);
$this->data['modules'] = array();
$modules = $this->model_layout->get_layout_modules($layout_id, 'content_top');
foreach ($modules as $module) {
$part = explode('.', $module['code']);
$setting_info = $this->model_module->get_module($part[1]);
$this->data['modules'][] = array (
'module_name' => $this->$part[0]($setting_info)
);
}
return $this->load->view('common/content_top', $this->data, TRUE);
}
/*
Add function for modules that are enabled for this page
*/
public function slideshow($setting_info) {
static $module = 0;
$this->data['banners'] = array();
$results = $this->model_banner->get_banner($setting_info['banner_id']);
foreach ($results as $result) {
$this->data['banners'][] = array(
'banner_image' => $this->model_image->resize($result['banner_image'], $setting_info['width'], $setting_info['height'])
);
}
$this->data['module'] = $module++;
return $this->load->view('module/slideshow', $this->data, TRUE);
}
}
Template View
<?php $this->load->view('common/header');?>
<?php $this->load->view($page);?>
<?php $this->load->view('common/footer');?>
Content Top View
<?php foreach ($modules as $module) {?>
<?php echo $module['module_name'];?>
<?php }?>
Home View
<div class="container">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<?php echo $content_top;?>
</div>
</div>
</div>
Proof Working
This happened to me when I did this:
$model = $this->load->model('user_model);
$data = [
'model' => $model
];
instead of this:
$this->load->model('user_model);
$model = $this->user_model->edit();
$data = [
'model' => $model
];
then when I echoed out the $model, it gave me the error. So I tried to print_r then it gave me a very long array until I realize my mistake. Hope it helps.
Just remove the echo on view page when you are using CI new versions.
<?php $this->load->view('headers/menu');?>
https://stackoverflow.com/a/40675633/2790502

get the values of custom options

I'm trying to alter a price based on some custom options set. Therefore I'm trying to get the value a customer has entered, not the default values set in the backend. To do this I'm using the event catalog_product_get_final_price used in Mage_Bundle_Model_Product_Price. I have registered the following observer:
public function observer_callback($evt_obs)
{
$event = $evt_obs->getEvent();
$data = $event->getData();
/* #var $collection Mage_Catalog_Model_Resource_Product_Collection */
$collection = $data['collection'];
$items = $collection->getItems();
/* #var $item Mage_Catalog_Model_Product */
foreach ($items as $item) {
if ( $item->getName() == 'Bundel Test2') {
$options = $item->getCustomOptions();
/* #var $option Mage_Catalog_Model_Product_Option */
foreach ($options as $option) {
// Here I'm trying to get the value given by the user/customer
var_dump($option->getData());
}
}
}
return $this;
}
It is a custom option from a bundle type. So the product can't be configurable.
I'm new to magento so I'm probably missing something.
Can anyone help me?
Hope this piece of code can help you:
public function productFinalPrice($observer){
$product = $observer->getEvent()->getProduct();
$productType=$product->getTypeID();
if($productType == 'your_product_type')
{
$option = $product->getCustomOptions();
$searchedOption = null;
//search for your option;
foreach ($product->getOptions() as $o) {
if($o->getTitle()=="your_attribute_title" && $o->getType()=="your_type_of_option(eg. area"){
$optionId = $o->getOptionId();//got your searched optionId
break;
}
}
foreach($option as $key => $o) {
if($key == "option_".$optionId) {
$searchedOption = $o;
//here you get the option object with the values in it
}
}
$articleNumber = $searchedOption->getData('value'); // getthe value of your option
//calculate final price like you need it
$product->setFinalPrice($finalPrice);
}
return $this;
}
best regards

How to auto fill shipping method Magento for onepagechekout

I want to auto fill the shipping method automatically and not show it on the onepage checkout. I was able to hide the shipping method on my Onepagechekout by changing this on app/code/local/Mage/Checkout/controllers/OnepageController.php:
/**
* save checkout billing address
*/
public function saveBillingAction()
{
if ($this->_expireAjax()) {
return;
}
if ($this->getRequest()->isPost()) {
// $postData = $this->getRequest()->getPost('billing', array());
// $data = $this->_filterPostData($postData);
$data = $this->getRequest()->getPost('billing', array());
$customerAddressId = $this->getRequest()->getPost('billing_address_id', false);
if (isset($data['email'])) {
$data['email'] = trim($data['email']);
}
$result = $this->getOnepage()->saveBilling($data, $customerAddressId);
if (!isset($result['error'])) {
/* check quote for virtual */
if ($this->getOnepage()->getQuote()->isVirtual())
{
$result['goto_section'] = 'payment';
$result['update_section'] = array(
'name' => 'payment-method',
'html' => $this->_getPaymentMethodsHtml()
);
} elseif (isset($data['use_for_shipping']) && $data['use_for_shipping'] == 1)
{
$result['goto_section'] = 'payment';
$result['update_section'] = array(
'name' => 'payment-method',
'html' => $this->_getPaymentMethodsHtml()
);
$result['allow_sections'] = array('shipping');
$result['duplicateBillingInfo'] = 'true';
} else {
$result['goto_section'] = 'shipping';
}
}
$this->saveShippingMethodAction();
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
}
}
As you can see I changed the link where I redirect the next step after billing action to the payment step.
In order to auto-save a shipping method, I added
$this->saveShippingMethodAction();
at the end of the function, and this method looks like here:
public function saveShippingMethodAction()
{
$this->_expireAjax();
if ($this->getRequest()->isPost()) {
/* $this->savePaymentAction(); */
$data = $this->getRequest()->getPost('shipping_method', 'flatrate_flatrate');
$result = $this->getOnepage()->saveShippingMethod($data);
$this->getResponse()->setBody(Zend_Json::encode($result));
}
}
So what I did is try to include automatically flatrate_flatrate method as the default one.
But when I try to finish a sale, it says I didn't specify a shipping method. Any idea on why it doesn't work?
Now you need to force the shipping_method in the quote and in the session :
$forcedMethod = "your_method_code";
$this->getOnePage()->getQuote()
->getShippingAddress()
->setShippingMethod($forcedMethod)
->save();
Mage::getSingleton('checkout/session')->setShippingMethod($forcedMethod);
And just before you call :
$this->saveShippingMethodAction();
add a :
$this->getRequest()->setPost('shipping_method', $forcedMethod);
It should work ;)

Resources