mschroeder 251 Bestower of Knowledge Team Colleague

This might give you some starting points (https://github.com/fabpot/Twig/blob/master/lib/Twig/TokenParser/For.php) also take a look at the TokenParser classes at the bottom of this directory. (https://github.com/fabpot/Twig/tree/master/lib/Twig)

mschroeder 251 Bestower of Knowledge Team Colleague

Your memory limit is set to 128MB not 13MB. In my experience with PHPExcel, you can expect between 1 - 10KB of memory usage on average per cell. Formulas and formatting causing even larger memory footprints.

While it will require converting your workbook into 4 csv files, you will then be able to iterate over the individual files by line and your memory footprint will be tiny.

  • Create one database connection.
  • Open the file by creating an instance of an SplFileObject
  • Set the READ_CSV flag (http://www.php.net/manual/en/splfileobject.setflags.php)
  • Set the CSV Controls to match your file's delimiter and enclosure (http://www.php.net/manual/en/splfileobject.setcsvcontrol.php)
  • Iterate over the files, line by line (see the example on the setCsvControl manual page).
  • Execute an insert for each line OR build a large insert statement and execute only 1 query.
    • Executing an insert for each line, will allow you to use prepared statements and will use less memory, but will take longer to execute
    • Executing one large query will make using prepared statements more difficult, will use more memory, but will execute faster.

If this is a big project and you really must work with Excel files, than I would suggest budgeting the money for the excellent LibXL, http://www.libxl.com/home.html This library also has a native php extension https://github.com/iliaal/php_excel

mschroeder 251 Bestower of Knowledge Team Colleague

Stop doing the insert in the loop. This is easily solved by using the loop to generate the insert query and then execute 1 query instead of 10000.

PDO Prepared Statements
Executes 10000 statements
Execution Completed: 10.082677841187 seconds

$db = new PDO( 
    'mysql:host=127.0.0.1;dbname=examples', 
    'username', 
    'password', 
    array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8") 
); 

$sth = $db->prepare('INSERT INTO persons (id, FirstName, LastName, Age, Code) VALUES (NULL, :FirstName, :LastName, :Age, :Code )');

for( $i=1; $i<=10000; $i++ ){
	
	$code = rand(10000,999999);
	$name = 'Peter'.rand(1000,9999);
	
	$sth->bindValue( ':FirstName', $name );
	$sth->bindValue( ':LastName', 'Griffin' );
	$sth->bindValue( ':Age', '35' );
	$sth->bindValue( ':Code', $code );
	$sth->execute();
}

PDO Single Query
Executes 1 query
Execution Completed: 0.28580498695374 seconds

$db = new PDO( 
    'mysql:host=127.0.0.1;dbname=examples', 
    'username', 
    'password', 
    array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8") 
); 

$inserts = array();
$queryFormat = '(NULL,"%s", "Griffin", "35", "%d")';

for ($i=1; $i<=10000; $i++)
{
	$code = rand(10000,999999);
	$name = 'Peter'.rand(1000,9999);	
	$inserts[] = sprintf( $queryFormat, $name, $code );	
}

$query = implode( ",", $inserts );

$db->query( 'INSERT INTO persons (id,FirstName, LastName, Age, Code) VALUES '.$query );

I made a few changes. The name "Peter" was not quoted, I also added a column for "Code' to my query as I think it was forgotten since the insert has a value for it.

Concept applies to all database drivers, but with PDO you'll have the most flexibility. If these values are coming from the end user, prepared statements will provide a much more secure database interaction than using the values directly in the query without first sanitizing/validating …

mschroeder 251 Bestower of Knowledge Team Colleague

You would need two loops, one that would handle your conditional repetitions and one which handled the execution of your batch files.

I would probably start with a for loop for the repetitions and a do-while loop for the batch statements.

mschroeder 251 Bestower of Knowledge Team Colleague

I agree some further explanation is necessary.

PHP is a server-side language so it is meant to run on a server.
HTML5 introduces some client-side storage mechanisms, but their support is going to be relatively limited and I'd be hard pressed to use them unless you're targeting a specific platform that you know supports it.

mschroeder 251 Bestower of Knowledge Team Colleague

@Biiim
The op is not using the mssql driver, they are using the sqlsrv driver provided my Microsoft for php on windows.

@deucalion0
Here is php.net documentation that has examples. My suggestion it to start reading through them to get a better understanding of how the driver is used.
http://us3.php.net/manual/en/book.sqlsrv.php

mschroeder 251 Bestower of Knowledge Team Colleague

You're back to using mysql functions. You can't mix them together.

mschroeder 251 Bestower of Knowledge Team Colleague
mschroeder 251 Bestower of Knowledge Team Colleague

MySQL is not the same as MSSQL. You should not be using the mysql* functions to connect to a microsoft sql server.You want to be using the SQL Server driver (http://msdn.microsoft.com/en-us/sqlserver/ff657782.aspx)

mschroeder 251 Bestower of Knowledge Team Colleague

What are your datatypes for Open and Close?

mschroeder 251 Bestower of Knowledge Team Colleague

Well only you know the architecture of the system(s) you're trying to work within. If you are building them from scratch Twig is an excellent template system.

If you're trying to add to an existing one, than the reason your include is showing before the rest of your output is because the include is being executed before your output is sent. SO it is outputting before the rest of your output.

TO remedy this you will need to wrap the include with output buffering, essentially capture it into a variable and then output where appropriate.
http://php.net/manual/en/function.ob-start.php

mschroeder 251 Bestower of Knowledge Team Colleague

@utroda

Looking at how your syntax works and what you're trying to accomplish, you should take a look at a package called Twig (http://twig.sensiolabs.org/)

It is a template engine that has the exact functionality you are trying to create. It is simple to implement, very well documented and very well tested.

mschroeder 251 Bestower of Knowledge Team Colleague

Hashing is not the same thing as encryption. Your examples are all hashing.

If you need to be able to encrypt and decrypt the data than check out the php documentation for the mcrypt library.
http://php.net/manual/en/book.mcrypt.php

mschroeder 251 Bestower of Knowledge Team Colleague

Have a look at the Zend ACL implementations, I think they're similar to what you'll ultimately end up with, even if they only inspire whatever you create. http://framework.zend.com/manual/en/zend.acl.introduction.html

One of the most advanced acl systems I have worked with was built with Zend's ACL at its foundation, but added some layers of functionality on top. Hence my use of their terms.

mschroeder 251 Bestower of Knowledge Team Colleague

Good thing you resurrected a 2 year old thread...

To simply answer your question, the idea of a hash is to be a one way algorithm. The only way you could "decrypt" a hash would be to generate hashes until your found a match.

If you want to encrypt and decrypt then you want to use encryption, not hashing.

In the future please don't revive a thread this old.

mschroeder 251 Bestower of Knowledge Team Colleague

It looks relatively simple which is a good thing. However i see a few things that may or may not be an issue for you.

First, it is mixing responsibilities, there really is no reason for an ACL to be handling routing the user. It should only be returning TRUE/FALSE whether the user can do what was queried. If it returns false it should be handled however it needs to outside of the ACL class.

Second, I see no way to deal with inheritance. While this might not be a major sticking point, trust me when I say you will get tired of redefining the same resources and privileges on multiple roles. Especially when you have two roles that are very similar but different by only a couple resources etc.

Another thing to keep in mind, is if you are only dealing with role based acl, you should come up with a way to serialize and cache the acl representation so you're not having to query and build it out each and every time a user hits a page. Once the acl is setup, the only time it would change is when a change was made to the roles/resources/privileges etc., so creating a static representation using php's serialize, json, or an xml representation will make it more efficient.

mschroeder 251 Bestower of Knowledge Team Colleague

In terms of an acl you often have the following entities, Users, Roles, Resources and Privileges. Of course everyone will have their own words for each thing but this is how I would define each for the rest of this post.

User - The Person
Role - The group 1 or more persons are in
Resources - A Noun e.g. newsletter, report, post, etc.
Privileges - The Actions e.g. edit, delete, create, view etc.

So when I have seen acl's applied to the routing it is usually handled in the FrontController via a plugin before the route is dispatched to a controller and action. Which seems to be how want it to function anyways. When this is implemented in this way, generally the Resources is in the pattern of Module.Controller.Action or Module-Controller-Action etc. and the FrontController is looking for a specific Privilege, such as view or access.

The nice thing about this naming convention is it allows you to control access at a granular or broad range. Your frontcontroller would first check the module only, than the module.controller and finally the module.controller.action.

So instead of having to enter records for every action in your system you could simple add the resource admin (admin module) with the access, view etc privilege to the user role admin.

The only thing to keep in mind is by default all users to your site either need a guest role, until they sign in, which allows access …

Stefano Mtangoo commented: Great post, thank you! +13
mschroeder 251 Bestower of Knowledge Team Colleague

@ajbest

Just be aware that there are limitations to strtotime and similar functions. The y2k38 bug is when the unix timestamp will exceed a 32bit integer. So for example, if you would try to generate a date, say 30 years in the future (maybe the end date of a mortgage), it will fail.

The php DateTime classes do no suffer from this same limitation. A 64bit build of php will also solve this.

mschroeder 251 Bestower of Knowledge Team Colleague

vlowe,

[edit]
Err, I misread that initially
[/edit]

The PHP DateTime library would be my preferred method of doing what you want.

<?php

//Only need to specify parameters if your timezone is not set.
$now = new DateTime( 'now', new DateTimeZone( 'America/New_York' ) ); //1319061332  or 10/19/2011 @ 4:55pm

//If your timezone is set in php.ini
//$now = new DateTime(); //1319061332  or 10/19/2011 @ 4:55pm

$timestamp = $now->getTimestamp(); //1319061332

//Minus 24 hours
$past24hrs = $now->sub( new DateInterval( 'P24H' ) );
$timestamp = $past24hrs->getTimestamp();

//Minus 1 week
$past1week = $now->sub( new DateInterval( 'P1W' ) );
$timestamp = $past1week->getTimestamp();

//Minus 30 days
$past30days = $now->sub( new DateInterval( 'P30D' ) );
$timestamp = $past30days->getTimestamp();

http://www.php.net/manual/en/class.datetime.php
http://www.php.net/manual/en/class.datetimezone.php
http://www.php.net/manual/en/class.dateinterval.php

[edit]
If you need a timestamp instead in milliseconds simply multiply the returned timestamps by 1000
[/edit]

mschroeder 251 Bestower of Knowledge Team Colleague

My intention was not to make a fool of you or to improve the code you corrected. It was simply to correct your flawed correction.

Both your single vs double quotes and the removal of white space arguments are insignificant points. The performance boost gained from using single quotes over double quotes is so trivial any professional developer would focus their time on bottlenecks that actually exist. An approximate ~1% execution difference in a micro benchmark is not enough to base an entire argument on. You'd be better off comparing concatenation methods as these represent a ~30% performance difference, again in a micro benchmark. The real measurable difference between the two quotes is the memory consumption used for parsing variables in double quoted strings vs single quoted strings using concatenation.

There is also no performance benefit to be had by removing whitespace. The only thing you have accomplished is reducing the readability of the code, making every developers job slightly more difficult. PHP does not gain from minifying or packing like javascript does as it does not have to pass it's source files over a network connection. Additionally libraries like APC, IonCube and Zend Encoder strip the whitespace, comments etc. from the cached code anyways.

"Even a fool may be wise after the event." - Homer

mschroeder 251 Bestower of Knowledge Team Colleague

You corrected the missing bracket, but removed one of the ending parentheses.

$ph = implode( ", ", array_map( 'mysql_real_escape_string', $_POST['phoneno'] ) );
mschroeder 251 Bestower of Knowledge Team Colleague

As of php 5.3 the mssql driver is not available on windows.
http://www.php.net/manual/en/intro.mssql.php

There is an official mssql driver from Microsoft for windows now.
http://msdn.microsoft.com/en-us/sqlserver/ff657782.aspx

mschroeder 251 Bestower of Knowledge Team Colleague

Be careful when using code like that with large files. That relies on your entire file being first read into memory.

The better way to do this would be to iterate over the file line by line.

<?php
$it = new LimitIterator( new SplFileObject( 'sometextfile.txt' ), 57 );

foreach( $it as $line ){
  echo $line;
}

http://www.php.net/manual/en/class.splfileobject.php
http://www.php.net/manual/en/class.limititerator.php

mschroeder 251 Bestower of Knowledge Team Colleague

A quick look at the code you posted, and I see a few issues.

1. ) You are using php short tags. While this is not "wrong" it is not enabled by default in most php configurations and become a real headache if you're not looking for it.

2.) None of the variables in your queries are filtered/validated in any way. Most of those headers you are using can be manipulated by the user in the request.

3.) You're using the mysql extension and I assume you're not using MySQL < 4.1.3. This is more of a pet peeve than anything but if interested read more: http://www.php.net/manual/en/mysqli.overview.php (halfway down or so)

As for some of the questions and thoughts you posed earlier.

Instead of passing the session id through the url, you could encrypt it with a key or a certificate that is unique to your sites. Then by base64 encoding (for url) the encrypted value, you could pass that value through the url as an identifier to your other sites.

You could use 3 1x1 images and use a url method just like you mentioned earlier to retrieve the encrypted value. Decrypt the value and set the session on those other sites to match. It is still a bit of a workaround, but it would stop you from passing the actual session id in the url. By using encryption it is a two way mechanism and you can decrypt it to …

mschroeder 251 Bestower of Knowledge Team Colleague

No pain no gain!

mschroeder 251 Bestower of Knowledge Team Colleague

To my understanding hmac variations are substantially less prone to collisions than the standard hash functions.

I know this is not directly related to your question, but have you considered using bcrypt for your passwords? Assuming your environment is 5.3+
http://us2.php.net/crypt
http://yorickpeterse.com/articles/use-bcrypt-fool/
http://phpmaster.com/why-you-should-use-bcrypt-to-hash-stored-passwords/
http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html
http://gom-jabbar.org/articles/2008/12/03/why-you-should-use-bcrypt-to-store-your-passwords

mschroeder 251 Bestower of Knowledge Team Colleague

You are correct, this would need to be done with an .htaccess file.
Essentially taking www.example.com/#### and mapping it to example.com/page.php?id=####

There are lots of examples and this has been covered quite a bit on these forums.

mschroeder 251 Bestower of Knowledge Team Colleague

I'm not sure how your code is working in the first place. You can not echo out the value of a private or protected class member. So if your class does contain a private $no_of_items you can not display it directly.

<?php
class bag{
  private $no_of_items=0;
  private $sub_total;
 
  public function update(){
  $this->no_of_items = $this->no_of_items++; 
  return true; 
  }
}

$cart = new bag;
//Some calculations...
$cart->update();
echo $cart->no_of_items;  // <== Should give a fatal error!
mschroeder 251 Bestower of Knowledge Team Colleague

Are you trying to build something that is compatible with Joomla, or are you using Joomla as a reference for how they have solved a certain problem?

mschroeder 251 Bestower of Knowledge Team Colleague

If you're going to evaluate a host, look less at the features and more at the infrastructure. If you are looking at a shared host or a reseller account than some important things to consider would be:

  1. Is your data protected by some kind of RAID array?
  2. Is your data also remotely backed up in some automated fashion at a set interval?
  3. Is the server oversold (AKA are the same resources sold to more than one user)?
  4. Where is the server located (Datacenter and Physically)?
  5. What kind of connectivity does the server have? 10Mbps/100Mbps/1000Mbps etc.

Some other more technical concerns should be how the host has PHP configured, including what extensions they have installed. Most shared/reseller hosts will NOT custom configure their php installations for you. But, there are some that will if that is what you need.

Most shared/reseller hosts use some form of control panel. These provide the features like emails, ftps, databases, etc etc. Commonly you'll see cPanel, DirectAdmin or Plesk. However, there are many other control panel solutions as well as some in-house solutions the host developed themselves.

I completely agree with ardav. You absolutely get what you pay for. Steer far away from unlimited hosting, unless of course you can show me an unlimited hard drive, or a NIC with an infinite port speed.

A great resource is Web Hosting Talk search for the name of any host you're looking at and read some reviews.

diafol commented: good points +13
mschroeder 251 Bestower of Knowledge Team Colleague

While those products seem to create functional projects, I'd be more curious to see what the generated code looks like. It appears that they have a major focus on CRUD with some basic UI on top.

If this is the route you're looking for, I'd highly suggest one of the many open source php frameworks and a CRUD package/component for them. Mostly because in the end you'll end up with a more robust framework, something that is community supported by a lot more users and you'll also have access to resources from users all over the world who may have tackled your problem before.

There are a variety of CRUD/Generator bundles for Symfony2.
I've seen CRUD generator capabilities built for Zend Framework.
I believe this is a feature built into CakePHP, maybe a cake user can confirm this.
I've also seen CRUD generator components for CodeIgniter.
There are lots of other frameworks too, but at the moment I think Symfony2 is the best of the best.

mschroeder 251 Bestower of Knowledge Team Colleague

I don't think I would put much stock in a product that "generated" source code for me, scaffolding like controllers is one thing, but not a whole project.

@ardav
I have to disagree with your comment about frameworks. Frameworks will save you from writing lots of code as they supply the architecture logic. As a developer you end up implementing the business services/models and the UI. Once you're familiar with a framework it can drastically speed up your development processes, especially on large projects.

mschroeder 251 Bestower of Knowledge Team Colleague

date_format() was throwing an error because the first parameter being supplied was not an instance of a PHP DateTime object. It has nothing to do with what the database column is set as.

If you're receiving a 1970-01-01 that means strtotime received a null value, or a value outside of the 1970 - 2038 range approximately. The php DateTime class should be used when possible, to avoid this.

If your date is stored in the database as a datetime field type, this is an easy transition.

<?php
echo DateTime::createFromFormat( 'Y-m-d H:i:s', $row_rs_propdetails['add_date'] )->format( 'Y-m-d' );
mschroeder 251 Bestower of Knowledge Team Colleague

http://www.php.net/manual/en/language.types.array.php

Your array keys are not included within quotes and there are not constants defined for username and passuser.

mschroeder 251 Bestower of Knowledge Team Colleague

Generally the templating functionality would be rolled into the "view" component of your MVC architecture, at least in some fashion. The code you have provided looks a lot more like a registry to me.

However to better understand your design, I'd really like to see how you envision other classes extending this base class and what their unique functionality would be.

From what you provided I see some changes that would make like easier.
First, if this class will always be extended and should not be used by itself, making it an abstract class would make sense. Also I think given what I have seen so far, by extending the SPL ArrayObject you'll gain a lot of useful functionality in sense of being able to work with your template as if it was an array.

Also I think you can drastically refactor your class and make it more flexible.

<?php
	
	abstract class TemplateBase extends ArrayObject
	{
		/**
		 *	Constructs a new TemplateBase object
		 * 	If an array is provided it is passed to the ArrayObject constructor
		 *
		 *	@param $options array
		 */
		public function __construct( $options = array() )
		{
			if( is_array( $options ) ){
				parent::__construct( $array() );
			}
		}
		
		/**
		 *	Adds an area to the template class
		 *	
		 *	@param $area string
		 *	@param $content mixed
		 *	@return self
		 */
		public function setArea( $area, $content = null )
		{
			$this[$area] = $content;
			return $this;
		}
		
		/**
		 *	Returns and area if it has previously …
mschroeder 251 Bestower of Knowledge Team Colleague

@newprimitive
Please post your entire Connect class. It appears you're missing a large portion of it, even if you're getting an error on one of the lines you posted, the fact that you're calling $this->set_session() and $this->get_session() and those functions are not presented it is impossible to debug your code properly.

There is a good chance that your error reporting levels differ from local to remote hosts. Or, possibly your datasets are different and the object is not getting populated correctly somewhere earlier.

@cwarn

Initializing a class without the parenthesis is a perfectly legitimate practice when you are not passing values into a constructor. Personally I always use the parenthesis for consistency so I agree with your statement, but it is not wrong.

mschroeder 251 Bestower of Knowledge Team Colleague

Well, it looks like you're setting $data on line 79. It looks like the value of $data mirrors how you're trying to use $imgDt.

mschroeder 251 Bestower of Knowledge Team Colleague

Yes this is absolutely possible.

The only library that is coming to mind is Zend_Mail http://framework.zend.com/manual/en/zend.mail.read.html

Other examples exists such as:
http://garrettstjohn.com/entry/reading-emails-with-php/

Googling will yield a lot of different examples.

mschroeder 251 Bestower of Knowledge Team Colleague

For starters this is not a PHP issue, this is a javascript issue.

On that note it appears you are using jQuery already. So you can add a couple listeners for the escape key press, any mouse click, and also if the search loses focus.

$(document).keypress(function(e) { 
    if (e.which == 27) {
          if( $('#id_of_element').is(':visible') ){
              $('#id_of_element').hide();
          }
    }
});
$('#id_of_input_element').focusout(function(){
    if( $('#id_of_element').is(':visible') ){
         $('#id_of_element').hide();
    }
});
$(document).mouseup(function(){
    if( $('#id_of_element').is(':visible') ){
         $('#id_of_element').hide();
    }
});

This isn't tested by should give you a good starting point.

mschroeder 251 Bestower of Knowledge Team Colleague

$imgDt is not an instance of an object. You also did not show any code where $imgDt is actually set.

mschroeder 251 Bestower of Knowledge Team Colleague

You don't have to use PDO for this and you don't have to use the type hinting like I did. The concept is still applicable for any database connection.

Whether it is Mysql (hopefully not), Mysqli, or PDO, create the connection into a variable and then pass the connection into the classes that need a database connection.

mschroeder 251 Bestower of Knowledge Team Colleague
<a href="./path/to/some/file/to/download.pdf"><button name="" id="">Download</button></a>

Am I missing anything about the complexity or functionality of this?

mschroeder 251 Bestower of Knowledge Team Colleague

If you're opening a mysql connection for every method call you are definitely doing it inefficiently.

The best way to handle the connection would be to setup one connection per request, since php's scope is limited pretty much to each request, and pass it into all of your different objects where it is needed.

e.g.

<?php

try {
    $dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}

//Inject the database handler via constructor
$someClass = new SomeClassThatNeedsDatabaseAccess( $dbh );
// OR use a setter
//$someClass = new Some ClassThatNeedsDatabaseAccess();
//$someClass->setDbh( $dbh );

$someClass->useTheDbConnection();

//.....

class SomeClassThatNeedsDatabaseAccess
{
	protected $dbh;
	
	public function __construct( $dbh = null )
	{
		if( !is_null( $dbh ) ){
			$this->setDbh( $dbh );
		}
	}
	
	public function setDbh( PDO $dbh )
	{
		$this->dbh = $dbh;
	}
	
	public function getDbh()
	{
		return $this->dbh;
	}
	
	public function useTheDbConnection()
	{
		$result = $this->getDbh()->query('...');
	}
	
}
mschroeder 251 Bestower of Knowledge Team Colleague
<?php
  $date = '140811 060632';
  echo DateTime::createFromFormat('dmy his', $date)->format('Y-m-d H:i:s');

http://php.net/manual/en/datetime.createfromformat.php

cereal commented: nice! :) +6
mschroeder 251 Bestower of Knowledge Team Colleague

If you spent even a fraction of a minute looking at their HTML you'd notice an ajax link like this:
http://tastykitchen.com/recipes/wp-content/plugins/wp-recipes/ajax.php

If you use Firefox, Chrome or Safari, and opened the developer tools/firebug, and adjusted the servings you'd see that the site is using that to make an ajax request. Which then returns a full block of html that is replaced on the site.

Although that is not useful, what you will notice is the /plugins/wp-recipe/ part of that url.
Simply googled for "wp-recipe plugin" and got http://wordpress.org/extend/plugins/wp-recipes/

SImply download the plugin and review the actual PHP source code and you should have a great place to start from.

mschroeder 251 Bestower of Knowledge Team Colleague

Symfony2's form component is completely standalone http://symfony.com/doc/current/book/forms.html

It is very well documented and extremely powerful.

mschroeder 251 Bestower of Knowledge Team Colleague

PHP is notoriously bad with UTF-8 characters. The only reasonable way I think you would accomplish this would be using the multi-byte functions. http://www.php.net/manual/en/ref.mbstring.php

$str = č;
if( mb_strpos( $_POST['tekst'], $str ) !== FALSE ) {
  echo 'Found String';
} else {
  echo 'No String';
}

I haven't tested this, but it should handle multi-byte characters better than the standard functions, however you don't have anywhere near the variety of functions to work with.

mschroeder 251 Bestower of Knowledge Team Colleague

Are you looking for a CRM or a Project Management system?

Both of these can and have been built on both Drupal and Joomla.
CiviCRM (http://civicrm.org/) comes to mind as this integrates with both content management systems.

As for project management there are a bunch of php project management systems. web2project (http://web2project.net/) comes to mind, but there are probably a dozen or so free and relatively active ones. If you don't mind spending money then what is available will greatly increase.

mschroeder 251 Bestower of Knowledge Team Colleague

JpGraph is made specifically for php and is extremely powerful: http://jpgraph.net/
Open Flash Charts 2provides flash based charts that can be modified on the fly: http://teethgrinder.co.uk/open-flash-chart-2/
Google Chart API: http://code.google.com/apis/chart/

mschroeder 251 Bestower of Knowledge Team Colleague

Because on line 62 - 65 when you catch the error, you do nothing to stop the execution of your script.