Problems, need help? Have a tip or advice? Post it here.
4 posts Page 1 of 1
Suppose I've set up CouchCMS on an old PHP site, let's call it simple.php:

Code: Select all
<?php /* PHP stuff ... */ ?>
<div>
  <cms:editable name="foo" type="text">
    Old
  </cms:editable>
</div>
<?php /* more PHP stuff ... */ ?>


Let's say the client makes an edit to the editable text region "foo," changing the text to "NEW".

The live page now says "NEW!", as expected! However, the source file (simple.php) still says "Old", because the edited content is loaded dynamically from Couch's database.

But what if I want to download simple.php with all of the client's latest edits? I.e. How can I download a PHP file with the following?:

Code: Select all
<?php /* PHP stuff ... */ ?>
<div>
  <cms:editable name="foo" type="text">
    NEW
  </cms:editable>
</div>
<?php /* more PHP stuff ... */ ?>


Is there some kind of export script? Or a "write content to original file" function?

How can I do this? :?:
Hi Matthew and welcome :)

The way Couch works, it allows PHP to have its full run and then manipulates the generated output . This way the original PHP source files are never modified even in the least bit (this also avoids needing write permission to the script files which, of course, is a security risk).

So, since the simple.php of your example never gets modified, downloading it directly will always get you the original version. Couch, out of the box, I'm afraid has no such utility that would get you the modified source file.

Anyways, this requirement of yours has piqued my interest. It is more like generating polymorphic code (code modifies code).
Would it be possible for you to let me know exactly how you plan to use such a functionality?
Maybe I could think of something else that might help.

Thanks.
Would it be possible for you to let me know exactly how you plan to use such a functionality?


Yes! And thank you, glad it piqued your interest.

The first (main) reason is our deployment scheme. This site requires that we 'push' from staging ~> production. I am hoping for a very simple push process: I'd like to just move PHP files, rather than dump->copy->import a DB too.

(Note: I did see the "Migrating from Development to Deployment Server" guide, but for reasons below it'd be useful just to be able to push PHP files only.)

The second reason is performance. The production server sees large traffic spikes occasionally, and just PHP files will be more performant in that environment if they don't have to make DB connections.

The third reason is revision history. We'd like to be able to download simple "snapshots" of the source files, so that we can revert/rollback to a static version if needed, without the DB dependency.

The final reason is security. Having just the generated PHP files without the "CMS" in production will be a bit safer.

Thanks again for your response!

Matthew
OK, I get it now :)

I think there is a way (albeit hackish) that we can use with Couch to modify PHP files the way want but before I get to that please permit me to discuss a couple of alternatives.

1. I totally understand your reasons, and going by those, I think the best performance and best security can be had by deploying plain HTML files, instead of PHP files, on the live server.

Why are you planning to deploy PHP instead? Will the files still have dynamic functionalities requiring PHP? If yes, can you let me know what are those?

If not really, then the best method would be to setup your development Couch to use prettyURLs and then 'scrap' the test site (e.g. mirror it completely using wget) and upload a completely static version onto the live server.
No security issues ever and blazing fast performance.
Use Git (or any revision control) for tracking all changes ever made to the HTML pages.

2. Out of the reasons you mentioned, if we can discount database for a moment, we can still use a full fledged Couch managed site on the live server and get the remaining benefits. This is how -
a. Configure Couch to use caching. Serving a cached file does not require making a database connection (or even loading Couch in its entirety) so the performance you get would be equal to serving raw PHP files.

b. If you are reluctant to place the 'CMS' functionality of Couch on your live server (not that I am saying that you should be - it is your choice), you can use only that part of it that is required to serve (and generate once on the fly if data changed) the pages.
The part of Couch that allows login, creation, modification, deletion etc. (the part of a CMS that is bothering you) can be totally removed from the installation on the live server.
This functionality is contained in only a few files and these can simply be removed from the installation. If security is what is bothering you, this now becomes exactly the same as serving raw PHP files.

c. Changes would have to be pushed by taking a database dump (by phpMyAdmin, not Couch) and applying it to the live server. This, of course, is not amenable to version tracking the way you can track static files but you can, nevertheless, still version track the full dump.

Anyways, those were the alternatives that came to my mind.
Let us come to what you want - modifying entire PHP files.
I'd like to draw you attention to one point here. In Couch a PHP file can serve as a template for multiple cloned pages. If we use your approach, the data from only a single of these pages can be persisted in the modified PHP file. If, of course, you are using uncloned templates, this point does not arise.

So the following is what we can do -
In your site's root create a folder named 'saved'. Make it writable. This folder will hold the modified PHP files.

Now suppose this is an original PHP file named 'static.php'
Code: Select all
<?php /* PHP stuff ... */ ?>
<div>
  <cms:editable name="foo" type="text">
    OLD
  </cms:editable>
</div>
<?php /* more PHP stuff ... */ ?>

Instead of retrofitting Couch into it (by enclosing the contents with require_once( 'couch/cms.php'); and <?php COUCH::invoke(); ?>), what we is do is place this PHP file in the 'snippets' folder of Couch.

In its place, create a new file with the same name (static.php) and place the following content within it -
Code: Select all
<?php require_once( 'couch/cms.php'); ?>

<cms:capture into='my_php_code'>
    <cms:embed k_template_name />
</cms:capture>

<cms:php>
    global $CTX;
    $template_name = '<cms:show k_template_name />';
    $save_folder = K_SITE_DIR . 'saved' . '/';
    $pathname = $save_folder . $template_name;
    $folder_path = substr( $pathname, 0, strrpos($pathname, '/') );
    // Test if folder exists
    if( !(is_dir($folder_path) || file_exists($folder_path)) ){
        // Create it if it does not
        if( !mkdir($folder_path, 0777, true) ){
            die( "Couldn't create folder: " . $folder_path );
        }
    }   
    $handle = @fopen( $pathname, 'w' );
    if( $handle ){
        fwrite( $handle, $CTX->get('my_php_code') );
        fclose( $handle );
    }
    else{
        die( "Couldn't create file: " . $pathname );
    }
   
    ob_start();
    require $pathname;
    echo ob_get_clean();
</cms:php>

<?php COUCH::invoke(); ?>

Notice that this template is the one actually managed by Couch (contains the 'require' and 'invoke' statements).

Access it via browser and the everything should appear as before. Edit the contents in admin panel and the new contents should also appear on the frontend as before.
So this is a 'shim' template that serves only to load the original now found in snippets folder.
However it also saves the modified output into the 'saved' folder we created as the first step.

Take a look at the 'saved' folder and you should find a file named 'static.php' there. Open it in an editor and it should contain the modified contents.

For all your other templates, follow the same steps -
1. Move the original into the snippets folder (take care to remove the require_once( '.couch/cms.php'); and <?php COUCH::invoke(); ?> from them.

IMP: if the template's name contains a path e.g. 'products/static.php' (that is because static.php resides within a subfolder named 'products'), make sure that you create the same folder structure in the snippets folder too.

2. Create a shim template to take their place. Make sure the names match exactly. Paste into it the code we saw above (all shims will have the same code).
3. Access the shim template using browser. Things should work just as before. If they do, you should find a saved PHP in the 'saved' folder.

Hope this helps. Please do let me know.
Thanks.
4 posts Page 1 of 1