<?php $this->template()->setHeader('head', array( 'somefile.js' => 'static_script', 'otherfile.js' => 'style_script' ));And it will be loaded in the head. Notice that the difference is the first param when calling ->setHeader.
Showing posts with label phpfox. Show all posts
Showing posts with label phpfox. Show all posts
Friday, September 13, 2013
Recently (version 3.6) we moved all JS files to the end of <body>, this improves performance but there are some cases where you as a developer need to put JS files in <head>, in 3.7 we are introducing a way to do this, from a controller you can now do this:
Monday, March 4, 2013
Optimizing Phpfox - Tip #2
The feed seems to be the most resource hungry feature so far. If Timeline is enabled , when going to a profile the script needs to find which years have content so it can display the Timeline years block; this can span up to 20 queries to the database in some cases and while it makes proper use of indexes and conditions this is a load we can save in 2 ways:
1) Disable Timeline
2) Disable the Time block, this is perhaps the most feasible option, if you have timeline enabled it must be for a reason. To disable this specific block go to AdminCP -> CMS -> Block Manager, then click on profile.index and disable "Feed Timeline":
you will keep the timeline look but the year selector wont be there
1) Disable Timeline
2) Disable the Time block, this is perhaps the most feasible option, if you have timeline enabled it must be for a reason. To disable this specific block go to AdminCP -> CMS -> Block Manager, then click on profile.index and disable "Feed Timeline":
you will keep the timeline look but the year selector wont be there
With this small change your site will be using a lot less resources and it will contribute to keeping it more stable and efficient.
Note: In case you are wondering, the queries that come from this block do in fact get cached, one cache file per user, but the cache file (specific to a user) is deleted after that user posts something that creates a feed.
Friday, March 1, 2013
Optimizing Phpfox - Tip #1
Lately I've been running into little "tricks" that can help a phpfox site perform better, I will try to add them here as I find them.
Today I have perhaps the most important one that I have seen so far, it came after debugging this database query:
Luckily we have a setting in the AdminCP that can help with this, "Feed Limit (Days)", this tiny little setting will help you greatly to improve performance. What it does is to limit the feeds to a number of days in the past. One way to find a good value for this is to do this check, add a photo to the feed or something that you can easily identify, come tomorrow and look for that feed, if you cannot find it in the first page (before the ajax load ) then you think that 1 day is enough, but for safety check the next page of feeds, if you cannot find it in the 3d page then my advise is to set this to 3 so it looks a maximum of 3 days in the past.
Hope it helps
Today I have perhaps the most important one that I have seen so far, it came after debugging this database query:
explain extended SELECT feed.*, f.friend_id AS is_friend, apps.app_title, u.user_id, u.profile_page_id, u.server_id AS user_server_id, u.user_name, u.full_name, u.gender, u.user_image, u.is_invisible, u.user_group_id, u.language_id FROM phpfox_feed AS feed JOIN phpfox_user AS u ON(u.user_id = feed.user_id) LEFT JOIN phpfox_friend AS f ON(f.user_id = feed.user_id AND f.friend_user_id = 1) LEFT JOIN phpfox_app AS apps ON(apps.app_id = feed.app_id) WHERE feed.time_stamp > '0' AND feed.feed_reference = 0 GROUP BY feed.feed_id ORDER BY feed.time_update DESC LIMIT 10Why is it such a naughty query? well the feed table is the main table here, but the only two conditions to filter it are the time_stamp and the feed_reference. Most of the time feed_reference will be 0 so this isn't a great filter, and time_stamp > 0 is trivial, in fact ignored by MySQL. So, many times this will run through the entire feed table, which is very likely to host hundreds of thousands of records.
Luckily we have a setting in the AdminCP that can help with this, "Feed Limit (Days)", this tiny little setting will help you greatly to improve performance. What it does is to limit the feeds to a number of days in the past. One way to find a good value for this is to do this check, add a photo to the feed or something that you can easily identify, come tomorrow and look for that feed, if you cannot find it in the first page (before the ajax load ) then you think that 1 day is enough, but for safety check the next page of feeds, if you cannot find it in the 3d page then my advise is to set this to 3 so it looks a maximum of 3 days in the past.
Hope it helps
Friday, February 8, 2013
Optimization of Phpfox: MySQL
The first thing I did was to set up a local copy of Phpfox 5.3.0 RC1 (not yet released) with content (users, blogs, friends,...), then enabled the slow_query_log and set the long_query_time to 2, because this is a local server with no traffic I assumed a safe bet that no query would take longer than 2 seconds. Then I enabled log-queries-not-using-indexes to capture those in the slow query log. Then using the script I was able to find queries that could be optimized (theoretically at least).
There were indeed some queries using union and joins that could be optimized (large sites will likely see a performance increase in 5.3.0 RC1).
I do have to point out a couple of things:
First, some queries are being logged but they are meant to scan the full table, for example when getting all the user groups we want all the records in that table, using indexes would not improve performance because we want everything in that table, intentionally this table is typically very small, it defaults to 5 records and in normal circumstances shouldn't grow beyond 10 rows.
Second, In some cases, MySQL seemed to not want to use a specific index, for example with this query:
SELECT COUNT(*) FROM phpfox_user AS u JOIN phpfox_user_field AS ufield ON (ufield.user_id = u.user_id) WHERE u.status_id = 0 AND u.view_id = 0If you run that query with explain you will see that MySQL had many indexes to use but chose none, and in my test it did run a full table scan. So to help in this situation we implemented the function forceIndex(
$iCnt = $this->database() ->from($this->_sTable, 'u') ->forceIndex('status_id') ->join(Phpfox::getT('user_field'), 'ufield', 'ufield.user_id = u.user_id') ->where($this->_aConditions) ->execute('getSlaveField');There surely are queries still to fix, if you find them please let us know, we will continue looking for them but must also attend to other bug reports.
Friday, June 29, 2012
Phpfox Developers: Correct way of sending mail (multiple languages)
Well we got a bug report today that at first seemed intimidating, the case was that in some mails being sent the script would not take into account the language of the receiver if it was a registered user. The first approach was to open the callback for that one case and scenario and fix it there, 3 lines of code edited no big deal, the problem is that it was a callback, meaning every module implemented, so 3 lines of code times 61 was too much to do by hand, luckily we have a built in method to change the language just for one phrase and the fix turned out to be site wide and implemented in less than 1 minute, here's the recap:
This code is wrong because it will not take the target user's language into account
This next is correct:
That is basically it, since you are passing the user_id in the ->to() function the mail library will pick up the language for that user, and by passing an array instead of the actual phrase the mail library will get the correct phrase, you can also include an array of parameters if you like as a second element in the array:
and it will run the replacements as if you had done a getPhrase. Our fix was to Replace In Files all
->subject(Phpfox::getPhrase
with
->subject(array
and same for
->message.
This code is wrong because it will not take the target user's language into account
Phpfox::getLib('mail')->to($aRow['user_id']) ->subject(Phpfox::getPhrase('module.var')) ->message(Phpfox::getPhrase('module.var'))
This next is correct:
Phpfox::getLib('mail')->to($aRow['user_id']) ->subject(array('module.var')) ->message(array('module.var'))
That is basically it, since you are passing the user_id in the ->to() function the mail library will pick up the language for that user, and by passing an array instead of the actual phrase the mail library will get the correct phrase, you can also include an array of parameters if you like as a second element in the array:
Phpfox::getLib('mail')->to($aRow['user_id']) ->subject(array('module.var', array('param1' => 'val1'))) ->message(array('module.var', array('param2' => 'val2')))
and it will run the replacements as if you had done a getPhrase. Our fix was to Replace In Files all
->subject(Phpfox::getPhrase
with
->subject(array
and same for
->message.
Thursday, June 28, 2012
User Group Settings Check
If your custom phpfox module adds user group settings you may want to implement a validation for them, we added a way to run checks based on one bug report related to the custom fields, if you go to the AdminCP and manage settings for a user group, in the "Custom" module there's a setting "Custom field database table name?", this is the name of a table that must exist in the database already, we want to improve this whole routine but meanwhile the admin has to have the table created. So we added a callback in the module "Custom", this function receives an array with two indexes ("variable" and "value") and checks if the table exists. This is how that function looks like:
Remember that callback functions are to be placed in your callback.class.php file in your folder "service".
public function isValidUserGroupSetting($aVal)
{
switch ($aVal['variable'])
{
case 'custom_table_name':
return $this->database()->tableExists($aVal['value']);
default:
return true;
}
}
Remember that callback functions are to be placed in your callback.class.php file in your folder "service".
Thursday, April 26, 2012
Phpfox: onReady with Ajax Browsing
Phpfox offers a site wide ajax browsing experience. This allows to load new pages and change the URL without actually going to another page. Clients save on resources since only needed components are loaded (things like the logo and menu are not requested).
This is pretty cool and makes for a smoother experience to the end user but some developers have had a hard time coupling their javascript routines into this model.
This is pretty cool and makes for a smoother experience to the end user but some developers have had a hard time coupling their javascript routines into this model.
Meet $Behavior
$Behavior is a namespace that is triggered every time a page is loaded, even in ajax browsing mode. If your old JavaScript code looked like this:$(document).ready(function() { // Your code here });You will have to change that to:
$Behavior.anyNameYouWant = function(){ // Your code here };They are both equivalent except that with ajax browsing enabled it will trigger your "anyNameYouWant" function and not the JQuery one. Similarly this replaces the following:
$(function() { // Your code here });since that is the same as $(document).ready Even if site wide ajax browsing is disabled, the $Behavior namespace will be triggered, so you can safely code in $Behavior and not worry about site wide ajax browsing being enabled or disabled.
Wednesday, April 11, 2012
Types of Plug-ins in Phpfox
There are two types of plug-ins in Phpfox, the flat-file ones and the database added ones. Please note that I am not talking about "Plug-in Hooks". The database added ones are the ones you create through the AdminCP, you can disable these from the AdminCP and tie them to a product and module so when you disable either of them the plug-in is also disabled:
The second type of plugins are flat files, there are no control over these from the AdminCP and should in general be avoided. To add this sort of plug-in you would only need to create a php file in the plugins folder of your module, the file name is the hook that will trigger this plug-in, for example: /module/mymodule/include/plugin/url_getdomain_1.php the contents of the php file must still include the php opening and closing tags (<?php and ?>)
The second type of plugins are flat files, there are no control over these from the AdminCP and should in general be avoided. To add this sort of plug-in you would only need to create a php file in the plugins folder of your module, the file name is the hook that will trigger this plug-in, for example: /module/mymodule/include/plugin/url_getdomain_1.php the contents of the php file must still include the php opening and closing tags (<?php and ?>)
Tuesday, April 10, 2012
Phpfox sites attacked
During Easter we learned that some phpfox sites were literally cracked ('hacked' is most commonly used out of context), funny thing is these sites did not apply the security fix that prevented this. We released that security patch over a month before the attacks. Thankfully the affected sites realized it was their mistake and didn't complained to us.
If your site is affected by this attack please contact our support department as soon as possible.
To help alleviate the situation our support department has been attending these cases regardless of their support access, with our without valid support we have been helping sites by cleaning their corrupted files and restoring their site to a working and healthy state.
Word of advise, stay up to date with security patches.
Edit: Ray said something today I had not thought of, people with pirated sites did not get the free clean up that we provided. Just by having a valid license we fixed the site administrator's mistake free of charge. Something to think about...
If your site is affected by this attack please contact our support department as soon as possible.
To help alleviate the situation our support department has been attending these cases regardless of their support access, with our without valid support we have been helping sites by cleaning their corrupted files and restoring their site to a working and healthy state.
Word of advise, stay up to date with security patches.
Edit: Ray said something today I had not thought of, people with pirated sites did not get the free clean up that we provided. Just by having a valid license we fixed the site administrator's mistake free of charge. Something to think about...
Sunday, April 8, 2012
An introduction to User Group Settings in Phpfox
Phpfox is built around the idea that one user belongs to a specific group.
With this in mind each user group can be customized in over 300 ways given the number of user group settings available. A user group setting must belong to a module, so we reference them with this format:
<module>.<name>
for example:
user.can_browse_users_in_public
A user group setting is used in the code to control different things. If you simply add a new user group setting via the AdminCP it will not do anything, you need to add the code for that new user group setting to make sense. Adding user group settings is a task for developers and a site administrator should never have to do this.
To change the value of a user group setting you simply go to the AdminCP -> Users -> Manage User Groups:
From here we can get to the user group settings:
With this in mind each user group can be customized in over 300 ways given the number of user group settings available. A user group setting must belong to a module, so we reference them with this format:
<module>.<name>
for example:
user.can_browse_users_in_public
A user group setting is used in the code to control different things. If you simply add a new user group setting via the AdminCP it will not do anything, you need to add the code for that new user group setting to make sense. Adding user group settings is a task for developers and a site administrator should never have to do this.
To change the value of a user group setting you simply go to the AdminCP -> Users -> Manage User Groups:
From here we can get to the user group settings:
Wednesday, April 4, 2012
Why CometChat Improves Performance?
Every now and then we get a client in support whose hosting account has been suspended for 'abuse'. The typical case is that the client was in a shared hosting package with more traffic than it could handle, and the real killer is often the default IM that comes with Phpfox. This does not necessarily mean that the default IM is poorly coded and here's why: When a user sends a message via the default IM this message uses an ajax connection and connects to the web server (which in 100% of the cases we've had with this problem is Apache), the web server loads the PHP engine, the PHP engine loads the Phpfox libraries and Phpfox connects to the database and stores the message in the database, which could be as short as one word ("Yes") or even less. A user can send almost one message per second (depends on typing speed) and in these (un)lucky cases that can mean the entire routine all over again for each and every message sent.
At the same time, every client that is connected to your IM is listening for messages, this process means that the client (web browser) opens an ajax connection, this reaches the web server (again, usually Apache), this loads the PHP engine which then loads the Phpfox libraries and it checks for new messages, so far its only a second, but if there are no new messages or no new users online, it simply waits, checks the database 5 seconds later and if nothing new still, it waits... and so on for like 30 seconds, during this time the connection to the server was open, PHP and Phpfox loaded in memory and database being queried constantly, for every client that is connected. Share hosting plans limit the amount of connections open and with good reason, they have to enforce the "good neighbor" policy, but this means one single site cannot support a certain number of connections open at the same time.
Frankly, CometChat has a lot of cool features, but what really boosts performance in the client's server is the CometService, it literally takes the load off the server. Make no mistake, if you do not get CometService you will still get a better IM than the default one, but it will query your server constantly and the benefits will be limited. The CometService adds true Comet technology, meaning it is the server who contacts the client (web browser) when there is anything new. And it is not even the client's server who takes the load, its CometChat's server.
If you are a Phpfoxer and your server is suffering from the default IM's load, do not blame the IM, blame the architecture, it was built before Comet technology existed, and give CometService a try, it costs $9/month.
At the same time, every client that is connected to your IM is listening for messages, this process means that the client (web browser) opens an ajax connection, this reaches the web server (again, usually Apache), this loads the PHP engine which then loads the Phpfox libraries and it checks for new messages, so far its only a second, but if there are no new messages or no new users online, it simply waits, checks the database 5 seconds later and if nothing new still, it waits... and so on for like 30 seconds, during this time the connection to the server was open, PHP and Phpfox loaded in memory and database being queried constantly, for every client that is connected. Share hosting plans limit the amount of connections open and with good reason, they have to enforce the "good neighbor" policy, but this means one single site cannot support a certain number of connections open at the same time.
Frankly, CometChat has a lot of cool features, but what really boosts performance in the client's server is the CometService, it literally takes the load off the server. Make no mistake, if you do not get CometService you will still get a better IM than the default one, but it will query your server constantly and the benefits will be limited. The CometService adds true Comet technology, meaning it is the server who contacts the client (web browser) when there is anything new. And it is not even the client's server who takes the load, its CometChat's server.
If you are a Phpfoxer and your server is suffering from the default IM's load, do not blame the IM, blame the architecture, it was built before Comet technology existed, and give CometService a try, it costs $9/month.
Friday, March 30, 2012
Short Guide To A Successful Upgrade of Phpfox
Recently we have heard of a series of failed upgrades from versions 3.0.x to 3.1.0. One thing they all had in common was a human factor, "level 8" in the OSI model as we used to joke back in college.
The upgrade routine is pretty straightforward, you can read the official guide here, but still it seems people have some problems, so here it is to make your life a little bit easier.
The upgrade routine is pretty straightforward, you can read the official guide here, but still it seems people have some problems, so here it is to make your life a little bit easier.
- If you are upgrading your live site before upgrading your development site, stop and change gears to upgrading your development site. Only when the upgrade has satisfied you in the development site do you upgrade your live site.
- If you do not have a development site set up one.
- Make a full backup of your site, this may be 'painful' in terms of server load and in 99.99% of the cases not needed, but if you are the lucky one you will regret not having one.
- Enable debug mode, if anything goes wrong it will show you very important information.
- Only upload recently downloaded files from the account area. In this way you are making sure that you have the most up to date files, and that these have no modifications.
- Read everything that the script shows you. Even if you have upgraded thousands of sites, read and assume you do not know by heart what the upgrade says.
- A red warning is worth attention. If you have a working site and you replace the file /include/setting/server.sett.php with an invalid one the upgrade routine will think you are installing fresh and offer you to drop (delete, remove, wipe, lose) the tables in your database. This means if you proceed you will lose your existing site, all the members, all the photos... everything. This warning looks like this, its really hard to miss!
(It does not even have a "Next" step, it has a red button with a warning) - Sometimes when you upload files they may land with very limited privileges, if you have debug mode enabled you will see a warning but know what to do because debug mode was enabled. Work with your hosting company to ensure that all files and folders have the least permissions needed for the script to work
Last: If you post a comment here asking for support you will be disappointed. While I might be in a good mood your best option is to go to the forums and look for help there, but look for posts already existing, your problem is most likely already solved in an existing thread.
Subscribe to:
Posts (Atom)