'__Delete',
);
protected $Columns= array(
'Headers'=> array(
'cb' => ' ', //Render a checkbox instead of text
'Id' => 'ID',
'Title' => '__Title'/* def */,
'Floor'=> '__Column.Floor|mFloorMap',
'Published'=> '__Column.Published|mFloorMap',
'LocationMark'=> '__Column.LocationMark|mFloorMap',
),
'Sortable'=> array(
'Id'=> array('Id', false),
'Title' => array('Title', false),
'Floor'=> array('Floor', false),
'Ordering'=> array('Ordering', false),
'LocationMark'=> array('LocationMark', false),
),
'Hidden'=> array(
),
);
protected function LoadItemData() {
global $wpdb;
// load from database
if ($this->Id > 0) {
$SQL= 'SELECT * FROM '.$this->Table.' WHERE '.$this->PrimaryKey.'='.$this->Id.' LIMIT 1';
$Results= $wpdb->get_results($SQL, ARRAY_A);
$R= empty($Results) ? null : $Results[0];
} else {
$R= null;
}
// prepare item record
$this->ItemData= array(
// key value from database value for new record
'Title' => $R ? $R['Title'] : '',
'OfficialTitle' => $R ? $R['OfficialTitle'] : '',
'Published' => $R ? intval($R['Published']) : 0,
'Floor' => $R ? intval($R['FloId']) : 0,
'LocationMark' => $R ? $R['LocationMark'] : '',
'Logo' => $R ? $R['Logo'] : '',
'Photo' => $R ? $R['Photo'] : '',
'Description' => $R ? $R['Descr'] : '',
'ContactInfo' => $R ? $R['ContactInfo'] : '',
'TimingInfo' => $R ? $R['TimingInfo'] : '',
'Mapping' => $R ? $R['Mapping'] : '',
'Tags' => array(),
);
// collect assigned tags
if ($R) {
$SQL= "SELECT TagId FROM {$wpdb->prefix}mfloormap_placetags WHERE PlaceId=$this->Id";
$Tags= $wpdb->get_results($SQL, ARRAY_A);
foreach($Tags as $Tag) {
$this->ItemData['Tags'][]= $Tag['TagId'];
}
}
}
/**
* Render form (for existing and new items).
*/
protected function RenderFormRows() {
$Logo= $this->UploadsDir.'/logos/'.$this->ItemData['Logo'];
$LogoURL= is_file($Logo) ? $this->UploadsURL.'/logos/'.$this->ItemData['Logo'] : '';
$Photo= $this->UploadsDir.'/photos/'.$this->ItemData['Photo'];
$PhotoURL= is_file($Photo) ? $this->UploadsURL.'/photos/'.$this->ItemData['Photo'] : '';
// find background image
global $wpdb;
$SQL= 'SELECT Image FROM '.$wpdb->prefix.'mfloormap_floors WHERE '.$this->PrimaryKey.'='.intval($this->ItemData['Floor']).' LIMIT 1';
$FloorData= $wpdb->get_results($SQL, ARRAY_A);
$BgImage= empty($FloorData) ? '' : $FloorData[0]['Image'];
$BgImagePath= $this->UploadsDir.'/floors/'.$BgImage;
$BgImageURL= is_file($BgImagePath) ? "$this->UploadsURL/floors/$BgImage" : '';
// prepare map
$Points= array_map('intval', explode(',', $this->ItemData['Mapping']));
$MinimumTop= $MinimumLeft= 99999;
$SVG_points= array();
$BgImgWH= is_file($BgImagePath)
? getimagesize($BgImagePath)
: array(0,0);
$x=0;
while(isset($Points[$x+1])) {
$SVG_points[]= $Points[$x].','.$Points[$x+1];
$MinimumLeft= min($Points[$x], $MinimumLeft);
$MinimumTop= min($Points[$x+1], $MinimumTop);
$x++; $x++;
}
$SVG_points= implode(' ',$SVG_points);
if ($MinimumLeft>99000) {
// seems that no points has defined jet, place viewport on center of map
$MinimumLeft= intval($BgImgWH[0]/2)-160;
$MinimumTop= intval($BgImgWH[1]/2)-80;
}
// bounce 100px away from border
$MinimumLeft= max(0, $MinimumLeft-100);
$MinimumTop= max(0, $MinimumTop-100);
// insert javascript files into header
wp_enqueue_script(__FILE__, plugin_dir_url(__FILE__).'JS/mFloorMapPlaces.js', array('jquery'), mFloorMap::GetInstance()->GetVersion(), false);
wp_enqueue_script("jquery-ui-draggable");
// HTML
return '
'.esc_html__('Name').'
'.esc_html__('Edit.OfficialTitle','mFloorMap').'
'.esc_html__('Column.Published','mFloorMap').'
ItemData['Published']===1?' checked="checked"':'').' />
'.esc_html__('Column.Floor','mFloorMap').'
'.$this->RenderSelect('floor', $this->GetFloorsList(' -'), $this->ItemData['Floor'], 'item_floor').'
'.esc_html__('Column.LocationMark','mFloorMap').'
'.esc_html__('Edit.Logo','mFloorMap').'
'.esc_html__('Edit.ImageReplace','mFloorMap').'
'.esc_html__('Edit.Photo','mFloorMap').'
'.esc_html__('Edit.ImageReplace','mFloorMap').'
'.esc_html__('Edit.Description','mFloorMap').'
'.esc_html__('Edit.ContactInfo','mFloorMap').'
'.esc_html__('Edit.TimingInfo','mFloorMap').'
'.($this->Id === 0 ? '' :'
'.esc_html__('Edit.Tags','mFloorMap').'
'.implode("\n ", $this->RenderTagControls()).'
'.esc_html__('Edit.Mapping','mFloorMap').'
x1
x2
x4
'.esc_html__('Edit.UpdatePoly','mFloorMap').'
').'
';
}
protected function RenderTagControls() {
// find FacId
global $wpdb;
$SQL= "SELECT T2.FacId"
." FROM $this->Table AS T1"
." LEFT JOIN {$wpdb->prefix}mfloormap_floors AS T2 ON T2.Id=T1.FloId"
." WHERE T1.Id=$this->Id";
$Items= $wpdb->get_results($SQL, ARRAY_A);
$FacId= isset($Items[0]) ? intval($Items[0]['FacId']) : 0;
if (!$FacId) {
return array(); // item has not assigned to any facility, therefore it has no tags
}
// find all tags
global $wpdb;
$SQL= "SELECT Id, Title FROM {$wpdb->prefix}mfloormap_tags WHERE FacId=$FacId ORDER BY Ordering";
$AllTags= $wpdb->get_results($SQL, ARRAY_A);
// render
$Controls= array();
foreach($AllTags as $Tag) {
$Chk= in_array($Tag['Id'], $this->ItemData['Tags'], true) ? ' checked="checked"': '';
$CtrlId= 'item_tag'.$Tag['Id'];
$Control= ' ';
$Controls[]= ''.$Control.' '.esc_html($Tag['Title']).' ';
}
return $Controls;
}
protected function Search($Where, $Order, $PerPage, $Page) {
global $wpdb;
$Offset= ($Page-1)*$PerPage;
$SQL= "SELECT T1.*, T2.Title AS FloorTitle, T3.Title AS FacTitle"
." FROM $this->Table AS T1"
." LEFT JOIN {$wpdb->prefix}mfloormap_floors AS T2 ON T2.Id=T1.FloId"
." LEFT JOIN {$wpdb->prefix}mfloormap_facilities AS T3 ON T3.Id=T2.FacId"
." ".$this->SearchJoins
." $Where ORDER BY $Order LIMIT $Offset,$PerPage";
$Items= $wpdb->get_results($SQL, ARRAY_A);
return $Items;
}
protected function GetSearchOrder() {
$Replace= array(
'T1.Floor'=> 'T2.Title',
);
$OrderBy= parent::GetSearchOrder();
return str_replace(array_keys($Replace), array_values($Replace), $OrderBy);
}
protected function GetSearchWhere() {
global $wpdb;
$Conditions= array();
// filter by floor
$FilterFloor= $this->Input('filter_floor', 'I');
if ($FilterFloor > 0) {
$Conditions[]= 'T1.FloId='.$FilterFloor;
}
// filter by tag
$FilterTag= $this->Input('filter_tag', 'I');
if ($FilterTag > 0) {
$Conditions[]= 'TT.TagId='.$FilterTag;
$this->SearchJoins .= ' LEFT JOIN '.$wpdb->prefix.'mfloormap_placetags AS TT ON TT.PlaceId=T1.Id';
}
// pack all conditions
return empty($Conditions)
? ''
: 'WHERE '.implode(' AND ', $Conditions);
}
/**
* Insert filtering controls next to the bulk actions.
*/
protected function extra_tablenav($which) {
if ($which <> 'top') {return;}
echo '
';
// filter by floor
echo ''.esc_html__('Column.Floor','mFloorMap').' ';
$List= $this->GetFloorsList(__('pl.Filter.AllFloors','mFloorMap'));
$Curr= $this->Input('filter_floor', 'I');
$Control= $this->RenderSelect('filter_floor', $List, $Curr, 'filter_floor');
echo $Control;
// filter by tag
echo ''.esc_html__('Edit.Tags','mFloorMap').' ';
$List= $this->GetTagsList(__('pl.Filter.AllTags','mFloorMap'));
$Curr= $this->Input('filter_tag', 'I');
$Control= $this->RenderSelect('filter_tag', $List, $Curr, 'filter_tag');
echo $Control;
// button
submit_button( __('Filter'), '', 'filter_action', false, array('id'=>'post-query-submit'));
echo '
';
}
/**
* Perform deleting specified item.
* Called by bulk operatations handler.
*/
protected function DeleteItem($Id) {
// find and delete existing images
global $wpdb;
$Results= $wpdb->get_results("SELECT * FROM $this->Table WHERE $this->PrimaryKey=$Id LIMIT 1", ARRAY_A);
$Logo= isset($Results[0]) ? $Results[0]['Logo'] : '';
if ($Logo) {
unlink("$this->UploadsDir/logos/$Logo");
}
$Photo= isset($Results[0]) ? $Results[0]['Photo'] : '';
if ($Photo) {
unlink("$this->UploadsDir/photos/$Photo");
}
// delete tag assignments
$wpdb->delete($wpdb->prefix.'mfloormap_placetags', array('PlaceId'=>$Id));
// call parent
parent::DeleteItem($Id);
}
//------------------------------------------------------------------------
// Column renderers
// -----------------------------------------------------------------------
/**
* Renderer of "facility" cell content.
*/
function column_floor($Item) {
$Title= $Item['FloorTitle'];
if ($Item['FacTitle']) {
$Title .= ' ('.$Item['FacTitle'].')';
}
return ($Title)
? $Title
: ' -';
}
//------------------------------------------------------------------------
// Actions
// -----------------------------------------------------------------------
/**
* Action: modify data.
*/
protected function Action_Update() {
global $wpdb;
// get para
$Id = $this->Input('id', 'I');
$Title = $this->Input('title', 'T');
$OfficialTitle= $this->Input('officialtitle', 'T');
$Published = $this->Input('published', 'I');
$Floor = $this->Input('floor', 'I');
$LocMark = $this->Input('locationmark', 'T');
$Description = $this->Input('description', 'T');
$ContactInfo = $this->Input('contactinfo', 'T');
$TimingInfo = $this->Input('timinginfo', 'T');
$Tags = $this->Input('tags', 'AI');
$Mapping = $this->Input('mapping', 'T');
// storing
$SQL= $Id === 0
? "INSERT INTO $this->Table (Id, Title, OfficialTitle, Published, FloId, LocationMark, Descr, ContactInfo, TimingInfo, Mapping)"
." VALUES(0, '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s')"
: "UPDATE $this->Table SET Title='%s', OfficialTitle='%s', Published=%d, FloId=%d, LocationMark='%s', Descr='%s', ContactInfo='%s', TimingInfo='%s', Mapping='%s'"
." WHERE $this->PrimaryKey=".intval($Id);
$Result= $wpdb->query($wpdb->prepare($SQL, $Title, $OfficialTitle, $Published, $Floor, $LocMark, $Description, $ContactInfo, $TimingInfo, $Mapping));
if (isset($Result['error']) && $Result['error']) {
$this->NotificationError($Result['error']);
}
// update current id after insertion
if ($Id === 0) {
$Id= intval($wpdb->insert_id);
}
// handle uploads
if (empty($this->Notifications['Error'])) {
$this->UploadImage('logo', 'Logo', 'logos', $Id);
$this->UploadImage('photo', 'Photo', 'photos', $Id);
}
// handle tags
$wpdb->delete($wpdb->prefix.'mfloormap_placetags', array('PlaceId'=>$Id));
if (!empty($Tags)) {
$Multi= array();
foreach(array_unique($Tags) as $Tag) {
$Multi[]= "($Id,$Tag)";
}
$SQL= "INSERT INTO {$wpdb->prefix}mfloormap_placetags (PlaceId, TagId) VALUES ".implode(', ',$Multi);
$Result= $wpdb->query($SQL); // all values are safe as integers, no need to "prepare" query
}
// disatch confirmation message
if (empty($this->Notifications['Error'])) {
$this->NotificationConfirmation(esc_html__($this->TDPrefix.'List.ConfirmItem'.($Id===0?'Created':'Updated'), $this->TextDomain));
}
// render form
$this->Id= $Id;
$this->DisplayForm();
}
}
?>