Skip to content

Instantly share code, notes, and snippets.

@brandonkelly
Created February 23, 2009 15:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brandonkelly/68984 to your computer and use it in GitHub Desktop.
Save brandonkelly/68984 to your computer and use it in GitHub Desktop.
<?php
// Code trimmed out while porting Playa to a FieldFrame extension
// ===========================================================================
/**
* Extension Constructor
*
* @param array $settings
* @since version 1.0.0
*/
function Playa($settings=array())
{
global $SESS;
$this->settings = $this->get_site_settings($settings);
if(isset($SESS->cache['bk']) === FALSE){
$SESS->cache['bk'] = array();
}
}
/**
* Get All Settings
*
* @return array All extension settings
* @since version 1.2.1
*/
function get_all_settings()
{
global $DB;
$query = $DB->query("SELECT settings
FROM exp_extensions
WHERE class = '{$this->class_name}'
AND settings != ''
LIMIT 1");
return $query->num_rows
? unserialize($query->row['settings'])
: array();
}
/**
* Get Site Settings
*
* @param array $settings Current extension settings (not site-specific)
* @return array Site-specific extension settings
* @since version 1.2.1
*/
function get_site_settings($settings=array())
{
global $PREFS;
$site_id = $PREFS->ini('site_id');
return isset($settings[$site_id])
? $settings[$site_id]
: array();
}
/**
* Settings Form
*
* Construct the custom settings form.
*
* Look and feel based on LG Addon Updater's settings form.
*
* @param array $current Current extension settings (not site-specific)
* @see http://expressionengine.com/docs/development/extensions.html#settings
* @author Leevi Graham <http://leevigraham.com>
* @since version 1.2.0
*/
function settings_form($current)
{
global $DB, $DSP, $LANG, $IN, $PREFS;
$current = $this->get_site_settings($current);
// Is MSM enabled?
$msm = ($PREFS->ini('multiple_sites_enabled') == 'y') ? TRUE : FALSE;
// Get the current Site ID
$site_id = $PREFS->ini('site_id');
// Get Statuses
$statuses = array();
$query = $DB->query('SELECT g.group_id, sites.site_label, g.group_name, s.status_id, s.status
FROM exp_status_groups AS g,
exp_statuses AS s,
exp_sites AS sites
WHERE sites.site_id = g.site_id
AND s.group_id = g.group_id '
. ($msm ? '' : "AND g.site_id = '{$site_id}' ")
. 'ORDER BY sites.site_label, g.group_name, s.status_order');
if ($query->num_rows)
{
foreach($query->result as $row)
{
if ( ! isset($statuses[$row['group_id']]))
{
$statuses[$row['group_id']] = array(
'group_name' => ($msm ? $row['site_label'].' &ndash; ' : '') . $row['group_name'],
'statuses' => array()
);
}
$statuses[$row['group_id']]['statuses'][$row['status_id']] = $row['status'];
}
}
// Form Header
$DSP->crumbline = TRUE;
$DSP->title = $LANG->line('extension_settings');
$DSP->crumb = $DSP->anchor(BASE.AMP.'C=admin'.AMP.'area=utilities', $LANG->line('utilities')).
$DSP->crumb_item($DSP->anchor(BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=extensions_manager', $LANG->line('extensions_manager')));
$DSP->crumb .= $DSP->crumb_item($this->name);
$DSP->right_crumb($LANG->line('disable_extension'), BASE.AMP.'C=admin'.AMP.'M=utilities'.AMP.'P=toggle_extension_confirm'.AMP.'which=disable'.AMP.'name='.$IN->GBL('name'));
$DSP->body = '';
// Donations button
$DSP->body .= '<div style="float:right;">'
. '<a style="display:block; margin:-2px 10px 0 0; padding:5px 0 5px 70px; width:190px; height:15px; font-size:12px; line-height:15px;'
. ' background:url(http://brandon-kelly.com/images/shared/donations.png) no-repeat 0 0; color:#000; font-weight:bold;"'
. ' href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=2181794" target="_blank">'
. $LANG->line('donate')
. '</a>'
. '</div>';
$DSP->body .= "<h1>{$this->name} <small>{$this->version}</small></h1>";
$DSP->body .= $DSP->form_open(
array(
'action' => 'C=admin'.AMP.'M=utilities'.AMP.'P=save_extension_settings',
'name' => 'settings_example',
'id' => 'settings_example'
),
array('name' => strtolower($this->class_name))
);
// Open Statuses Setting
$DSP->body .= $DSP->table_open(array('class' => 'tableBorder', 'border' => '0', 'style' => 'margin-top:18px; width:100%'));
$DSP->body .= $DSP->tr()
. $DSP->td('tableHeading', '', '2')
. $LANG->line("open_statuses_title")
. $DSP->td_c()
. $DSP->tr_c();
$DSP->body .= $DSP->tr()
. $DSP->td('', '', '2')
. "<div class='box' style='border-width:0 0 1px 0; margin:0; padding:10px 5px'><p>" . $LANG->line('open_statuses_info') . "</p></div>"
. $DSP->td_c()
. $DSP->tr_c();
$DSP->body .= $DSP->tr()
. '<td class="tableCellOne" style="width:60%; padding-top:8px; vertical-align:top;">'
. $DSP->qdiv('defaultBold', $LANG->line("open_statuses_label"))
. $DSP->td_c();
$DSP->body .= $DSP->td('tableCellOne');
foreach($statuses as $status_group)
{
$DSP->body .= '<fieldset>'
. '<legend>'.$status_group['group_name'].'</legend>';
foreach($status_group['statuses'] as $status_id => $status)
{
$checked = ( ! isset($current['open_statuses']))
? ( $status == 'open' ? 'y' : 'n' )
: ( in_array($status_id, $current['open_statuses']) ? 'y' : 'n' );
$DSP->body .= '<label>'
. $DSP->input_checkbox('open_statuses[]', $status_id, $checked)
. " {$status}"
. '</label>'
. $DSP->br();
}
$DSP->body .= '</fieldset>'
. $DSP->br();
}
$DSP->body .= $DSP->td_c()
. $DSP->tr_c();
$DSP->body .= $DSP->table_c();
// Updates Setting
$lgau_query = $DB->query("SELECT class
FROM exp_extensions
WHERE class = 'Lg_addon_updater_ext'
AND enabled = 'y'
LIMIT 1");
$lgau_enabled = $lgau_query->num_rows ? TRUE : FALSE;
$check_for_extension_updates = (( ! $lgau_enabled) OR ($current['check_for_extension_updates'] == 'y')) ? TRUE : FALSE;
$DSP->body .= $DSP->table_open(
array(
'class' => 'tableBorder',
'border' => '0',
'style' => 'margin-top:18px; width:100%'
)
)
. $DSP->tr()
. $DSP->td('tableHeading', '', '2')
. $LANG->line("check_for_extension_updates_title")
. $DSP->td_c()
. $DSP->tr_c()
. $DSP->tr()
. $DSP->td('', '', '2')
. '<div class="box" style="border-width:0 0 1px 0; margin:0; padding:10px 5px"><p>'.$LANG->line('check_for_extension_updates_info').'</p></div>'
. $DSP->td_c()
. $DSP->tr_c()
. $DSP->tr()
. $DSP->td('tableCellOne', '60%')
. $DSP->qdiv('defaultBold', $LANG->line("check_for_extension_updates_label"))
. $DSP->td_c()
. $DSP->td('tableCellOne')
. '<select name="check_for_extension_updates"'.($lgau_enabled ? '' : ' disabled="disabled"').'>'
. $DSP->input_select_option('y', $LANG->line('yes'), ($check_for_extension_updates ? 'y' : ''))
. $DSP->input_select_option('n', $LANG->line('no'), ($check_for_extension_updates ? '' : 'y'))
. $DSP->input_select_footer()
. ($lgau_enabled ? '' : NBS.NBS.NBS.$LANG->line('check_for_extension_updates_nolgau'))
. $DSP->td_c()
. $DSP->tr_c()
. $DSP->table_c();
// Close Form
$DSP->body .= $DSP->qdiv('itemWrapperTop', $DSP->input_submit())
. $DSP->form_c();
}
/**
* Save Settings
*
* @since version 1.2.0
*/
function save_settings()
{
global $DB, $PREFS;
$settings = $this->get_all_settings();
$current = $this->get_site_settings($settings);
// Save new settings
$settings[$PREFS->ini('site_id')] = $this->settings = array(
'check_for_extension_updates' => isset($_POST['check_for_extension_updates']) ? $_POST['check_for_extension_updates'] : 'y',
'open_statuses' => $_POST['open_statuses'] ? $_POST['open_statuses'] : array()
);
$DB->query("UPDATE exp_extensions
SET settings = '".addslashes(serialize($settings))."'
WHERE class = '{$this->class_name}'");
// Update Playa Data if open_statuses has changed
if (( ! isset($current['open_statuses']))
OR ($this->settings['open_statuses'] != $current['open_statuses']))
{
$this->update_all_playa_data();
}
}
/**
* Update All Playa Data
*
* Updates all Playa Data based on new open_statuses setting.
*
* @since version 1.2.0
*/
function update_all_playa_data()
{
global $DB, $FNS;
// Get all Playa fields
$fields = $DB->query("SELECT field_id, group_id
FROM exp_weblog_fields
WHERE field_type = '{$this->type}'");
foreach($fields->result as $field)
{
$field_name = 'field_id_'.$field['field_id'];
// Get all Playa data
$parents = $DB->query("SELECT entry_id, {$field_name} data
FROM exp_weblog_data
WHERE {$field_name} != ''");
foreach($parents->result as $parent)
{
$rel_ids = $this->get_rel_ids($parent['data']);
if ($rel_ids)
{
$children = $DB->query("SELECT r.rel_id, t.entry_id, t.title, t.status, w.status_group, s.status_id
FROM exp_weblog_titles AS t,
exp_weblogs AS w,
exp_statuses AS s,
exp_relationships AS r
WHERE r.rel_id IN (".implode(',', $rel_ids).")
AND t.entry_id = r.rel_child_id
AND w.weblog_id = t.weblog_id
AND ( w.status_group = 0 OR ( w.status_group = s.group_id AND s.status = t.status ))
GROUP BY t.entry_id
ORDER BY t.weblog_id, t.title");
$playa_data = array();
foreach($children->result as $child)
{
$key = array_search($child['rel_id'], $rel_ids);
if ($key !== FALSE) {
$status = $this->get_entry_status($child);
$ref = $this->assemble_rel_reference($child['rel_id'], $child['title'], $status);
$playa_data[$key] = $ref;
}
}
$playa_data = array_filter($playa_data);
ksort($playa_data);
$this->update_playa_data($parent['entry_id'], $field_name, $playa_data);
}
}
}
// Clear relationships cache
$FNS->clear_caching('relationships');
}
/**
* Activate Extension
*
* Resets all Playa exp_extensions rows
*
* @since version 1.0.0
*/
function activate_extension()
{
global $DB;
// Get settings
$settings = $this->get_all_settings();
// Delete old hooks
$DB->query("DELETE FROM exp_extensions
WHERE class = '{$this->class_name}'");
// Add new extensions
$ext_template = array(
'class' => $this->class_name,
'settings' => $settings ? addslashes(serialize($settings)) : '',
'priority' => 10,
'version' => $this->version,
'enabled' => 'y'
);
$extensions = array(
// LG Addon Updater
array('hook'=>'lg_addon_update_register_source', 'method'=>'register_my_addon_source'),
array('hook'=>'lg_addon_update_register_addon', 'method'=>'register_my_addon_id'),
// Admin > Field Groups
array('hook'=>'show_full_control_panel_end', 'method'=>'edit_field_group'),
array('hook'=>'publish_admin_edit_field_extra_row', 'method'=>'edit_custom_field'),
array('hook'=>'sessions_start', 'method'=>'save_custom_field'),
// Publish / Edit
array('hook'=>'publish_form_start', 'method'=>'publish_form_start'),
array('hook'=>'publish_form_headers', 'method'=>'add_header_includes', 'priority'=>11),
array('hook'=>'publish_form_field_unique', 'method'=>'assemble_field'),
array('hook'=>'submit_new_entry_start', 'method'=>'modify_post_vars'),
array('hook'=>'submit_new_entry_end', 'method'=>'update_relations'),
// Delete
array('hook'=>'delete_entries_start', 'method'=>'gather_mourning_parents'),
array('hook'=>'delete_entries_loop', 'method'=>'relieve_mourning_parents'),
// Modify Template
array('hook'=>'weblog_entries_tagdata', 'method'=>'modify_template', 'priority'=>9)
);
foreach($extensions as $extension)
{
$ext = array_merge($ext_template, $extension);
$DB->query($DB->insert_string('exp_extensions', $ext));
}
}
/**
* Update Extension
*
* @param string $current Previous installed version of the extension
* @since version 1.0.0
*/
function update_extension($current='')
{
global $DB;
$sql = array();
if ($current == '' OR $current == $this->version)
{
return FALSE;
}
if ($current < '1.3.6')
{
$this->activate_extension();
}
else
{
$sql[] = "UPDATE exp_extensions
SET version = '".$DB->escape_str($this->version)."'
WHERE class = '{$this->class_name}'";
foreach ($sql as $string)
{
$DB->query($string);
}
}
}
/**
* Disable Extension
*
* @since version 1.0.0
*/
function disable_extension()
{
global $DB;
$DB->query("UPDATE exp_extensions
SET enabled='n'
WHERE class='{$this->class_name}'");
}
/**
* Register a New Addon Source
*
* @param array $sources The existing sources
* @return array The new source list
* @see http://leevigraham.com/cms-customisation/expressionengine/lg-addon-updater/
* @author Leevi Graham <http://leevigraham.com>
* @since version 1.1.0
*/
function register_my_addon_source($sources)
{
global $EXT;
// Check if we're not the only one using this hook
if($EXT->last_call !== FALSE)
$sources = $EXT->last_call;
// add a new source
// must be in the following format:
/*
<versions>
<addon id='LG Addon Updater' version='2.0.0' last_updated="1218852797" docs_url="http://leevigraham.com/" />
</versions>
*/
if(( ! isset($this->settings['check_for_extension_updates'])) OR $this->settings['check_for_extension_updates'] == 'y')
{
$sources[] = 'http://brandon-kelly.com/downloads/versions.xml';
}
return $sources;
}
/**
* Register a New Addon
*
* @param array $addons The existing sources
* @return array The new addon list
* @see http://leevigraham.com/cms-customisation/expressionengine/lg-addon-updater/
* @author Leevi Graham <http://leevigraham.com>
* @since version 1.1.0
*/
function register_my_addon_id($addons)
{
global $EXT;
// Check if we're not the only one using this hook
if($EXT->last_call !== FALSE)
$addons = $EXT->last_call;
// add a new addon
// the key must match the id attribute in the source xml
// the value must be the addons current version
if(( ! isset($this->settings['check_for_extension_updates'])) OR $this->settings['check_for_extension_updates'] == 'y')
{
$addons[$this->class_name] = $this->version;
}
return $addons;
}
/*...snip...*/
/**
* Edit Field Group
*
* @param string $out The content of the admin page to be outputted
* @return string Modified $out
* @see http://expressionengine.com/developers/extension_hooks/show_full_control_panel_end/
* @author Mark Huot <docs@markhuot.com>
* @since version 1.0.0
*/
function edit_field_group($out)
{
global $DB, $EXT, $LANG;
// Check if we're not the only one using this hook
if($EXT->last_call !== false)
{
$out = $EXT->last_call;
}
if(preg_match_all("/C=admin&amp;M=blog_admin&amp;P=edit_field&amp;field_id=(\d*).*?<\/td>.*?<td.*?>.*?<\/td>.*?<\/td>/is", $out, $matches))
{
foreach($matches[1] as $key=>$field_id)
{
$query = $DB->query("SELECT field_type
FROM exp_weblog_fields
WHERE field_id='{$field_id}'
LIMIT 1");
if($query->row['field_type'] == $this->type)
{
$replace = preg_replace("/(<td.*?<td.*?>).*?<\/td>/si", "$1{$this->name}</td>", $matches[0][$key]);
$out = str_replace($matches[0][$key], $replace, $out);
}
}
return $out;
}
else
{
return $out;
}
}
/*...snip...*/
global $EXT, $LANG, $DB, $PREFS, $DSP;
// Check if we're not the only one using this hook
if($EXT->last_call !== false)
{
$r = $EXT->last_call;
}
/*...snip...*/
// --------------------------------
// Add custom JS
// --------------------------------
// Tell other Field Type handlers to hide playa blocks on select
// - Unfortunately, this won't get added to any other custom field types
// that get added *after* this one :-(
$r = preg_replace("/(id\s*==.*?)\}/s", "$1
document.getElementById('playa_block1').style.display = \"none\";
document.getElementById('playa_block2').style.display = \"none\";
}", $r);
// Add handler for playa Field Type
$r = preg_replace("/(id\s*==\s*.rel.*?})/is", "$1
else if (id == '{$this->type}')
{
document.getElementById('playa_block1').style.display = \"block\";
document.getElementById('playa_block2').style.display = \"block\";
document.getElementById('rel_block').style.display = \"none\";
document.getElementById('select_block').style.display = \"none\";
document.getElementById('pre_populate').style.display = \"none\";
document.getElementById('text_block').style.display = \"none\";
document.getElementById('textarea_block').style.display = \"none\";
document.getElementById('date_block').style.display = \"none\";
document.getElementById('rel_block').style.display = \"none\";
document.getElementById('relationship_type').style.display = \"none\";
document.getElementById('formatting_block').style.display = \"none\";
document.getElementById('formatting_unavailable').style.display = \"block\";
}", $r);
// --------------------------------
// Set proper built-in block displays if field_type == playa
// --------------------------------
if (isset($data['field_type']) AND $data['field_type'] == $this->type)
{
preg_match("/(id=.formatting_block.*?display:\s*)block/", $r, $formatting_unavailable);
if(count($formatting_unavailable) > 0)
{
$r = str_replace($formatting_unavailable[0], $formatting_unavailable[1] .= "none", $r);
}
preg_match("/(id=.formatting_unavailable.*?display:\s*)none/", $r, $formatting_unavailable);
if(count($formatting_unavailable) > 0)
{
$r = str_replace($formatting_unavailable[0], $formatting_unavailable[1] .= "block", $r);
}
}
// --------------------------------
// Add custom blocks
// --------------------------------
if (isset($data['field_type']) AND $data['field_type'] == $this->type)
{
$display = 'block';
$field_playa_max = (isset($data['field_maxl'])) ? $data['field_maxl'] : '';
$field_playa_size = (isset($data['field_ta_rows'])) ? $data['field_ta_rows'] : '10';
$field_playa_blogs = (isset($data['field_list_items']))
? array_filter(explode(',', $data['field_list_items']))
: array();
}
else
{
$display = 'none';
$field_playa_max = '';
$field_playa_size = '10';
$field_playa_blogs = array();
}
/*...snip...*/
// Add $block2 above div#date_block
$r = preg_replace("/(<div\s*id=.date_block.)/", "$block2$1", $r);
/*...snip ...*/
/**
* Save Custom Field
*
* @see http://expressionengine.com/developers/extension_hooks/sessions_start/
* @since version 1.0.0
*/
function save_custom_field()
{
$is_playa = (isset($_POST['field_type']) AND $_POST['field_type'] == $this->type) ? TRUE : FALSE;
if ($is_playa)
{
$_POST['field_pre_populate'] = 'n';
$_POST['field_pre_blog_id'] = '0';
$_POST['field_pre_field_id'] = '0';
$_POST['field_fmt'] = 'xhtml';
$_POST['field_show_fmt'] = 'n';
$_POST['field_list_items'] = isset($_POST['field_playa_blogs'])
? implode(',', $_POST['field_playa_blogs'])
: '';
}
if (isset($_POST['field_playa_blogs']))
{
unset($_POST['field_playa_blogs']);
}
$i = 0;
while(isset($_POST["field_playa_blogs_{$i}"]))
{
unset($_POST["field_playa_blogs_{$i}"]);
$i ++;
}
$fields = array(
array('playa_post'=>'field_playa_maxl', 'col'=>'field_maxl', 'default'=>'0'),
array('playa_post'=>'field_playa_size', 'col'=>'field_ta_rows', 'default'=>'10'),
array('playa_post'=>'field_playa_orderby', 'col'=>'field_related_orderby', 'default'=>'title'),
array('playa_post'=>'field_playa_sort', 'col'=>'field_related_sort', 'default'=>'asc'),
array('playa_post'=>'field_playa_max', 'col'=>'field_related_max', 'default'=>'0')
);
foreach($fields as $field)
{
if ($is_playa)
{
$_POST[$field['col']] = isset($_POST[$field['playa_post']])
? $_POST[$field['playa_post']]
: $field['default'];
}
if (isset($_POST[$field['playa_post']]))
{
unset($_POST[$field['playa_post']]);
}
}
}
/*...snip...*/
global $DB, $DSP, $EXT, $LANG;
if ($row['field_type'] != $this->type)
{
return ($EXT->last_call !== false) ? $EXT->last_call : '';
}
/*...snip...*/
// --------------------------------
// Assemble ul.options.list
// --------------------------------
$options_list = '';
foreach($options as $blog_id => $blog)
{
if ( ! count($blog['entries'])) continue;
$options_list .= '<li class="heading"><h4>'.$blog['title'].'</h4><ul>';
foreach($blog['entries'] as $entry_id => $entry)
{
$selected = ($entry['selected']) ? ' selected' : '';
$options_list .= '<li id="'.$playa_id.'-option-'.$entry_id.'" '.
'class="playa-status-'.$entry['status'].$selected.'" '.
'title="'.$entry['title'].'">'.
$entry['title'].
'</li>';
}
$options_list .= '</ul></li>';
}
if ($options_list == '') return $no_related_entries;
// --------------------------------
// Assemble ul.selections.list
// --------------------------------
$selections_list = '';
foreach($selected_entry_ids as $entry_id)
{
if ( ! isset($selections[$entry_id])) continue;
$selections_list .= "<li id=\"{$playa_id}-option-{$entry_id}-selected\" ".
"class=\"playa-status-{$selections[$entry_id]['status']}\" ".
"title=\"{$selections[$entry_id]['title']}\">".
$selections[$entry_id]['title'].'<div class="dragHandle"></div></li>';
}
// --------------------------------
// Assemble and return HTML
// --------------------------------
$ul_height = (($row['field_ta_rows']) ? (int) $row['field_ta_rows'] : 10) * 21 - 1;
$r = '<table border="0" cellpadding="0" cellspacing="0" class="playa" id="'.$playa_id.'">
<tr>
<td class="options list">
<ul style="height: '.$ul_height.'px;">'.$options_list.'</ul>
</td>
<td class="btns">
<input type="button" class="select-options" value="Add -&gt" />
<input type="button" class="deselect-options" value="&lt;- Remove" />
</td>
<td class="selections list">
<ul style="height: '.$ul_height.'px;">'.$selections_list.'</ul>
</td>
</tr>
<tr>
<td class="options info"></td>
<td></td>
<td class="selections info"></td>
</tr>
</table>
<div id="'.$playa_id.'-console" style="font-family: monospace;"></div>
<input type="hidden" id="'.$field_id.'" name="'.$field_id.'" value="'.implode(',', $selected_entry_ids).'" />
<input type="hidden" name="field_ft_'.$row['field_id'].'" value="'.$row['field_fmt'].'" />
<script type="text/javascript">playa_init("'.$row['field_id'].'", '.$row['field_maxl'].');</script>';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment