Plugin: Outputting content to static PHP file

I’m trying to write a plugin that when a specific resource (Privacy Policy) is saved, a static file is overwritten (or created if doesn’t exist) with everything from the resource’s [[*content]] field. The point here is that this content will be included and loaded from other sites as well, but I’d rather be able to edit it once by this main resource.

I thought that file_put_contents() or fopen/fwrite/fclose would work, but I’m doing something wrong.

if ( ($resource->get( ‘template’ ) == 57) && ($modx->event->name == ‘OnDocFormSave’) ) :

//$file = '/assets/elements/shared/privacypolicy.php';
$file = fopen( "/assets/elements/shared/privacypolicy.php" ) or die("unable to open file!");

$newContent = $resource->get( 'content' );

//$resource->file_put_contents( $file, $newContent );
fwrite( $file, $newContent );
fclose( $file );

endif;

Any help would be appreciated.

thanks

Try using Modx service class: https://docs.modx.com/current/en/extending-modx/services/modfilehandler

Also, just check that you have the right permissions. If you’re creating a PHP file you might need to add php file extension to the upload_file_types setting (although, please don’t do this on production as that’s asking to get hacked). Do you get an error in the log when the write fails?

Your fopen call is missing the mode parameter:

$file = fopen( "/assets/elements/shared/privacypolicy.php" , 'w') or die("unable to open file!");

FYI, if OnDocFormSave is the only event the plugin is attached to, checking $modx->event->name is unnecessary.

Also, you probably don’t want to just die() if the file won’t open:

$file = fopen( "/assets/elements/shared/privacypolicy.php" , 'w');
if (!$file) {
  $modx->log(modX::LOG_LEVEL_ERROR, 'Could not open file');
}

I’m still having trouble getting this to work. I even changed the file type to html rather than PHP for security reasons.

I think part of the problem is my inexperience with writing plugins. Is there a better resource with examples than the MODX documentation on plugins? It doesn’t have much info there.

I’ve tried each of these with no success:

if ( $resource->get( ‘template’ ) == 57 ) :

$file = fopen( "/assets/elements/shared/privacy-test.html", 'w' );
if (!$file) {
  $modx->log(modX::LOG_LEVEL_ERROR, 'Could not open file');
}
$newContent = $resource->get( 'content' );

fwrite( $file, $newContent );
fclose( $file );

endif;

$modx->getService(‘fileHandler’,‘modFileHandler’);
$file = $modx->fileHandler->make(‘/assets/elements/shared/privacy-test.html’);
if (!$file->create(‘Hello!’)) {
return ‘File not written.’;
}
return ‘File written.’;

if ($modx->event->name != ‘OnDocFormSave’) {return false;}

if($resource->get('template') == 57) :
    if($resource->get('content')) :
        
        $modx->getService('fileHandler','modFileHandler');
        $file = $modx->fileHandler->make('/assets/elements/shared/privacy-test.html');  
        
        if (!$file->create('Hello!')) :
           return 'File not written.';
        endif;
        
        return 'File written.';
        
        
    endif;
endif;

Thanks

Try putting a return statement at the end of your plugin. Also, don’t return messages, write them to the Error log.

It might help to write your plugin as a snippet first, with $modx->resource->getContent().

If you turn on error reporting, you may get an immediate error message.

Where would I put that snippet at in my template then? Does it matter? Or should it go at the end of the body like some scripts?

Usually, the snippet tag would go in the Content field of a test resource, which you’d view in the front end to execute the snippet.

Did you try my first two suggestions? You may not need the snippet.

Yes, i tried them and it didn’t work. I’ve tried something new to see if i’m doing this right and it looks like I’m probably not.

I made a snippet called privpolTest and it includes:

$file = fopen( "/assets/elements/shared/test.txt" , 'w');
if (!$file) {
  $modx->log(modX::LOG_LEVEL_ERROR, 'Could not open file');
}
$newContent = 'hello world';

fwrite( $file, $newContent );
fclose( $file );

Then, I created a new resource (without rich text) and just included the snippet [[privpolTest]]. Loaded that page in the browser, refreshed the files tab in the CMS, checked for the file but the file doesn’t exist.

Nothing in the error log either.

Found this from an ancient article in the old forums.

Had to prepend the /assets/ directory with:

$modx->getOption(’base_path’).

Now it writes the content to the file.