Initial upload of latest CCMS (SVN rev. 44)

Signed-off-by: Xander <xander@compactcms.nl>
gitignore
initial commit of original code as per 2010-12-23, as obtained from http://www.phpclasses.org/package/3698-PHP-MySQL-database-access-wrapper.html
moved examples to subdirectory: cleaner dir layout
Merge commit '32216e335b3fc7d1cb803fc10a30cba2d139209c' - start with mixing in the old CCMS version of the UMSQL class so the move to GPL doesn't pollute the new code; only change included is the db_charset=utf8 line which is trivial. My own changes which will follow can be done under the original (empty/free) license of ultimatemysql.

Conflicts:
	mysql.class.php
Security fixes part I: define("COMPACTCMS_CODE") + BASE_PATH

All php entry point files will
  define("COMPACTCMS_CODE", 1);
while all non-entry point php files will check for this define and b0rk with an error ASAP to prevent attackers from executing php code in undesirable ways/order.

Together with this comes a consistency update where each entry point PHP file will make sure that the 'BASE_PATH' define is set, which can be used in PHP require/require_once/include statements.
security part III : die horribly when you're not supposed to start with this PHP file...

Introduced a
  if !defined(SPECIAL_MARKER) die("horribly!");
mechanism like many other PHP projects out there already sport a long time.
The alternative would have been .htaccess, but that one's granularity is per-dir which is a no-go for us.
A slew of fixes (and some enhancements) for the MySQL db class:
- more consistent & rigorous error checking
- in the same line: better/early error propagation, i.e. errors are detected early and methods terminate ASAP.
- all parts of the query building process now not only accept arrays but also literal strings as an alternative; that way specific parts of a query string can be prepared outside the method/class. This is useful for COUNT() queries such as this one:
    $total = $db->SelectSingleValue($cfg['db_prefix']."modcomment", array('pageID' => MySQL::SQLValue($pageID, MySQL::SQLVALUE_TEXT)), 'COUNT(commentID)');

Additions:
- GetStatistics() delivers some useful statistics about the engine; including the number of queries executed through this MySQL class instance.
- Each Query* method now has a Select* counterpart - the Select* methods allow users to provide parameters and have the class build the query on its own (as in the 'SELECT COUNT(x) FROM table WHERE field=value' example above)
- SetError() always returns FALSE as a means to create lean code to percolate the error 'signal' FALSE up the call stack.

Changes:
- Boolean values are now written in 'quoted' mode, i.e. as '0' and '1' instead of the values 0 and 1 as it turns out that for CCMS at least there are several booleans fields done as enum('0', '1') and MySQL apparently doesn't like enum(0,1) nor queries matching those enum values as if it were integer numbers. :-(
when in development, the special development define is set (in config.inc.php) and we don't want to be warned about the _install directory then, nor redirected to it every time we enter the site.

(Running the install script will take care of that define for us, so we're okay when going to the 'production site')
Start of planned review --> fixed issues with admin pages' feedback messages producing non-compliant URIs and some messages simply not getting through.

The action data was fed back over the URI as ?status=XXX&msg=YYY, but in some as ?status=XXX&action=YYY, but that didn't mean the various receivers were down with that.

Now it's handled consistently throughout: ?status=XXX&msg=YYY to feed back fail/success reports with descriptive texts (YYY).

Where the message part of the status report has been lackign before, this has been corrected.

This change includes a fix for the fact that the URI's were non-compliant for arbitrary &msg=YYY -- this is fixed by using rawurlencode/decode before/after passing the data over the URI query part like that.

The modules (news, comments, lightbox) now also use the nicer-looker sprite-d status report <div> which was already appearing in the rest of the admin screens.

TESTED REVISION (the rev's up to the last were generally hand-merged from an existing source tree; this one's seen some testing before check-in :-) )
continued: 2nd security review. Fixed: $_GET/$_POST access + HTTP compliancy re text in GET URL query sections

- all $_GET access has now been reviewed; whenever possible this is fed through getGETparam4...() functions (common.inc.php) - note the 'whevever POSSIBLE' here: we strive for an absolute minimum of cases with 'special circumstances', so we have to spend the least amount of effort at any later date to review the code re XSS/SQLinject/XSRF/... safety again.

- now all $_POST access has been reviewed as well. Note that here as well the principle is 'least number of exceptions from the rule' so almost everything is fed through getPOSTparam4...() functions or their filterParam4...() equivalents when processing arrays (foreach($_POST['label'] as $key => value){...})

- several more cases were found where (semi-)arbitrary messages are passed useing the query part of the URL (a la GET request): these are now properly ENCODED when written using rawurlencode(). Also...

- ... we've augmented the getGETparam4...() functions to pick up on proper HTTP GET URL query section parsing through implicit invocation of the rawurldecode() counterpart to ensure any HTTP URL encoded text elements get through unaltered.

- Several cases where data retrieved from the database was incorrectly fed to SQLUnfix() -- my own mistake; done earlier based on mistaken assumptions -- have been corrected: data is now implicitly escaped (correctly!) when fed INTO a SQL query (through SQLValue() calling SQLFix() under the hood), but any column data produced by any query should NOT be 'unescaped' as MySQL will have done so for us already: you can test this by entering the following string in any description field and subsequently check whether this text comes out the other end unharmed 'on screen':
  test ' " \' \" \\' \\"
which should show up with the exact same number of backslashes when output to screen (HTML page).

- the modules' Manage/Process.php parts were not invoked with the correct setup as sitemap.php would only load the security.inc.php code when the request URL would be inside the /admin/ path -- which is NOT TRUE for any AJAX-ian invocations of the xyz.Manage.php code in the /admin/index.php display, because these AJAX-ian requests would simply list the URL/path to the Manage.php files themselves and thus FAIL to load the security.inc.php.

This will go unnoticed as session data has a relatively long lifetime, but when you 'expire' the session, e.g. by accessing the regular visitor screens for adding comments or through timeout, you wouldn't get sent to the auth.inc.php login display when clicking on these links in the admin section, but just be treated to a simple 'access denied' message, which is somewhat cryptic under such circumstances. Particularly because other links in the /admin/ display WOULD show the login dialog under the same conditions. This has now been fixed.

- removed the few too strict checks in the comments module: adding comments does not require a session state as set up for when you're logged into the admin screen -- resulting in this activity being denied for arbitrary visitors. (AuthCheck() is too restrictive there; deleting comments and other administrative tasks re comment management DO require an authenticated session, though)

- implemented an 'early check AND EXIT' policy throughout: this means the session/authentication checks happen as soon as possible in the code and do exit/die IMMEDIATELY. This replaces the old code which had these checks and skipped 95% of the code to the end, to die() there.
Fix for backwards compatibility of the database: 'zerofill' numeric fields are now parsed just like the v1.4.2+ non-zerofill-ed numeric fields.

For this purpose, the rm0lead() function has been introduced (which is also handy when you need to 'print' a possibly-zero-valued integer, as this function will then spit out "0" instead of the empty string "").
Another bit which was introduced to support this fix is the SQLVALUE_ENUMERATE type, because comment ratings are an 'enumerate' of '1'..'5' and MySQL already showed during previous tests that it did not tolerate
  WHERE field=3
integer-like SQL queries, but required
  WHERE field='3'
instead for this enumerate. Meanwhile we removed the quotes around the 'true' integers to make sure MySQL performs the expected conversions when comparing zerofill-ed numeric fields with literal specified values.
Adopted the many improvements as offered by GerHobbelt. Additional changes made to prevent notices and fix glitches such as the removal of leading zeros in common.inc.php and the parse error on the eval() function in engine.class.php.

Signed-off-by: Xander <xander@compactcms.nl>
CCMS_DEVELOPMENT_ENVIRONMENT define must be TRUE or FALSE; changed from being defined or not defined.

This makes things a little easier our upgrading installer in due time: all defines in config.inc.php are true/false, yes always present.
security review: MySQL access + fixed MySQL access class to support arbitrary ASC/DESC sort order combinations.

The previous implementation only allowed for all ASCending or all DESCending sort order; the new implementation looks at the field prefix of the fields listed in the sort order array:a '-' minus means DESCending sort order for that field is required, while no prefix or a '+' plus sign indicates ASCending sort order for that particular field.

All queries have been inspected and action has been taken to ensure:

1) all variable arguments are fed through the SQLValue() filter/converter method.

2) all queries use the Select*() methods whenever possible; under the hood these create the required SELECT FROM queries; only the table joining SELECT FROM ... queries remain as is in the code, invoking the basic Query() method.

All table arguments for the query methods use single quotes for the table name - which makes for easier grep-ping of the code: only one grep to get them all. (Note that the only exception to this rule is those table-joining raw SELECT queries in there!)
MySQL access class: code reflow only, no code change.
MySQL class code shortening:

pattern
  if (boolean_expression)
  {
    return true;
  }
  else
  {
    return false;
  }

is identical to:

  return boolean_expression;

Changed throughout the code; note the use of !! to turn arbitrary object returns into boolean true/false.
replaced the define()s in config.inc.php with $cfg[] entries: far easier that way to perform an upgrade (which has to set/reset all those entries to the site's original state, overriding the CCMS 'new install' defaults in there.

Also note that some $cfg[] fields in config.inc.php are DELIBERATELY empty: their comments indicate what should be in there, but empty fields in there help simplify the upgrade code/process in /_install/
too much to mention: a Mother of a submit. Positive: lots of fixes and tweaks. Negative: tinyMCE is completely and utterly broken.

- CSS fixes and tweaks for IE6/7/8/FF

- the combiner is now using the browscap info to filter CSS server-side so most browsers get fed clean, compliant CSS while any hacks only arrive at the destinations where they need to be

- Comments manager page now does not say 'News' any longer: that copy&paste error has been erased

- Comments can now, like the news items, be deleted in BULK. That's particularly handy with comments, especially when something went wrong and you got spammed. Just to name one 'opportunity' where bulk-erase is so very handy to have around.

- JavaScript moved to the bottom of the content in preparation of the LazyLoader approach.

- Comments Management and News Management MochaUI screens now also get their own 'reasonable sizes' assigned for a better overall look of the thing.

- Comments are placed in a styled <table> for better perusal in the management screen; styling very similar to other screens which show possibly large amounts of data.

- fix in the MySQL driver class which croaked when a database error would happen.

- adjusted the custom exception class so overly large messages (either real or made by an adversary) don't loose us the pageID query element

- posting empty news items is now also blocked at the backend, where it should be validated anyway, regardless of what checks are performed in /any/ frontend.

- fix for the GetAvailableLanguages() call which used a relative path where it should NOT have assumed anything like that and use an absolute BASE_PATH-based scan instead.

- Now all spots where language-related things can be picked by the user (installer, news and comments management pages) now all use the same code, which also checks which languages are available -- the language sets in news&comments where very disparate with the set listed in the installer.
intermediate checkin: rough development status:

- CSS for all mochaUI windows now corrected, including the module/plugin windows. NOT yet tested 100% on IE7/6.

- PHP fixes: the MySQL class methods Query() and SelectRows() SHOULD be considered DEPRECATED: you only get the records afterwards, using class member variables. The effect is that executing another query over the same connection in the meantime COMPLETELY destroys the record set in the outer loop.

- Backup: SQL just a little closer to phpmyadmin SQL backup/dump similarity.

TODO:

make sure the INSERT INTO statements mention the fields, because they don't do so now and that's VERY dangerous when restoring an older version's backup into a later table format when fields have been added in the middle of the record definition!

- security fixes for the session check and the lightbox module upload (which, incidentally, is finally WORKING again :-)  I broke it a while ago.)

- lazyload JS guaranteed order loading applied to almost all admin screens ('edit user' has not been processed yet; maybe I missed a few others; the main screens have been done now)

- preliminary test to get tinyMCE working again. The test example dumped in the owner mgt. page (abused as a test page) works! :-)

- further tweaks to give all modules 'reasonable sized' mochaUI windows

- moved the table header of the dyn_list and menu mgt. in the main admin index page into the the section that's loaded through AJAX: when you're trying to keep the texts in the headers aligned with the content rows, you were in for a no-win game as depending on language used in the backend (and a few other factors) you'd get different distances. Now, by having the ENTIRE table regenerated through AJAX, do we have two benefits:

a) we are NOT strictly column (40px block) bound anymore: the table renderer in your browser can now pull and tug all those columns to deliver a best fit. VERY important to have workable admin screen on 1024x768px laptop windows! :-)

b) the 'page filters' don't need the complex JavaScript any more to produce the correct helpful tooltip on each change, as now we can simply stick with the PHP-generated tooltip! Yay!

- Combiner now augmented to support googletranslate-style JS callbacks to ensure the main-page JS only gets invoked when a given external JS file is loaded: it works by generating a bit of JS code at the end of the external file, which takes the callback argument from the URL query part and then, when that function is known, calls it.
Exactly like GOOGLE implemented their translate JS service code.

- all ss_sprite sprites are now placed in their own <span>s to ensure, no matter what happens, that those sprites don't show their neighbours.
- added the assisting class 'ss_has_sprite' for the outer element to make the text indent correctly: this makes the sprite look like it was a 'real' button point. (See the installer for examples of the altered text reflow: disable ss_has_sprite to see the difference.)

- installer augmented with a small link to generate a 'safe' authCode for you: not a number with ~ 16 bits of entropy tops like it was done before, but whenever possible this now uses the OpenSSL cryptographically strong random generator to produce a nice salt. Of course using the new salt will invalidate user passwords when upgrading, so it's not done by default then and a warning about the matter is clearly displayed during the install/upgrade phase.

- login page doesn't abuse the session store any more to report login failures. The error feedback is not styled very similar to the rest of the admin pages: red-ish top div for the feedback text when there's an error.

- I'm sure I missed a few spots. It's a Mother of All Commits commit, but now the admin section of the site is at least functioning again (for me, that is ;-) )