Using Custom PHP Codes on Magento

Magento is one of the newest and awarded ecommerce application right now. And I seem to have a project launched nowadays about it.

Above the ecommerce part like adding/modifying products, it also has a built-in CMS. It looks quite useful. Not very powerful though.  It just evaluates html code and not php. In most of the time this is prefered by the way. Because of security risks and things like that. But there are also cases which you want to do if you are importing something to magento or if you are just wanting to do in a quick and dirty way!

Well, the workarounds you find are not quite good. Simply they just take the CMS code, write it to a temporary file and include it, or writing a bit complicated parser inspired from joomla/mambo. Check out here for the details of the workaround. The tutorial I’m putting here is from there to, however I will also try to write solutions to problems that I have encountered (mostly because of magento versions).

This tutorial is working for magento version 1.1.8. You can download the latest version from here.

Now open up your favorite php/xml/html editor. While it will open up, also open your magento installation folder. Magento has a lots of folders for lots of things, which I do not know why. The code part is in app/ directory as you may guess. In the app folder you will find the etc/ where there are configurations for magento generally. Our PHP Code will be a module to the Magento, so we have to go modules directory and create a new xml file, named according to your module. The syntax is like: Parkyeri_customPHP. The first part till underscore means the name of the module, int this case Parkyeri. The second part indicates the component of the module. So you may have different components in one module, in this case customPHP, If we are talking about custom codded PHP pages, so in this module named Parkyeri, there can be different pages like: About, Contact, Jobs. And these are all different components, doing different things. If we were trying to create the About page then we had to use something like Parkyeri_About. You can add all of them in the same xml file.

Open up /app/etc/modules/ and create a file named Parkyeri.xml (the name of the module) and add these lines to file:




    
        true
        local
        
    

But what this means? You declare a new module named Parkyeri to the global site by naming the file Parkyeri.xml. Then you define in the module config file that, this module has a component named customPHP. You say that this component is active and the system can find it in the app/code/local directory by looking at the codepool

As you get it now we pass to the next stage. Now open up app/code/local/Parkyeri/customPHP/etc/ and create a file named config.xml (the default configuration file name for every module.) and add these lines in it.



    
        
            
                Parkyeri_customPHP_Block
           
       
    

What does it mean? This is more of a mapping file than a configuration file. What you are doing here is to map (you may also think bind) a class named Parkyeri_customPHP_Block to a block called parkyeri_customphp. So whenever a block of type parkyeri_customphp will be called, this block will look out for the class you defined in this configuration/mapping/binding file. But also you are defining the location of the component files that you want to call. In most of the cases, you want to call a component’s block from a module. So when calling you will say that I want a component named customPHP, and a block named test and this component is under the module Parkyeri. We move on…

Now the fun part, open up app/code/local/Parkyeri/customPHP/Block and create a file named Test.php and add these lines in it:


class Parkyeri_customPHP_Block_Test extends Mage_Core_Block_Abstract
{
    protected function _toHtml()
    {
        //put here your custom PHP code with output in $html;
        //use arguments like $this->getMyParam1() , $this->getAnotherParam()
        $html = "Hello" . $this->getWorld();
        return $html;
    }
}

So, we have finally reached the part which you are most comfortable, writing code! You will write down all the code you want to evaluate in this file. The _toHtml() method is called when you call it in the cms part. A magical function just like toString(). As you may remark the name of the class, is conventional according to the location of the class. That was how the previous configuration knew where to look when mapping.

And the final part is to embed it in the CMS, this is easy part. But the part where you get dissapointed most. Add this to page you want to show your custom php code:

{{block type="parkyeri_customphp/test" world="World"}}

So, it’s obvious isn’t it? In this code part, you say that, you want to put a block here. The type of this block is parkyeri_customphp/test. So actually you want a block named test under the customphp component which also a part of parkyeri module.  But you may be curious of the rest, on what I mean by saying, world. I’m sending a parameter to the class. Remember the code where there was $this->getWorld(). This world is that world!. So the code will print out “Hello World” (without an exclamation).
So this was it! Did it worked? No I didn’t did it? The real reason that it did not worked, is because, you did not refresh the caching system!! Yes, it’s that simple! It gave me a lots of headache though, hope it won’t to you. You can disable the caching from System -> Cache Management by the way.  Better then refreshing every time :)
If you are stuck on somewhere you should really check out magento forums. There are really helpful people out there from real developers, ceos and community experts.

Update: I have tested this code sample with 1.1.8 and all works fine.

  • Ranjan Goyal

    Hi,

    I want to register a session in magento. How can I do it?

    Regards,
    Ranjan

  • admin

    I’m not totally sure If I get what you mean.

    So if you mean that how you could set a session variable in php, you may use the codes above to create a custom page like that. And in the _toHTML() function you can always set a session variable $_SESSION[‘session’] like this. But I don’t think that’s what you are talking about.

    I really have no idea. Maybe Magento forums will be more helpful than me. There are lots of people who are really helpful out there.

    Roy

  • Pingback: How to Customize Magento Product Page | Kingdom of Roi()

  • david

    Thanks! Do you have any thoughts/opinions/advise on code management and deployment for magento?

  • admin

    @david

    It really looks easy to customize magento code for yourself. The problem is first to understand how the code works. How the configuration files are used, what blocks are around, what are the files which gives the output. It’s a bit complicated.

    There are lots of database tables, it’s not easy to see the relations between them and other kind of things. The reason that its hard for me is that I’m a stranger to the core code of Magento. I’m sure that it will get easier with each time I do something on it.

    The best way to understand is through making something. I suggest that you try to customize your magento. Like changing the html layout or other kind of simple things.

    When you get an understanding of how the core code and work flow works, it’s really easy to customize it. (Which I did not understood it very well yet.) You can always extend the core object and derive your own class. Then you bind your newly created class instead of the core class and this is it! Your customized class is used in all the places where the core class was used. So this way you can always update magento without having fear to lose your own code. I guess that’s the part where magento is powerful. Because in all most of the open source project there is no such thing. I used a heavily modified phpbb portal for 2 years, I was trying to develop it, but the phpbb team was so good that all the free time I had was passing in updating to the new phpbb :)

    Above that, it really gives you everything you need to create an online ecommerce application. The only missing part is the auction but as community grows and does understand better the core concepts, it will be easier to write it I suppose I had an intention to make it but I don’t know have enough of the understanding yet.

    I hope I was able to help.

    Roy

  • ruchi

    Would appreciate your help in understanding where exactly do I need to put the code {{block type=”parkyeri_customphp/test” world=”World”}}.

    am not able to see any output by doing the following.

    I did put the following code in the content part of one of the CMS page :

    HELLO RUCHI …………………..

    {{block type=”parkyeri_customphp/test” world=”World”}}

    HELLO AGAIN !!

    Your help is needed, Thanks in advance. Please HELP.

  • admin

    @ruchi

    You add this block part to the textarea that comes when you edit the cms page.

    Perhaps there is a problem with system cache thing. It had passed days before I finally figured out it was because of the caching.

    Be sure that the type=”” part is correct. Be sure that your module name is parkyeri and component name customphp. And under customphp folder there is block folder and under it a test.php file which contains your php code. I’m not very sure but it must be case sensitive. You must check the cases you have written in the xml configs.

    hope that helps.

    Roy

  • manu

    sir,

    i had done all the steps that you said.But i got the following error.
    Warning: simplexml_load_string() [function.simplexml-load-string]: Entity: line 1: parser error : XML declaration allowed only at the start of the document in C:\wamp\www\magento\lib\Varien\Simplexml\Config.php on line 501
    Trace:
    #0 [internal function]: mageCoreErrorHandler(2, ‘simplexml_load_…’, ‘C:\wamp\www\mag…’, 501, Array)
    #1 C:\wamp\www\magento\lib\Varien\Simplexml\Config.php(501): simplexml_load_string(‘ loadString(‘ loadFile(‘C:\wamp\www\mag…’)
    #4 C:\wamp\www\magento\app\code\core\Mage\Core\Model\Config.php(171): Mage_Core_Model_Config->_loadDeclaredModules(Object(Mage_Core_Model_Config_Base))
    #5 C:\wamp\www\magento\app\code\core\Mage\Core\Model\App.php(236): Mage_Core_Model_Config->init(Array)
    #6 C:\wamp\www\magento\app\Mage.php(424): Mage_Core_Model_App->init(”, ‘store’, Array)
    #7 C:\wamp\www\magento\app\Mage.php(443): Mage::app(”, ‘store’, Array)
    #8 C:\wamp\www\magento\index.php(52): Mage::run()
    #9 {main}

    Please give a solution to this problem

  • admin

    @manu

    This might be a problem about your xml file. Some missing “>” or “<", maybe an unclosed tag. Please check that your config.xml and Parkyeri.xml (or the name of the module you are creating) sytax is valid. An xml editor might be useful to find syntax problems too.

  • mstanchi

    Hello, I am in need of some advice. With Magento what is the best way (request variable php?) to provide a custom url (for embedded discount code for banner ad (ie click here and receive 10% off)? Right now I utilize the promotion codes/discount box in the shopping cart but I want to be able to create customized urls.

    thanks for any guidance, Matt

  • manu

    sir,i had solved it…thanks..

    There is one more problem.I have to add some products to my website.When adding products, the images are not able to add with this new products. Please help immediateley.Please give a detailed solution to this problem.

    manu

  • admin

    @mstanchi

    Even I’m still not an expert, perhaps the link you are giving can set a predefined promotion code on backend. I’m not very sure how you can do this as I’m not familiar with the promotion part. But the best way looks like is the condition part of the promotion rules. Something like “if a link visited” matches your request I guess. But how you can do it, I don’t know. I guess you have to look on magento’s forums and wikis.

    @manu
    Can you be a bit more specific? Once you click on browse, and add files, you have to upload them. Perhaps you have missed it. I had missed that :) Again it might be possible that the folder which the files are uploaded cannot be written (chmod problems). Or perhaps there is a bug with your current magento installation(I was unable to open browse files pane with magento 1.1.6 and don’t know why yet.)

  • Wilson

    This is great work got it all working, But how would you add more than one component to a cms page though? thansk.

  • admin

    Defining another component to the same module is similar.

    You had used the and xml file defining your module (/app/etc/modules/Parkyeri.xml in this case.) All you have to do is define another part to this module just like you have added parkyeri_customphp.

    Let’s say if your component’s name will be “myphp” than you should add someting like this to Parkyeri.xml below “</Parkyeri_CustomPHP>”:

    <Parkyeri_myphp>
    <active>true</active>
    <codePool>local</codePool>
    </Parkyeri_myphp>

    It won’t be enough of course you should also add additional entryies to the /app/code/local/Parkyeri/myphp. Configuration files and block files. You should go on just like you did for the customphp part.

    Hope that this helps

  • macfred

    Hello,

    I am trying to use that module to add some personnal information in a CMS page. It seems to work perfectly, but i have problems to reach the user firstname.

    I used that code, but it doesn’t seem to work…

    $html = “Hello” . $this->getCustomer(‘firstname’);

    Any idea?

  • admin

    Hi,

    When you are calling your module in the cms page you should use somehing like this:

    {{block type=”parkyeri_customphp/test” world=”World”}}

    While you want to get that “world” parameter, you are using getWorld(). I don’t know if you can send arguments to that functions but if you are using something like this:

    {{block type=”parkyeri_customphp/test” firstname=”Roy”}}

    then you have to call:

    $this->getFirstname(); //This will return "Roy"
    

    I don’t think if the below code works, but it does not really make sense

    {{block type=”parkyeri_customphp/test” customer/firstname=”Roy”}}

    Hope that this helps.

  • Hi,
    I have followed the above and still cant get my page to output anything :(

    is this valid for the latest version of magento?

  • admin

    Hi,

    I have not tested for the latest version (1.1.8) but I will give it a try when I get a spare time. I had tested it with 1.1.6 and it was ok. I don’t think they have putted a major change but I will give it a try You should check if you have done everything and refreshed the cache. Perhaps this is the case.

  • Anjanesh

    I have a situation where I want the top-menu displayed at the bottom on all CMS pages and at the top for all non-CMS pages.

    Is there a way to detect like
    if ($this->pageType = ‘CMS’) inside CMS or other phtml files ?

  • admin

    I don’t know to be exact. There is always a bad for this of course, using javascript changing the location of a div with an id. But you shouldn’t do it until you are very desperate.

    When I get time I will look out for it but it would be better if you had searched the magento forums about this.

  • admin

    Hi, Finally I was able to check for 1.1.8 version and it works without any problems. just to inform new users. Still I’m not yet able to check for page type thing.

  • Saggy

    Hey Dude,

    Very useful article. Thanks for sharing. But unfortunately there is bits and pieces missing in this because you haven’t created .phtml file so which means this component is not ready to be used in CMS -> Managed Pages.

    Hi All,

    I found this article very useful but explaination in this article is very useful.

    http://www.exploremagento.com/magento/simple-custom-module.php

  • admin

    @saggy

    You are right I have never intended to use a phtml file in this article so I have not looked on that part, And the link you have given shows hot to add it very well! When I will have time I will add the phtml part and it will put the missing parts together. thanks :)

  • tal

    I am trying to include an external php file into the phtml file I created.

    Include(‘http://www………’ )

    I get an error that file cannot be found in the magento folder app/code/local. Seems that magento is only allowing php includes from its own path.

    Any way to go around this?

    Thanks.

  • It’s possible that Magento prevents including remote files but I’m not really sure. It’s most probably about allow_url_fopen. You could try to change the value from php.ini (and only from php.ini). If you are on a reseller host and can’t change the php.ini you could request if they can change it or not.

    You can also try something like this:

            $postdata = 'myparam=1&myparam2=2'
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, "http://www.example.com/file.php");
            curl_setopt($ch, CURLOPT_TIMEOUT, 180);
            curl_setopt($ch, CURLOPT_HEADER, false);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata); //Makes post requests if required, you may delete this
            $data = curl_exec($ch); // Returns the source code of the url you have entered
            if (!$data) {
                $data = array();
                $data["error"] = curl_error($ch);
                $data["errcode"] = "HTTP";
            }
            curl_close($ch);
            echo $data;
    

    you can use something like this making a curl request (I think that it should be an equivalent library in Zend Framework so you could look out for it for a more proper solution.). It’s not very pretty when you think but this should work as a workaround.

    I would have suggested to look for magento boards but it looks like you did :) and they mentioned about allow_url_fopen too.

    hope that helps

  • Thanks posting such tutorials which is very helpful yummy :)

  • Sailcomp

    I use to load a generated img into a PHP-Script (into the CMS like above). This img is a CAPTCHA and I want to set a Sessionvar in img.php. It is not possible to access this var from the original script. How can I do it?

    Detail:
    formular.php
    unset($_SESSION[‘captcha_spam’]);
    <img src=”yy/yy/yy/yy/yy/yy/yy/bild.php?sessionfe=” border=”0″ />

    bild.php
    <?php
    session_id($_GET[‘sessionfe’]);
    session_start();
    echo “Captcha Spam1: |”.$_SESSION[‘captcha_spam’].”|”;
    unset($_SESSION[‘captcha_spam’]);
    echo “Captcha Spam2: |”.$_SESSION[‘captcha_spam’].”|”;
    ?>

    formularverarbeiten.php

    –> NOT SET

    Thank your for your help!

  • As Magento is an application built over Zend Framework, I think it will be wiser to use a ZF component to get/set session data.

    Here is what I find from google: http://framework.zend.com/manual/en/zend.session.basic_usage.html#zend.session.basic_usage.basic_examples

    As in this example maybe you might get your session variable via $_SESSION[‘Default’][‘captcha_spam’]. But I don’t think it’s possible you better try something like this:

    $captchaSession = new Zend_Session_Namespace(‘Captcha’);
    $captchaSession->spam = ‘some_value’;

    And when you want to use it, use it like this:

    $captchaSession = new Zend_Session_Namespace(‘Captcha’);
    echo $captchaSession->spam;

    Hope this helps. I haven’t tested the above script but it might work for you.

  • Sailcomp

    Hello Roy

    Thank you for your answer and the great idea. Which files from Magento do I have to include to get access to “Zend_Session_Namespace”?

    Otherwise I get this back: “Fatal error: Class ‘Zend_Session_Namespace’ not found in…”

  • Hmm, That’s interesting because lazy loader (zend_loader_autoloader or something like that) must handle the autoloading things for you.

    It’s enough if you just do something like this:

    require_once(“Zend/Session/Namespace.php”);

    The file includes the class and all the depedency files you will need. The file you see is located according to it’s name, all the classes in the ZF uses this convention which also solves the namespace problem which does not exist for PHP 5.2 and lower.

  • S.S.B.Muhundan

    step by step procedure to create a module and a block

    ActiveCodeline — module name
    Example — block name

    step1
    =====

    app\etc\modules
    — create ActiveCodeline_Example.xml

    truelocal

    step2
    =====

    create the following folder structure

    app\code\local

    \ActiveCodeline
    \Example

    \etc

    \block

    step3
    =====

    under app\code\local\ActiveCodeline\Example\etc

    create one xml file config.xml

    0.1.0

    ActiveCodeline_Example_Block

    step4
    =====

    under app\code\local\ActiveCodeline\Example\Block

    create one xml file View.php

    This is the output of the activecodeline example:
    class ActiveCodeline_Example_Block_View extends Mage_Core_Block_Template {
    public function doSomeAction(){

    /*

    u can place ur own codings in this section.

    */

    $message = ‘Hello from ActiveCodeline sample module…’;
    return $message;
    }
    }

    tip: u can place your own codings within the function doSomeAction

    step5
    =====
    create the folder “example” under

    app\design\frontend\default\default\template

    \example

    step6
    =====

    create the file view.phtml under

    app\design\frontend\default\default\template\example

    This is the output of the activecodeline example:
    <?php
    echo “Class name: “. get_class($this) .”“;
    echo $this->doSomeAction();
    ?>

    step7:
    =====

    go to admin panel

    click CMS —>Manage Pages—> Home page

    and paste the above code in content area

    {{block type=”ActiveCodeline_Example/view” template=”example/view.phtml”}}

    final step
    =========
    now type the url

    http://localhost/magento

    now u will see the output…

  • After I read your comments, I remarked that there were a lot of things to do (mostly nothing else than creating folders and files.). So this labor might be done by something else

    http://www.magentocommerce.com/extension/1108/modulecreator

    try this extension, it might help you to create your own custom modules easily.

  • vijay nair

    Great Job Done

    It will really helps all the new people to code in magento

    Thanks

  • Saurabh

    Warning: simplexml_load_string() [function.simplexml-load-string]: Entity: line 38: parser error : Entity ‘trade’ not defined in /www/magento/lib/Varien/Simplexml/Config.php on line 510
    Trace:
    #0 /www/magento/lib/Varien/Simplexml/Config.php(510): mageCoreErrorHandler(2, ‘simplexml_load_…’, ‘/content/Hostin…’, 510, Array)
    #1 /www/magento/lib/Varien/Simplexml/Config.php(498): Varien_Simplexml_Config->loadString(’loadFile(’loadModulesConfiguration(’/content/Hostin…’)
    #4 /www/magento/app/code/core/Mage/Adminhtml/Model/Config.php(63): Mage_Adminhtml_Model_Config->_initSectionsAndTabs(’system.xml’)
    #5 /www/magento/app/code/core/Mage/Adminhtml/controllers/System/ConfigController.php(70): Mage_Adminhtml_Model_Config->getSections()
    #6 /www/magento/app/code/core/Mage/Core/Controller/Varien/Action.php(376): Mage_Adminhtml_System_ConfigController->editAction(NULL)
    #7 /www/magento/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(248): Mage_Core_Controller_Varien_Action->dispatch()
    #8 /www/magento/app/code/core/Mage/Core/Controller/Varien/Front.php(158): Mage_Core_Controller_Varien_Router_Standard->match(’edit’)
    #9 /www/magento/app/Mage.php(459): Mage_Core_Controller_Varien_Front->dispatch(Object(Mage_Core_Controller_Request_Http))
    #10 /www/magento/index.php(65): Mage::run()
    #11 {main}

    Will really really appreciate if someone can help me with getting this going. I am at the last lap of the entire project and this has put a spanner in the works. Friends please help urgently.

  • I can’t say I’m sure but you seem to be missing a configuration about “trade”, You have either added it to the xml which is not recognized or you have used it on the code but did not added in the xml file. I’m not really sure.

  • Nice Tutorial i liked it.
    visit Magento Vedio Tutorials

    thanks,

  • handoyo

    Hi,thanks for the tutor.I want to ask,is it possible to load custom php codes without using block?I’m trying to update currency rates by using external php..Thanks a lot..

  • Well, the easiest way to do it is to setup a cron job and activate your own update-currencies.php file. You don’t actually need to do anything in the Magento code.

    You could write an extension to magento where your update function is attached to an observer. You can then be able to execute your update function whenever that observable event is raised. But you should find out an observer event that runs everytime a page is called. I guess you can find a list of observable events (or hooks if you prefer) somewhere in the magento wiki.

    Hope these help.

  • handoyo

    Thank you,i was thinking to create a model to do that as i found out a tutorial that using cron to send birthday email here : Create cron jobs .I can’t get it work although. Is it possible to only create a model without creating view etc to do that? Thank you

  • I’m not sure I understood what you were saying about models and views but yes it’s possible to create models without views.

    what you need is actually very simple. You have to write a simple php script which will run a sql query and it will get current users with the birthday (assuming mangento saves this info) and then you will send them emails using mail() function in php.

    It’s ok if you are sending mails to 10-20 people but if the number increases to 200-500, you should read some more tutorials about mass mailing or you might get be marked as spam.

  • handoyo

    That means i can also create a php file to update the currency database without touching the magento code?The link i provide was just for an example of what i’m trying to achieve by using cron,not the send email that i want to achieve. :d .Sorry if my explanation is not clear enough. :d Thanks..

  • if you add the appropriate bootstrapping code to your php file yes, you can use models there. What is that? I don’t really know. Perhaps there might be a plugin which might help you, I don’t know that either.

  • handoyo

    Ok,thanks alot Roy.. :d

  • Pingback: The 54 Most Useful Magento Articles of All Time « Custom Magento Development – Collins Harper()

  • Pingback: The 54 Most Useful Magento Articles of All Time | @nexcess()