Skip to content

Instantly share code, notes, and snippets.

@ckimrie
Created August 10, 2012 08:32
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save ckimrie/3312619 to your computer and use it in GitHub Desktop.
Save ckimrie/3312619 to your computer and use it in GitHub Desktop.
Example extension that allows you to modify the final ExpressionEngine CP output
<?php
/**
* Modifying the final CP Output
*
* This extension demonstrates how you can access and modify the final ExpressionEngine
* CP output. It is not a hack, but it is a new technique that to my knowledge has not
* been used before in an EE addon.
*
* This has not been road tested and its side effects are unknown, so use this at your own risk.
*
* NB: Lines 74 and 75 will need to be modified by you before this extension will work.
*
* - Christopher Imrie
*
*/
class Example_ext {
var $EE;
var $name = 'Example Extension';
var $version = '0.1a';
var $description = 'Allows access to the final ExpressionEngine CP output';
var $settings_exist = 'n';
var $docs_url = '';
var $settings = array();
/**
* Constructor
*
* @param mixed Settings array or empty string if none exist.
*/
function __construct($settings = '')
{
$this->EE =& get_instance();
$this->settings = $settings;
}
/**
* Initialize CI Hooks
*
* Using CI Hooks is the only way that we can ensure that our method is
* LAST, after the EE CP Controller has finished.
*
* @param object $Session EE Session instance
* @return null
*/
public function initialize_ci_hook($Session)
{
global $EXT;
//If this request is a JS or AJAX call, dont bother to load initilise hooks.
//We want legit CP page loads only
if($this->EE->input->get("C") == "javascript"){
return;
}
//Enable CI Hooks
$EXT->enabled = TRUE;
//Create the post_controller hook array if needed
if(!isset($EXT->hooks['post_controller'])){
$EXT->hooks['post_controller'] = array();
}
//Add our hook
$EXT->hooks['post_controller'][] = array(
'class' => __CLASS__,
'function' => 'modify_cp_output',
'filename' => THIS-FILENAME, // eg: ext.example.php
'filepath' => DIRECTORY-TO-THIS-FILE, // Relative to the system/expressionengine folder
'params' => array()
);
}
/**
* Post EE Controller
*
* This method will be called after the EE Controller has finished.
*
* @return null
*/
public function modify_cp_output()
{
//Fetch the final CP Output
$html = $this->EE->output->final_output;
//
// GO CRAZY CHANGING ALL THE THINGS !
//
//Reset the final output to your modified version
$this->EE->output->final_output = $html;
}
/**
* Activate, Update and Delete
*/
function activate_extension()
{
$this->settings = array();
$data = array(
'class' => __CLASS__,
'method' => 'initialize_ci_hook',
'hook' => 'sessions_start',
'settings' => serialize($this->settings),
'priority' => 1,
'version' => $this->version,
'enabled' => 'y'
);
$this->EE->db->insert('extensions', $data);
}
function update_extension($current = '')
{
if ($current == '' OR $current == $this->version)
{
return FALSE;
}
$this->EE->db->where('class', __CLASS__);
$this->EE->db->update(
'extensions',
array('version' => $this->version)
);
}
function disable_extension()
{
$this->EE->db->where('class', __CLASS__);
$this->EE->db->delete('extensions');
}
}
// END CLASS
@GDmac
Copy link

GDmac commented Nov 5, 2012

You could check REQ == CP early in the sessions_start hook, to make sure this is not called on every page load on front end too.

@mithra62
Copy link

mithra62 commented Nov 5, 2012

I dig this so damn much! A couple suggestions though:

  1. I think you could avoid the CP checks by using the "cp_menu_array" hook instead of session_start. Just be sure to return the menu on the method.

  2. For the CI Hook itself, you can set the file name and path dynamically like the below:

    $parts = explode(DIRECTORY_SEPARATOR, dirname(__FILE__));
    //Add our hook
    $EXT->hooks['post_controller'][] = array(
            'class' => __CLASS__,
            'function' => 'modify_cp_output',
            'filename' => basename(__FILE__), // eg: ext.example.php
            'filepath' => 'third_party/'.end($parts), // Relative to the system/expressionengine folder
            'params' => array()
    );
    

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment