How to run Magento (version 1.4.0.1) session into an external site?

42 Comments

This post is an update for my blog entry on how to extend the Magento session to an external site but instead of using the version 1.2.1.2, I used the the latest stable version as of this writing which is version 1.4.0.1. The script below also implements the login() and logout() method the Magento way as well as extracting the customer data (firstname and lastname) using getCustomer() method.

<?php
// Include Magento application
require_once ( "/var/www/your-magento-directory/app/Mage.php" );
umask(0);

// Initialize Magento
Mage::app("default");

// You have two options here,
// "frontend" for frontend session or "adminhtml" for admin session
Mage::getSingleton("core/session", array("name" => "frontend"));
$session = Mage::getSingleton("customer/session");

if(!isset($_REQUEST['action'])) {
	$_REQUEST['action'] = '';
}

switch($_REQUEST['action']){
	case "login":
		try{
			// Do login request.
			// I know, there are ways to sanitize the form.
			// But for simplicity's sake, let's assume we already
			// did our homework regarding the matter.
			$login = $session->login($_POST['username'],$_POST['password']);
		}catch(Exception $e){
			// Do something for the error message
			$message = $e->getMessage();
		}

		header("location: index.php");

		break;
	case "logout":
		// Execute the logout request
		$session->logout();
		header("location: index.php");

		break;
	default:
		// If the customer is not logged in, show login form
		// else, show logout link
		if(!$session->isLoggedIn()){
		?>
			<html>
			<head>
			<title>External Page for Magento</title>
			</head>
			<body>
			<h3>Login here</h3>
			<form method="POST" action="index.php">
			Username <input type="text" name="username" size="10" />
			Password <input type="password" name="password" size="10" />
			<input type="submit" name="submit" value="login" />
			<input type="hidden" name="action" value="login" />
			</form>
			</body>
			</html>
<?php
		}else{
			$firstname = $session->getCustomer()->getData('firstname');
			$lastname = $session->getCustomer()->getData('lastname');
			echo "Welcome ".$firstname." ".$lastname."!<br>";
			echo "You're currently logged in ";
			echo "[ <a href=\"index.php?action=logout\">click here to logout</a> ]";
		}
}
?>

Just copy the whole script and save it as index.php and run the script.

42 Comments (+add yours?)

  1. Jason
    Mar 31, 2010 @ 22:12:49

    Hi Richard,

    Thank you very much for this helpful post!

    Unfortunately, I’m running into a similar issue as Tim from the last post. Where the script works in the WordPress directory in a separate file, but when I simply call the file from my theme, I end up with a blank page. All I’m trying to do is log the user into Magento at the same time they’re logging into my website. Here’s my code:

    require_once(“../unanchor/magento/app/Mage.php”);
    umask(0);
    Mage::app(‘default’);
    Mage::getSingleton(‘core/session’, array(‘name’ => ‘frontend’));
    $loggedin = Mage::getSingleton(‘customer/session’)->login($user,$pass);

    Any thoughts or suggestions?

    Thanks again!
    Jason

    Reply

    • Richard Feraro
      Mar 31, 2010 @ 23:00:35

      Hello Jason! Thanks :)

      If you’re getting a blank page, it means that there is an error in your code. Try setting the PHP error_reporting to ‘all’ just like what I suggested to Tim Jukes from the original post. It may provide clue to the error. Also, I believe there’s a function collision with Magento and WordPress but I haven’t tested it though.

      Regarding your script, it should work well but I usually initiate the login separately like the sample below:

      your script:
      $session = Mage::getSingleton(‘customer/session’)->login($user,$pass);

      my suggestion:
      $session = Mage::getSingleton(‘customer/session’);
      $session->login($user,$pass);

      so you can reuse $session for checking the login status like $session->isLoggedIn(), this is the proper format for version 1.4.0.1.

      Reply

  2. alain
    Apr 03, 2010 @ 05:32:25

    Thanks for your great post!
    I’m using magento for an Intranet system and want to log user to magento using another CMS.
    Got you script to work but can’t figure how to detect if user is logged or not in magento.
    I added this in magento header.phtml to check for user login and limit access but keep getting “Not logged in”:

    $session = Mage::getSingleton(“customer/session”, array(“name”=>”frontend”));
    if($session->isLoggedIn())
    {
    echo “Logged in”;
    }else{
    echo “Not logged in”;
    }

    Any suggestions?

    Thanks

    Reply

    • Richard Feraro
      Apr 03, 2010 @ 12:49:21

      Hello Alain! Thank you :)

      Did you use the login() function of Magento? I think 1.4.0.1 requires that for isLoggedIn() to work. Also keep in mind that you need the Mage.php in all pages that uses the Magento functions.

      If you’re running it thru localhost, please check my post regarding running Magento via localhost. Is your page capable of creating cookies when you run it?

      Reply

      • alain
        Apr 04, 2010 @ 09:06:09

        Hi Richard,
        what I don’t understand is that when I print the session it is different in the file that uses your code and on the Magento side. Your side as the customer info in it not the Magento side.
        Basically have 2 different session is it the same for you?

        Thanks

        Reply

      • Richard Feraro
        Apr 04, 2010 @ 14:03:02

        What do you mean when you said, “Magento side”? Remember there two types of session there. The admin and the frontend creates two different types of session so basically you can’t compare the session created by your external file and whichever of the two sessions (frontend or adminhtml) you’re referring to as ‘Magento side’.

        For example, my root folder is htdocs, my actual Magento files resides in ‘htdocs/magento’ folder and the finally external application that uses the Mage.php is placed in ‘htdocs/other’ folder. In this setup, when I run Magento’s frontend, it is running at http://localhost/magento/, right? This creates a session ‘frontend’ for a customer. If I run the admin page at http://localhost/magento/admin, this generates the ‘adminhtml’ session. So at this point we already have two different session and two different cookies. So by concept, if I run my external application using the Mage.php file which instantiates ‘frontend’ session depending on the getSingleton() method, I’ll be running it thru http://localhost/other which in turn generates a different customer session because it has a different cookie location. To check if this is true, look at this image and check the ‘path’ column in the firebug cookie tab. The admin has ‘/magento’ cookie path, in our example external application it will be ‘/other’.

        http://mysillypointofview.files.wordpress.com/2010/03/magento-admin-login-with-cookie.png

        Reply

  3. alain
    Apr 05, 2010 @ 00:55:34

    Thanks, that’s what I though I can’t have have Magento use the Session generated by your script .
    Do you have any idea how I would go to make my Magento catalog side password protected ?

    Thanks

    Alain

    Reply

    • Richard Feraro
      Apr 05, 2010 @ 18:06:43

      Is it for an external site or the actual Magento catalog page?

      Reply

  4. Sanjoy
    Apr 05, 2010 @ 19:46:32

    using Magento ver. 1.4.0.1, getting the following error when i try to logout the admin :

    Invalid method Mage_Admin_Model_Session::logout(Array ( ) )

    Any thoughts?

    Reply

    • Richard Feraro
      Apr 05, 2010 @ 20:16:41

      Hello Sanjoy!

      Can you provide more details to your inquiry? I believe there’s more infomation found inside the logout(…) when this error occured in your page.

      Thanks.

      Reply

      • Sanjoy
        Apr 06, 2010 @ 19:02:38

        Well, I am sorry it does not give any thing more than that error. I am actually trying to log in to the magento admin from my own CMS application which i successfully did but was unable to find an way to log out the admin when i logged out of my CMS application , so i tried the code you had posted here, but it errors out with the exception “Invalid method Mage_Admin_Model_Session::logout(Array ( ) )”. Since the error says invalid method , i searched for the logout method in adminhtml, but didn’t get any, could this be the reason?

        Reply

      • Richard Feraro
        Apr 06, 2010 @ 23:01:03

        Hi Sanjoy,

        I think you didn’t actually use my code above but rather created a different one to simulate an administrator logging in to an external site. I was able to recreate your error on my end using the code below:

        // Show all errors
        error_reporting(E_ALL);
        // Include Magento application
        require_once ( "path/to/your/app/Mage.php" );
        umask(0);
        
        // Initialize Magento
        Mage::app("default");
        
        // You have two options here,
        // "frontend" for frontend session or "adminhtml" for admin session
        Mage::getSingleton("core/session", array("name" => "adminhtml"));
        $session = Mage::getSingleton("admin/session")->logout();

        the code above produces this error:

        Fatal error: Uncaught exception 'Varien_Exception' with message 'Invalid method Mage_Admin_Model_Session::logout(Array ( ) )' in path:\to\your\magento\lib\Varien\Object.php:542 Stack trace: #0 [internal function]: Varien_Object->__call('logout', Array) #1 path:\to\your\externalsite\index.php(13): Mage_Admin_Model_Session->logout() #2 {main} thrown in path:\to\your\magento\lib\Varien\Object.php on line 542

        Is the error similar on your end?

        Reply

      • Sanjoy
        Apr 07, 2010 @ 14:06:34

        Yes, that’s the error i am getting. I didn’t get all the details about the error because i was doing a try catch and was printing the exception only, but yes that’s what i was trying to do, i just replaced the frontend calls shown in your code to backend calls going by the comments (// “frontend” for frontend session or “adminhtml” for admin session) in in your code.

        Reply

        • Richard Feraro
          Apr 11, 2010 @ 05:47:40

          @Sanjoy: please refer to sonassi’s instruction where got the code.

  5. Jason
    Apr 14, 2010 @ 09:08:25

    Hi Richard,

    This is slightly off-topic, but since you seem very knowledgeable I figured I’d give it a shot.

    Can you use the above method to also check if there are items in the cart? Here’s what I’m trying to do:

    require_once(“$magpath”);
    umask(0);
    Mage::app(‘default’);
    Mage::getSingleton(‘core/session’, array(‘name’ => ‘frontend’));
    $session = Mage::getSingleton(‘customer/session’);

    if ((Mage::getSingleton(‘checkout/cart’)->getItemsCount()) > 0)
    $cart = TRUE;
    else
    $cart = FALSE;

    This isn’t working though, any thoughts?

    Thanks again, your posts have been extremely helpful!
    Jason

    Reply

    • Richard Feraro
      Apr 14, 2010 @ 10:12:34

      Hi Jason,

      Checkout my comments within the code below:

      // Remove the quote since this is a variable
      require_once($magpath);
      umask(0);
      Mage::app("default");
      Mage::getSingleton("core/session", array("name" => "frontend"));
      // Use this as your session below
      $cart_session = Mage::getSingleton("checkout/session");
      // Use the $cart_session, access the quote, check item's count
      // getItemsQty() = get total quantity as a whole
      // getItemsCount() = get total unique quantity
      if($cart_session->getQuote()->getItemsCount() > 0)
          $cart = TRUE;
      else
          $cart = FALSE;

      Thank you Jason for the feedback.

      Reply

  6. stephan
    Apr 18, 2010 @ 15:50:25

    Hello Richard,

    What a great post !

    I would like to know if we can hire you :) for a custom installation with WP/Magento

    My email contact: pecqhkg@gmail.com

    Reply

  7. Pete
    May 10, 2010 @ 20:23:54

    Great post!

    Is there a way to extend the web API to carry out the login authentication and session creation, as I need to set this up from a non-PHP website (running asp.net)?

    Cheers,

    Pete

    Reply

    • Richard Feraro
      May 10, 2010 @ 22:35:11

      For non-PHP site, use the Magento Core API which utilizes SOAP and XML RPC protocols. It’s somewhat slower compared to running it in a manner I posted here in the article because of how web services work.

      Reply

  8. Madhu
    May 18, 2010 @ 12:39:53

    how do i access image from this session..right now i can get product name its quantity i have to display image and a delete button (same like my cart :) )how do i access image?

    Reply

  9. Madhu
    May 18, 2010 @ 12:48:53

    To be more specific I am trying to implement ajax add to cart…I am able to add products to cart again i have to refresh mycart widget..so i have come half way through as I have told i need to access image and a delete button.. so how do i access it?

    Reply

    • Richard Feraro
      May 21, 2010 @ 16:33:11

      Use the load() method for catalog/product model:

      $product = Mage::getModel(‘catalog/product’);
      $product->load(3); // this could be any product ID
      // get product image url, note this produces an image with a width of 265px
      echo $product->getImageUrl();

      Reply

  10. Michael
    Aug 17, 2010 @ 10:58:53

    Richard, thanks so much for all the hard work, WP Mage-Enabler is a lovely plugin and all of your help on this blog is so appreciated!

    I am having trouble detecting if a user is logged in (or not) from WP, the following code (yours) seems to always return false no matter what I try (Mage Enabler is working, and enabled, etc), any hints? Seems to just be a completely different session than Magento (possibly because Magento is in a subdirectory?). Thanks!

    Mage::getSingleton("core/session", array("name" => "frontend"));
    $session = Mage::getSingleton("customer/session");
    echo 'isLoggedIn? '.$session->isLoggedIn();
    $helper = Mage::helper('customer');
    echo 'isLoggedIn? '.$helper->isLoggedIn();

    Reply

    • Richard Feraro
      Aug 17, 2010 @ 20:46:05

      Hi Michael, thanks for the feedback.

      May I know your Magento version? Also, try this one:

      // Customer Information
      $firstname = "John";
      $lastname = "Smith";
      $email = "johnsmith@localhost.local";
      $password = "myverysecretpassword";
      
      // Website and Store details
      $websiteId = Mage::app()->getWebsite()->getId();
      $store = Mage::app()->getStore();
      
      $customer = Mage::getModel("customer/customer");
      $customer->website_id = $websiteId;
      $customer->setStore($store);
      
      try {
      	// If new, save customer information
      	$customer->firstname = $firstname;
      	$customer->lastname = $lastname;
      	$customer->email = $email;
      	$customer->password_hash = md5($password);
      	if($customer->save()){
      		echo $customer->firstname." ".$customer->lastname." information is saved!";
      	}else{
      		echo "An error occured while saving customer";
      	}
      }catch(Exception $e){
      	// If customer already exists, initiate login
      	if(preg_match('/Customer email already exists/', $e)){
      		$customer->loadByEmail($email);
      
      		$session = Mage::getSingleton('customer/session');
      		$session->login($email, $password);
      
      		echo $session->isLoggedIn() ? $session->getCustomer()->getName().' is online!' : 'not logged in';
      	}
      }

      At the initial run of the script above, a new customer will be created if the email doesn’t exists in your customer database. It should show John Smith information is saved!. Refreshing the same page should run the login method and display John Smith is online! if successful, not logged in if not.

      Reply

  11. Michael
    Aug 22, 2010 @ 00:47:40

    Richard,

    The trouble is that the login is still occuring through the normal Magento login, so I never get the email passed to me. Thing is I have a topnav that changes based on the user’s logged in status, so I need to detect whether the user is logged into the magento store at /shop/ on all pages including those that site at the site root (not sure if the subdirectory thing is even relevant).

    If I print_r the $session from inside WP its pretty empty, whereas doing it from inside a Magento page shows a whole ton of stuff (eg the actual customer info). So it seems to just not be pulling in the session properly…

    Thanks again for all your help!

    Reply

    • Michael
      Aug 22, 2010 @ 02:15:09

      O sorry RIchard, I forgot to mention its Magento 1.4.1.1, thanks again!

      Reply

    • Richard Feraro
      Aug 22, 2010 @ 02:27:58

      Question, are you trying to run Magento to an external site? Or using the Mage Enabler? I get confused maybe because you’re in a different thread. If yes, please confirm so I can move the whole conversation to the other post for Mage Enabler :)

      Reply

      • Michael
        Aug 22, 2010 @ 21:39:35

        Sorry for not being clear, I am in fact using Mage Enabler

        Reply

        • Richard Feraro
          Aug 23, 2010 @ 19:09:30

          May I see the code you’re using inside a WP page (include the filename if it’s a default file within WP?)

    • Michael
      Aug 24, 2010 @ 10:41:00

      Ahh, sorry Im just cluttering up your blog—feel free to delete the messed up ones!

      head.php:

      <?php
      if (class_exists('Mage')) {
      Mage::getSingleton("core/session", array("name" => "frontend"));
      $session = Mage::getSingleton("customer/session");
      }
      ?>
      <!DOCTYPE html>
      <html <?php language_attributes(); ?>>
      <head>
      <meta charset="<?php bloginfo( 'charset' ); ?>" />
      <title><?php wp_title( '|', true, 'right' ); bloginfo('name'); ?></title>
      <link rel="profile" href="http://gmpg.org/xfn/11" />
      <link rel="shortcut icon" type="image/x-icon" href="/shop/skin/frontend/default/xxx/favicon.ico" />
      <!–<link rel="stylesheet" type="text/css" media="all" href="<?php bloginfo( 'stylesheet_url' ); ?>" />–>
      <link rel="stylesheet" type="text/css" media="all" href="/shop/skin/frontend/default/xxx/css/styles.css" />
      <link rel="stylesheet" type="text/css" media="all" href="/shop/skin/frontend/default/xxx/css/pluit-carousel.css" />
      <link rel="stylesheet" type="text/css" media="all" href="/shop/skin/frontend/default/xxx/css/shadowbox.css" />
      <link href='http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz' rel='stylesheet' type='text/css'>
      <link href='http://fonts.googleapis.com/css?family=Reenie+Beanie' rel='stylesheet' type='text/css'>
      <script type="text/javascript" src="/shop/js/prototype/prototype.js"></script>
      <script type="text/javascript" src="/shop/js/prototype/validation.js"></script>
      <script type="text/javascript" src="/shop/js/scriptaculous/builder.js"></script>
      <script type="text/javascript" src="/shop/js/scriptaculous/effects.js"></script>
      <script type="text/javascript" src="/shop/js/scriptaculous/dragdrop.js"></script>
      <script type="text/javascript" src="/shop/js/scriptaculous/controls.js"></script>
      <script type="text/javascript" src="/shop/js/scriptaculous/slider.js"></script>
      <script type="text/javascript" src="/shop/skin/frontend/default/xxx/js/pluit-carousel.js"></script>
      <script type="text/javascript" src="/shop/skin/frontend/default/xxx/js/shadowbox.js"></script>
      <script type="text/javascript" src="/shop/skin/frontend/default/xxx/js/global.js"></script>
      <?php wp_head(); ?>
      </head>
      
      header.php:
      <div class="header-container">
      <div class="top-nav-container">
      <?php if (class_exists('Mage')) :
      $top_nav_id = ($session->isLoggedIn()) ? 'top-nav-logged-in' : 'top-nav-logged-out';
      // echo 'is?'.$session->isLoggedIn();
      $helper = Mage::helper('customer');
      // echo 'is?'.$helper->isLoggedIn();
      endif;
      wp_nav_menu( array( 'container_class' => 'top-nav links', 'theme_location' => $top_nav_id ) ); ?>
      </div>
      <div class="header">
      <h1 class="logo"><strong><?php bloginfo('name'); ?></strong><a href="<?php echo get_option('home'); ?>" title="<?php bloginfo('name'); ?>" class="logo"><img src="<?php echo get_option('home'); ?>/shop/skin/frontend/default/xxx/images/logo.gif" alt="<?php bloginfo('name'); ?>" /></a></h1>
      <?php wp_nav_menu( array( 'container_class' => 'main-nav links', 'theme_location' => 'main-nav' ) ); ?>
      </div>
      </div>
      
      <body <?php body_class(); ?>>
      <div id="wrapper">
      <div class="page">

      Reply

      • Richard Feraro
        Aug 24, 2010 @ 19:39:56

        To display code, you may use [php]your-code-here[/php]

        Reply

      • Richard Feraro
        Aug 24, 2010 @ 19:57:32

        Is your Mage.php absolute URL working? What’s the output when you save the URL in the Mage Enabler admin plugin page?

        Once you’ve checked that the needed parameter (URL) of the plugin is indeed correct, try adding the code below inside one of your theme files. It should show Mage and Varien_Autoload in the list.

        <?php print_r(get_declared_classes()); ?>

        Reply

        • Michael
          Aug 25, 2010 @ 08:49:50

          Mage Enabler is definitely working well (thanks again!) as later on that page I have a little scrollbar thing that pulls out a bunch of prodcuts, which has been working flawlessly from day one. 

          Both Mage and Varien_Autoload are listed in the declared classes, so still no idea why its giving me trouble—weird right?!

        • Richard Feraro
          Aug 25, 2010 @ 15:19:30

          Your scripts’ logic in checking whether a user is online or not seems okay and Mage’s session is running in your page. How about your login script? May I see it?

        • Michael
          Aug 25, 2010 @ 22:00:51

          Hmm, I am actually just using Magento’s login. So the user logs in at domain.com/shop/customer/account/login but I was hoping that session could carry over to all pages including those at domain.com/ (/shop is Magento root folder). That the problem (I still dont get why)?

        • Richard Feraro
          Aug 25, 2010 @ 22:42:20

          I see, now I understand. Mage Enabler, like what its description says, only runs the Magento’s session inside your WordPress. Magento’s session means the Mage object (Mage and Varien_Autoload), the one you see when you ran get_declared_classes() so it’s perfectly working on your end. No wonder you say it isn’t working because you didn’t do any programming at all for the login.

          Try reading some of the info here. It may enlighten you on how to do it.

        • Michael
          Aug 26, 2010 @ 01:34:46

          Aha, except mine would be more like the opposite of that post of yours. I dont even really need people to be able to login to WP, just detect their logged in status in Magento. If I were to have to go through WP it would also mean making the user registration mirror from Magento to WP, which sounds like a lot of work. Am I missing something here? Any kind of workaround you can think of?

          Thanks again for your help

        • Richard Feraro
          Aug 26, 2010 @ 01:50:08

          You can’t detect from WordPress who’s online in Magento because the two has different cookie session path. Your shop’s cookie path is in ‘/shop’ while WordPress is in the www root ‘/’. The purpose of Mage Enabler is to do the manipulation of session (i.e. login, registration, product query etc.) within WordPress thru Mage object, not the other way around.

        • Richard Feraro
          Aug 26, 2010 @ 01:51:27

          The login script must be executed within WordPress and then pass thru Mage session.

        • Michael
          Aug 26, 2010 @ 07:35:22

          Richard, thanks so much for all your help. What I ended up doing, now that you helped me figure out the problem was to add an event hook Observer to Magento for login / logout and have this set a custom cookie that WP then checks for later. Works pretty well!

          Thanks again for all your help

Leave a Reply