Wednesday, November 30, 2011

My answer to "How the Request will be passed to index page"

This is my answer to a Question on Support site for LampCMS project


the value of 'a' resolved to name of controller - a class in the Lampcms/Controllers directory.
For example the a=unanswered resolved to Lampcms/Controllers/Unanswered.php

If controller does not exist for the action (this should never happen) then there will be an error.
Every controller class extends Lampcms/WebPage.php

The job of controller is to implement own main() method and setup the values in the this->aPageVars array. This array is then passed to tplMain template and the page is rendered. WebPage class sets up some vars then calls the main().
Controllers all have their own version of main() - that's where controller does their main processing and controller usually sets up the values of ['body'] which is the main area of page and often the value of side navigation blocks, the page title.

After the main() is run, the controller adds some extra values to aPageVars and the in index.php there is this line:
echo new $class($Registry);

This calls the __toString() method in WebPage which basically passes the aPageVars array to the tplMail::parse() and that gets back the html of the web page. The page is echoed to the browser.

There is also an Event Dispatcher involved. The Controller and WebPage class (which is base for every controller) does post some events to event dispatcher, for example 'onPageView', 'onBeforeNewQuestion', 'onNewQuestion', etc.

This allows to write and add custom modules that extends Lampcms/Event/Observer and then these modules are registered as observers and receive all events. Any one of the observers usually ignores most of the events and acts only when specific event occurs. There are several modules that exist, so you can see how they are written. For example Email notifications is a module. Just look in Modules and Modules/Observers directory for some examples. Every Observer since it extends Lampcms\Event\Observer has access to Registry object, meaing it can access the Mongo, Request, and some other important objects from it. A custom observer module just has to implement own main() method and inside that main() method do it's logic. Usually an observer module will first examing the name of the $this->eventName and see if it's the event it's interested in.

Last thing is fastcgi_finish_request() is run and it often runs some extra functions that have been setup usually in custom modules. These functions all run after the page has been served to used, so user experience does not suffer by running some functions that can be run after the page is returned. Such functions may include adding the new question to search index. finding similar questions, posting the new question/answer to twitter, facebook, tumblr, linkedin, emailing users who may be subscribed to that particular tag, updating the 'whos online' collection, which resolved ip to geo location. All these extra steps run after the page is returned and connection to browser is closed. The end-result is similar to offloading the extra work to another thread in Java. Of cause in Java you can create more than one thread and run each task separately, but that's a different story. The user experience is still the same - page is served as fast as possible and extra processing is done afterwards if possible.

Tuesday, November 29, 2011

My answer to "Is it possible to separate the mongodb from Lampcms."

This is my answer to a Question on Support site for LampCMS project


It is not possible. This project is written specifically for mongodb. To put is simply - it takes advantage of the features that Mongodb has and mysql does not have. There are many Q&A projects that are powered by MySQL, but this one runs on MongoDB and that's why it will always be faster and will be able to easier handle heavy traffic and easier to scale when your site grows to millions of questions and answers than MySQL based programs.

Saturday, November 26, 2011

My answer to "How to set local email server details in Lampcms???"

This is my answer to a Question on Support site for LampCMS project


It's sometimes not easy to setup php to send email from local server. Usually you need to add smtp server in your php.ini file and restart your web server.

If you are on Linux then it different and may be due to some unconfigured hosts file or something like a missing PTR record that points back to your domain name.

It really have nothing to do with Lampcms. If you want to show page loading time there is a config option called
SHOW_TIMER in your !config.ini file. You need to change the value to true and it will start showing page rendering time just like on this site.

My answer to "Which design pattern Lampcms following??"

This is my answer to a Question on Support site for LampCMS project


A complex program like this one usually implements more than one design pattern. One pattern that is well-known and is used here is Subject/Observer. Many interesting points in the program post events to event dispatcher.

Various observers are registered with the Dispatcher and listen to events and take some actions on various events. Custom modules are all observer objects and receive events and can then do stuff to the objects passed in Event, including modifying data in the object.

Other patterns I like is adapter pattern.

Also the whole program pretty much designed with MVC pattern. All web pages are actually controllers, all database related stuff is taken care by very lightweight class on top of php's Mongo classes.

There is no dedicated routing class, all requests are routed based on name of the 'a' param in URL. 'a' stand for "action''. For example a request to index.php?a=unanswered is automatically routed to 'Unanswered' class in Lampcms\Controllers\ namespace, etc.

Most classes are autoloaded based on the namespace. Base classes are always pre-loaded for extra efficiency.

The custom templating engine I wrote is very simple and fast, a template is a php class, so templates are cached by APC cache really well. There is no pre-parsing of any kind in the template, you simply pass the array of key=>value pairs to a template's parse() function and it returnes a parsed html block

There is also a REST api with read/write functions. I hope one day to start writing an Android app for this program. I know Java, I played with Android SDK before, it should be pretty easy for me to at least start an Android app. I'll make it open source also, so hopefully others will join and contribute.

Friday, November 25, 2011

My answer to "Getting error when clicking on signup button"

This is my answer to a Question on Support site for LampCMS project


You need to make sure you have the tmp directory and that it has writable permissions.
Baiscally the errors points to a directory that is probably does not exist on your server or is not writable:
/var/www/lamp/www/w/img/tmp/

Check on your server to make sure that this directory exists, and then check the permissions.

Thursday, November 24, 2011

My answer to "Which server is best for LampCMS???"

This is my answer to a Question on Support site for LampCMS project


This site runs on Lighttpd server. It's easy to install, easy to configure. Rewrite rules for it are documented in the program distribution. Using lighttpd with php-fpm (fastcgi process manager for php) is close to 10 times more efficient than traditional Apache with mod_php and most importantly running php under php-fpm adds an extra function to the php 'fastcgi_finish_request' which this program uses to implement a 'runLater' functionality.
It allows the web server to close connection to the browser but continue to execute some extra functions after. For example posting your new question to Twitter, Facebook, etc is done after the page is served to uses, so even if it takes an extra second or two, the user will not see that extra delay in page load. It's also used for indexing new post, finding similar topics, updating tags, updating the geo-location of the request for the 'whos online' plugin.

So no matter which server you choose (even Apache can do that), you should always try to set up the php-fpm and run your php as fastcgi under the php-fpm control. The result will be very similar to using an extra thread in Java to do heavy processing without affecting the load time of the page.

Monday, November 21, 2011

My answer to "Popup "Step 2: provide email address""

This is my answer to a Question on Support site for LampCMS project


I looked at your account. It looks like you have not provided an email address for this account. I think you have also created a different account and provided an email address for that other account.

That's why when you try to enter email address for this account it rejects it because the email address is already used by your other account.

So basically this is not a bug, it's just asking you to provide an email address because you joined the site using external authentication like Google Friend connect and have not provided an email address. This is a feature of the site - to let people quickly join with external login systems like Twitter, LinkedIn, but then also ask for an email address.

My answer to "Translation tools"

This is my answer to a Question on Support site for LampCMS project


This maybe useful, especially if you use Eclipse
http://www.slideshare.net/guesta950cdd8d/lets-localize-your-plugins

My answer to "Error in profile page"

This is my answer to a Question on Support site for LampCMS project


It's fixed now. What happened is that I redesigned a templating engine, basically improved it alot. Now the templating engine has 2 base classes "Fast" and "Simple", Simple extending Fast.

The "Fast" template has ordered placeholders - in the format that works with sprintf() function, which basically has placeholders like %1$s, %2$s, etc - in order, and each placeholder can appear more than once in the template if necessary. This template uses vsprintf() function of php to render the template, which is very fast.

The "Simple" template has named placeholders like {some_name}, {something_else}, etc. This type of template is alot easier to create and edit but it's 20% slower to render. Basically any template that being used inside the loop - like to render a list of comments or a list of answers, etc should extend "Fast" template, but templates that used only once on page like to render some block on the page can extend "Simple" template.

Anyway, now I uploaded new templates to go with the new templating engine and everything works again.

Also in debug mode the templating engine automatically adds html comment blocks to <!-- begin sometemplate --> and <!-- // end sometemplate --> and also comments before and after the template loop. This makes it very easy to debug your template design by just viewing the source html of the page.

These comments are not added in production (non-debug mode), so you don't worry about extra overhead for your production site.

I also plan to release this templating engine as a stand-alone project, calling it "Fast and Simple" php templates.

Sunday, November 20, 2011

My answer to "mongodb collections choice question"

This is my answer to a Question on Support site for LampCMS project


There is no such thing as one thread here. Both Questions and Answers can contain comments. Comments are stored as nested arrays. So QUESTIONS and ANSWERS collections are very similar in structure but they are not exactly the same. For example the QUESTION has a concept of being "unanswered" and also can have the "best answer", while ANSWER does not have these properties.

Also if a question contains so many answers that it requires a pagination, it is then easier to select paginated results from dedicated ANSWERS collection rather than using extra condition to only select answers from a single collection and also paginate results on top of that.

Also sorting questions by recent, popular, unanswered, active is easier when dealing with a dedicated collection - QUESTIONS rather than adding extra condition + sorting condition. It just makes some sorting and pagination operations more efficient.

Same thing when paginating the main page (home page, for example), it's a lot easier and also more efficient when you work with just one collection - QUESTIONS, you just pass the pagination conditions to one collections and get the results.

Also in the long run when you have millions and maybe tens of millions of questions and answers it may be more easier to scale, for example you can store questions and answers on separate servers at some point.

I am sure it is possible to store all in one collection, even questions, answers and comments. But I am glad I chose the separate collections approach, I think it makes the program faster, also easier to work with and also be ready to better handle situation where a site grows to tens of millions of questions/answers.

Thursday, November 17, 2011

My answer to "Fatal error: Method Lampcms\Controllers\Viewquestions::__toString() must not throw an exception"

This is my answer to a Question on Support site for LampCMS project


Thank you for reporting this bug. Yes, it was error that I overlooked after I refactored - remaned and moved many classes to organize them better but I forgot to update couple of files with new namespaces.

I just uploaded the corrected version to github. Please download the newest version and try it.

Let me know if there are still some errors.

Tuesday, November 15, 2011

My answer to "Mongo extension is not installed"

This is my answer to a Question on Support site for LampCMS project


It's possible that extension is installed but not loaded. You need to add it to list of extensions in php.ini
like this:
extension="mongo.so"
and restart the apache (or whatever web server you using)

You may also try to load that extension dynamically, try to add this to your !inc.php - on top of file.

if(!extension_loaded('mongo'){
    dl('mongo.so');
}