<?php
/**
* @package Habari
*
*/
/**
* Habari Block class
* Block class for theme display of pluggable content
*
*/
class Block extends QueryRecord implements IsContent, FormStorage
{
private $data_values = array( '_show_title' => true );
/**
* Constructor for the Block class.
* @param array $paramarray an associative array of initial block field values.
*/
public function __construct( $paramarray = array() )
{
// Defaults
$this->fields = array_merge(
self::default_fields(),
$this->fields,
$this->newfields
);
parent::__construct( $paramarray );
$this->exclude_fields( 'id' );
$this->unserialize_data();
}
/**
* Overrides QueryRecord __get to implement custom object properties
*
* @param string Name of property to return
* @return mixed The requested field value
*/
public function __get( $name )
{
switch($name) {
case 'css_classes':
$classes = array();
if(array_key_exists( $name, $this->data_values )) {
$classes = $this->data_values[$name];
}
if(is_string($classes)) {
$classes = explode(' ', $classes);
}
if($this->_first) {
$classes[] = 'first';
}
if($this->_last) {
$classes[] = 'last';
}
if($this->_area_index) {
$classes[] = 'index_' . $this->_area_index;
}
$classes[] = 'block-type-' . Utils::slugify($this->type);
$classes[] = 'block';
$classes = Plugins::filter('block_classes', $classes, $this);
return implode(' ', $classes);
break;
default:
if ( array_key_exists( $name, $this->data_values ) ) {
return $this->data_values[$name];
}
else {
return parent::__get( $name );
}
}
}
/**
* Overrides QueryRecord __set to implement custom object properties
*
* @param string Name of property to return
* @return mixed The requested field value
*/
public function __set( $name, $value )
{
switch ( $name ) {
case 'id':
case 'title':
case 'data':
parent::__set( $name, $value );
$this->unserialize_data();
return parent::__get( $name );
break;
case 'type':
return parent::__set( $name, $value );
break;
default:
$this->data_values[ $name ] = $value;
return $this->data_values[ $name ];
break;
}
}
/**
* Overrides QueryRecord __isset, returns whether this Block has the named
* data. Falls back to QueryRecord's __isset.
*
* @param string $name The name of the parameter
* @return boolean True if the value is set, false if not
*/
public function __isset( $name )
{
return ( isset( $this->data_values[$name] ) || parent::__isset( $name ) );
}
/**
* Return the defined database columns for a Block.
* @return array Array of columns in the Block table
*/
public static function default_fields()
{
return array(
'id' => 0,
'title' => '',
'data' => '',
'type' => '',
);
}
/**
* Render and return the block content
*
* @param Theme $theme the theme object with which the block will be rendered
* @return string The rendered block content
*/
public function fetch( $theme )
{
Plugins::act( 'block_content_' . $this->type, $this, $theme );
Plugins::act( 'block_content', $this, $theme );
$output = implode( '', $theme->content_return( $this ) );
return $output;
}
/**
* Return the content types that this object represents
*
* @see IsContent
* @return array An array of strings representing the content type of this object
*/
public function content_type()
{
$types = array(
'block.' . $this->type,
'block',
);
if ( isset( $this->title ) ) {
array_unshift( $types, 'block.' . $this->type . '.' . Utils::slugify( $this->title ) );
}
if ( isset( $this->_area ) ) {
$areas = array();
foreach ( $types as $type ) {
$areas[] = $this->_area . '.' . $type;
}
$types = array_merge( $areas, $types );
}
$types = Plugins::filter( 'block_content_type_' . $this->type, $types, $this );
$types = Plugins::filter( 'block_content_type', $types, $this );
return $types;
}
/**
* Unserialize the stored block data
*/
public function unserialize_data()
{
if ( trim( $this->data ) != '' ) {
$this->data_values = unserialize( $this->data );
}
}
/**
* Saves form fields that are tied to this block. Implements FormStorage.
*
* @param string $key The name of the form field to store.
* @param mixed $value The value of the form field
*/
public function field_save( $key, $value )
{
$this->$key = $value;
$this->update();
}
/**
* Load the form value from the block
*
* @param string $key The name of the form field to load
* @return mixed The value of the block for the form
*/
public function field_load( $key )
{
return $this->$key;
}
/**
* Insert this block into the database
*
* @return boolean True on success
*/
public function insert()
{
// Let plugins disallow and act before we write to the database
$allow = true;
$allow = Plugins::filter( 'block_insert_allow', $allow, $this );
if ( ! $allow ) {
return;
}
Plugins::act( 'block_insert_before', $this );
$this->data = serialize( $this->data_values );
$result = parent::insertRecord( DB::table( 'blocks' ) );
// Make sure the id is set in the block object to match the row id
$this->newfields['id'] = DB::last_insert_id();
// Update the block's fields with anything that changed
$this->fields = array_merge( $this->fields, $this->newfields );
// We've inserted the block, reset newfields
$this->newfields = array();
EventLog::log( _t( 'New block %1$s: %2$s', array( $this->id, $this->title ) ), 'info', 'content', 'habari' );
// Let plugins act after we write to the database
Plugins::act( 'block_insert_after', $this );
return $result;
}
/**
* Update this block in the database
*
* @return boolean True on success
*/
public function update()
{
$allow = true;
$allow = Plugins::filter( 'block_update_allow', $allow, $this );
if ( ! $allow ) {
return;
}
Plugins::act( 'block_update_before', $this );
$this->data = serialize( $this->data_values );
$result = parent::updateRecord( DB::table( 'blocks' ), array( 'id' => $this->id ) );
$this->fields = array_merge( $this->fields, $this->newfields );
$this->newfields = array();
Plugins::act( 'block_update_after', $this );
return $result;
}
/**
* Delete this block
*
*/
public function delete()
{
// Let plugins disallow and act before we write to the database
$allow = true;
$allow = Plugins::filter( 'block_delete_allow', $allow, $this );
if ( !$allow ) {
return false;
}
Plugins::act( 'block_delete_before', $this );
$result = parent::deleteRecord( '{blocks}', array( 'id'=>$this->id ) );
EventLog::log( sprintf( _t( 'Block %1$s (%2$s) deleted.' ), $this->id, $this->title ), 'info', 'content', 'habari' );
// Let plugins act after we write to the database
Plugins::act( 'block_delete_after', $this );
return $result;
}
/**
* Get the form used to update this block
*
* @return FormUI The altered FormUI element that edits this block
*/
public function get_form()
{
$form = new FormUI( 'block-' . $this->id, 'block' );
$form->on_success( array( $this, 'save_block' ) );
$form->set_option( 'success_message', '</div><div class="humanMsg" id="humanMsg" style="display: block;top: auto;bottom:-50px;"><div class="imsgs"><div id="msgid_2" class="msg" style="display: block; opacity: 0.8;"><p>' . _t( 'Saved block configuration.' ) . '</p></div></div></div>
<script type="text/javascript">
$("#humanMsg").animate({bottom: "5px"}, 500, function(){ window.setTimeout(function(){$("#humanMsg").animate({bottom: "-50px"}, 500)},3000) })
parent.refresh_block_forms();
</script>
<div style="display:none;">
');
Plugins::act( 'block_form_' . $this->type, $form, $this );
Plugins::act( 'block_form', $form, $this );
return $form;
}
/**
* Display a standard success message upon saving the form
*
* @return
*/
public function save_block( $form )
{
$form->save();
return false;
}
/**
* Add this block to a particular area in the theme
*
* @param string $area The name of the area to add to
* @param integer $order The position of the block within the area
* @param string $scope The scope id into which to add this block
*/
public function add_to_area( $area, $order = null, $scope = null )
{
if(is_null($scope)) {
$scope = '';
}
if(is_null($order) || ! is_int($order)) {
$order = DB::get_value('SELECT max(display_order) + 1 FROM {blocks_areas} WHERE area = :area AND scope_id = :scope', array('area'=>$area, 'scope'=>$scope));
if(is_null($order)) {
$order = 1;
}
}
else {
DB::query('UPDATE {blocks_areas} SET display_order = display_order + 1 WHERE area = :area AND scope_id = :scope AND display_order >= :order', array('area'=>$area, 'scope'=>$scope, 'order'=>$order));
}
// If the block isn't saved in the database, insert it.
if(!$this->id) {
$this->insert();
}
$result = DB::query( 'INSERT INTO {blocks_areas} (block_id, area, scope_id, display_order) VALUES (:block_id, :area, :scope_id, :display_order)', array( 'block_id'=>$this->id, 'area'=>$area, 'scope_id'=>$scope, 'display_order'=>$order ) );
}
}
?>