Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
323 lines (291 sloc) 9.53 KB
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Entry_directories
*
* This extension takes newly published entries in a channel and uses the data in
* specific fields to create directories in the file structure.
*
* @package Entry Directories
* @version 1.0.1
* @author Justin Koivisto <justin@creativearc.com>
* @copyright Copyright © 2012 Justin Koivisto
* @license LGPL: http://www.gnu.org/licenses/lgpl.html
* @link http://koivi.com/ee-entry-directories
*/
class Entry_directories_ext {
// =================================================
// required variables for EE 2.0 extensions
// =================================================
public $settings = array();
public $name = 'Entry Directories';
public $version = '1.0.1';
public $description = 'Creates directories based on entry fields.';
public $settings_exist = 'y';
public $docs_url = 'http://koivi.com/ee-entry-directories';
// internal EE object by reference
protected $EE = NULL;
// =================================================
// this extension's custom variables for operation
// =================================================
// somewhere to store error messages
protected $errors = array();
// default channel fields that are in the
// =================================================
// required methods for EE 2.0 extensions
// =================================================
public function __construct($settings='')
{
$this->EE =& get_instance();
$this->settings = $settings;
}
/**
* what to do when the extension is activated
*/
public function activate_extension()
{
$this->EE->db->insert('extensions', array(
'class' => __CLASS__,
'method' => 'entry_submission_absolute_end',
'hook' => 'entry_submission_absolute_end',
// Additional processing after entry submission, after all processing, prior to redirect.
// $this->extensions->call('entry_submission_absolute_end', $this->entry_id, $this->meta, $this->data);
'settings' => '',
'priority' => 10, // last thing to fire
'version' => $this->version,
'enabled' => 'y'
));
$this->EE->db->insert('extensions', array(
'class' => __CLASS__,
'method' => 'entry_submission_absolute_end',
'hook' => 'entry_submission_absolute_end',
// Additional processing after entry submission, after all processing, prior to redirect.
// $this->extensions->call('entry_submission_absolute_end', $this->entry_id, $this->meta, $this->data);
'settings' => '',
'priority' => 10, // last thing to fire
'version' => $this->version,
'enabled' => 'y'
));
}
public function update_extension($current=''){
if($current == '' || $current == $this->version){
return FALSE;
}
if($current < '1.0'){
// Update to version 1.0
}
$this->EE->db->where('class', __CLASS__);
$this->EE->db->update(
'extensions',
array('version' => $this->version)
);
}
/**
* what to do when the extension is disabled
*/
public function disable_extension()
{
$this->EE->db->where('class', __CLASS__);
$this->EE->db->delete('extensions');
}
/**
* The function that creates the admin settings page
* @access public
*/
public function settings()
{
$settings = array();
// Creates a text input
$settings['parent_directory'] = array(
'i',
'',
$_SERVER['DOCUMENT_ROOT']
);
// Creates a set of checkboxes for channels
$sql = 'SELECT channel_id, channel_name, channel_title FROM exp_channels WHERE site_id = 1';
$result = $this->EE->db->query($sql);
$channels = array();
if($result->num_rows() > 0){
foreach($result->result_array() as $row){
if($row['channel_name'] != ''){
$channels[$row['channel_id']] = $row['channel_name'];
}
}
}
$settings['channels'] = array(
'c',
$channels,
array() // no default channels
);
// Creates a text input
$settings['dir_field'] = array(
'i',
'',
'url_title'
);
// General pattern:
//
// $settings[variable_name] => array(type, options, default);
//
// variable_name: short name for the setting and the key for the language file variable
// type: i - text input, t - textarea, r - radio buttons, c - checkboxes, s - select, ms - multiselect
// options: can be string (i, t) or array (r, c, s, ms)
// default: array member, array of members, string, nothing
return $settings;
}
// =================================================
// this extension's custom methods for operation
// =================================================
/**
* Create the directory within the parent if possible
* @access private
* @return bool
*/
private function create_directory($dirname)
{
// there should not be any path info in this variable
$dirname = basename($dirname);
// filter the name
$pat = '`^[0-9a-z_.-]+$`i';
if(!preg_match($pat, $dirname)){
$this->errors[] = 'Only letters, numbers, underscore (_), period (.) and dash (-) are allowed in directory name.)';
return FALSE;
}
// can we read/write for our parent directory?
if(file_exists($this->settings['parent_directory'])){
if(is_writeable($this->settings['parent_directory'])){
// this should mean I can write inside this directory
if(file_exists($this->settings['parent_directory'].'/'.$dirname)){
// if the directory already exists, we are OK for this extension
return TRUE;
}else{
if(mkdir($this->settings['parent_directory'].'/'.$dirname)){
// directory was created as desired
return TRUE;
}else{
$this->errors[] = 'Unable to create directory: '.$dirname;
return FALSE;
}
}
}else{
$this->errors[] = 'Can not write to directory: '.$this->settings['parent_directory'];
return FALSE;
}
}else{
$this->errors[] = 'Directory does not exist: '.$this->settings['parent_directory'];
return FALSE;
}
}
/**
* checks if this is the channel we are set to action on
* @param int channel_id id of the channel submitted
* @return bool
*/
private function check_channel($channel_id){
if(in_array($channel_id, $this->settings['channels'])){
// this is the channel to action on
return TRUE;
}
return FALSE;
}
/*
* simply gets the field ID of the indicated field in settings
* @param string $field The setting key name of the desired field
*/
private function get_field_id($field)
{
$res = $this->EE->db->query('
SELECT field_id FROM exp_channel_fields
WHERE field_name LIKE \''.$this->EE->db->escape_str($this->settings[$field]).'\''
);
if($res->num_rows == 0){
return FALSE;
}
$r = $res->row_array();
return intval($r['field_id']);
}
/**
* Retrieve a field from the channel entry table
* @param string $field The field name to query
* @param int $entry_id The entry_id to query for
* @return string|bool field value on success, FALSE on error
*/
private function get_entry_field_value($field, $entry_id){
if($field == 'url_title'){
// this is the only field that will be passed that needs to query
// somewhere other than exp_channel_data
$q = 'SELECT url_title FROM exp_channel_titles WHERE entry_id = '.intval($entry_id);
}else{
$q = 'SELECT '.$field.' FROM exp_channel_data WHERE entry_id = '.intval($entry_id);
}
$res = $this->EE->db->query($q);
if($res->num_rows == 0){
// not in the database?!
$this->errors[] = 'Unable to query '.$field.' for entry '.$entry_id;
return FALSE;
}
$r = $res->row_array();
return $r[$field];
}
/**
* get any error messages that we came across
* @param bool $html Whether or not to return HTML formatted errors
* @return string
*/
public function error($html=TRUE)
{
ob_start();
foreach($this->errors as $e){
if($html) echo '<p class="errorMsg">';
echo $e;
if($html) echo '</p>';
echo "\n";
}
return ob_get_clean();
}
// =================================================
// methods called on hooks
// =================================================
/**
* Called method for this extension at hook "entry_submission_absolute_end"
* @param int $entry_id entry_id of submitted entry
* @param array $fields Array of entry's metadata (channel_id, entry_date, i.e. fields for exp_channel_titles.)
* @param array $data Array of entry's field data
*/
public function entry_submission_absolute_end($entry_id, $fields, $data)
{
if(!$this->check_channel($data['revision_post']['channel_id'])){
// not our actionable channel
// acceptable
return TRUE;
}
// set up directory name field name
if($this->settings['dir_field'] == 'url_title'){
$dir_field = 'url_title';
}else if($this->settings['dir_field'] != 'title'){
// exp_channel_data stores fields by IDs in the name instead of by name
$dir_field = 'field_id_'.$this->get_field_id('dir_field');
}else{
$this->errors[] = 'Cannot use title field for directory names.';
return FALSE;
}
// get the directory name form the database
$dirname = $this->get_entry_field_value($dir_field, $entry_id);
if($dirname === FALSE){
// entry wasn't able to be queried
return FALSE;
}else if(!$dirname){
// no directory name supplied, must not need protection
// acceptable
return TRUE;
}
// make directory
$res = $this->create_directory($dirname);
if(!$res){
echo $this->error(TRUE);
die;
return FALSE;
}else{
return TRUE;
}
}
}
Jump to Line
Something went wrong with that request. Please try again.