<?php
/**
* Ajax "save" route, for saving editor contents to disk
*/
class Loco_ajax_SaveController extends Loco_ajax_common_BundleController {
/**
* {@inheritdoc}
*/
public function render(){
$post = $this->validate();
// path parameter must not be empty
$path = $post->path;
if( ! $path ){
throw new InvalidArgumentException('Path parameter required');
}
// locale must be posted to indicate whether PO or POT
$locale = $post->locale;
if( is_null($locale) ){
throw new InvalidArgumentException('Locale parameter required');
}
$pofile = new Loco_fs_LocaleFile( $path );
$pofile->normalize( loco_constant('WP_CONTENT_DIR') );
// ensure we only deal with PO/POT source files.
// posting of MO file paths is permitted when PO is missing, but we're about to fix that
$ext = strtolower( $pofile->fullExtension() );
if( 'mo' === $ext ){
$pofile = $pofile->cloneExtension('po');
}
else if( 'pot' === $ext ){
$locale = '';
}
else if( 'po' !== $ext ){
throw new Loco_error_Exception('Disallowed file extension');
}
// Prepare compiler for all save operations. PO/MO/JSON, or just POT
$compiler = new Loco_gettext_Compiler($pofile);
// data posted may be either 'multipart/form-data' (recommended for large files)
if( isset($_FILES['po']) ){
$data = Loco_gettext_Data::fromSource( Loco_data_Upload::src('po') );
}
// else 'application/x-www-form-urlencoded' by default
else {
$data = Loco_gettext_Data::fromSource( $post->data );
}
// WordPress-ize some headers that differ from that sent from JavaScript
if( $locale ){
$head = $data->getHeaders();
$head['Language'] = strtr( $locale, '-', '_' );
}
// commit PO file directly to disk
$bytes = $compiler->writePo($data);
$mtime = $pofile->modified();
// start success data with bytes written and timestamp
$this->set('locale', $locale );
$this->set('pobytes', $bytes );
$this->set('poname', $pofile->basename() );
$this->set('modified', $mtime);
$this->set('datetime', Loco_mvc_ViewParams::date_i18n($mtime) );
// add bundle to recent items on file creation
// editor permitted to save files not in a bundle, so catching failures
try {
$bundle = $this->getBundle();
Loco_data_RecentItems::get()->pushBundle($bundle)->persist();
}
catch( Exception $e ){
$bundle = null;
}
// Compile MO and JSON files if PO is localised and not POT (template)
if( $locale ){
$mobytes = $compiler->writeMo($data);
$numjson = 0;
// Project required for JSON writes
if( $bundle ){
$project = $this->getProject($bundle);
$jsons = $compiler->writeJson($project,$data);
$numjson = $jsons->count();
}
$this->set( 'mobytes', $mobytes );
$this->set( 'numjson', $numjson );
}
// Final summary depending on whether MO and JSON compiled
$compiler->getSummary();
return parent::render();
}
}