Created
January 13, 2015 18:00
-
-
Save bobmagicii/6084ba58a0d50db51abc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static function Search($opt=null) { | |
/*// | |
@todo cache search results for a little bit. | |
@argv object Options | |
@return object | |
perform a search of objects with various properties. if called from a child | |
class then that type will be automatically forced and relevant tables | |
automatically joined. | |
//*/ | |
// allow the child class to extend these options. | |
$opt = static::Search_Extend_Options($opt); | |
//////// | |
//////// | |
// the basic listing with pagination. | |
$search = (new DMA\Database) | |
->Select('dma_objects o') | |
->Fields(['Fields' => 'SQL_CALC_FOUND_ROWS *']) | |
->Limit($opt->Limit) | |
->Offset(($opt->Page - 1) / $opt->Limit); | |
// specific type filtering. use the child class join tables to construct | |
// an inner join so we don't pull any broken rows. | |
if($opt->Type) { | |
$search->Where('o.obj_type=:Type'); | |
foreach(static::$JoinTables as $table) { | |
list($tname,$talias) = explode(' ',$table); | |
$search->Join(sprintf( | |
'%s ON o.obj_id=%s.obj_id', | |
$table, | |
$talias | |
),Verse::JoinInner); | |
} | |
} | |
static::Search_Extend_Filters($search,$opt); | |
static::Search_Extend_Sorts($search,$opt); | |
//////// | |
//////// | |
// stop now if all we wanted from this was a count. | |
if($opt->CountOnly) return $search->Count($opt); | |
//////// | |
//////// | |
$set = $search->Query($opt); | |
$list = []; | |
while($row = $set->Result->Next()) $list[] = new static($row); | |
return (object)[ | |
'Query' => $search->GetSQL(), | |
'Count' => $set->Found, | |
'Page' => $opt->Page, | |
'PageCount' => ceil($set->Found / $opt->Limit), | |
'PageLimit' => $opt->Limit, | |
'Payload' => $list | |
]; | |
} | |
protected static function Search_Extend_Options($opt) { | |
/*// | |
setup the options for the search so that we can use the data in advanced | |
filtering later on. any classes that which to overwrite this method should | |
immediately call parent::Search_Extend_Options($opt) before adding their | |
own data to it. | |
//*/ | |
$opt = new Nether\Object($opt,[ | |
// object properties | |
'Type' => static::GetObjectType(), | |
'Subtype' => null, | |
'Owner' => 0, | |
'Parent' => 0, | |
'Title' => null, | |
'Alias' => null, | |
'Enabled' => true, | |
'Deleted' => false, | |
'Flags' => 0, | |
'Tags' => [], | |
// sort options. | |
'Sort' => [], | |
// search options. | |
'ByText' => null, | |
'Page:int' => 1, | |
'Limit:int' => 20, | |
'CountOnly:bool' => false | |
]); | |
return $opt; | |
} | |
protected static function Search_Extend_Filters($s,$opt) { | |
/*// | |
bind the filters to the sql that will perform the search upon the database. | |
any classes that which to overwrite this method should immeidately call | |
parent::Search_Extend_Filters($s,$opt) before adding their own filters to | |
the search object. | |
//*/ | |
// specific properties. | |
if($opt->Subtype) $s->Where([ 'Subtype' => 'o.obj_subtype=:Subtype' ]); | |
if($opt->Flags) $s->Where([ 'Flags' => '(o.obj_flags1&:Flags)=:Flags' ]); | |
if($opt->Owner) $s->Where([ 'Owner' => 'o.u_id=:Owner' ]); | |
if($opt->Parent) $s->Where([ 'Parent' => 'o.obj_parent=:Parent' ]); | |
// fuzzy text searches. | |
if($opt->Title) $s->Where([ 'Title' => 'o.obj_title LIKE :Title' ]); | |
if($opt->Alias) $s->Where([ 'Alias' => 'o.obj_alias LIKE :Alias' ]); | |
if($opt->ByText) { | |
$opt->ByText = "%{$opt->ByText}%"; | |
$s->Where([ 'ByText' => '(o.obj_alias LIKE :ByText OR o.obj_title LIKE :ByText)' ]); | |
} | |
// if enabled is true then only show enabled. if false then only show | |
// disabled. if null or omitted then ignore the enabled state all | |
// together. | |
if($opt->Enabled === true) $s->Where([ 'Enabled' => 'o.obj_enabled=1' ]); | |
if($opt->Enabled === false) $s->Where([ 'Enabled' => 'o.obj_enabled=0' ]); | |
// if deleted is false then only show objects which have never been | |
// marked as deleted. if true, only show objects which have been marked | |
// deleted. if you pass a numeric value treat it as a unix time and then | |
// only pull the items which have been deleted since that time. | |
if($opt->Deleted === false) $s->Where([ 'Enabled' => 'o.obj_deleted=0' ]); | |
if($opt->Deleted === true) $s->Where([ 'Enabled' => 'o.obj_deleted!=0' ]); | |
if(is_numeric($opt->Deleted)) $s->Where([ 'Enabled' => 'o.obj_deleted>=:Deleted' ]); | |
// if any tags are provided then only find things that have them. if | |
// the tag id is positive then use it to include the tag. if negitive | |
// use it to exclude. | |
if(!empty($opt->Tags)) { | |
$tagin = []; | |
$tagout = []; | |
foreach($opt->Tags as $tid) { | |
if($tid > 0) $tagin[] = $tid; | |
elseif($tid < 0) $tagout[] = $tid * -1; | |
} | |
if(!empty($tagin)) { | |
$s->Join(sprintf( | |
'dma_tag_assoc ta ON ((ta.obj_id=o.obj_id AND ta.tag_obj_id IN (%1$s)) OR (ta.tag_obj_id=o.obj_id AND ta.obj_id IN (%1$s)))', | |
implode(',',$tagin) | |
),Verse::JoinRight); | |
} | |
// TODO tag exclusion. my first few attempts resulted in a slow | |
// query returning mutliples of the same objects. | |
} | |
return; | |
} | |
protected static function Search_Extend_Sorts($s,$opt) { | |
/*// | |
create any sorting that needs to be done to the query. any classes which | |
overwrite this method should immediately call | |
parent::Search_Extend_Sorts($s,$opt) before adding their own sorts to the | |
search object. | |
//*/ | |
foreach($opt->Sort as $sort) { | |
switch(strtolower($sort)) { | |
case 'alias-az': { | |
$s->Sort([ 'Alias-AZ' => 'o.obj_alias' ],Verse::SortAsc); | |
break; | |
} | |
case 'alias-za': { | |
$s->Sort([ 'Alias-ZA' => 'o.obj_alias' ],Verse::SortDesc); | |
break; | |
} | |
case 'title-az': { | |
$s->Sort([ 'Title-AZ' => 'o.obj_title' ],Verse::SortAsc); | |
break; | |
} | |
case 'title-za': { | |
$s->Sort([ 'Title-ZA' => 'o.obj_title' ],Verse::SortDesc); | |
break; | |
} | |
case 'newest': { | |
$s->Sort([ 'Newest' => 'o.obj_time_created' ],Verse::SortDesc); | |
break; | |
} | |
case 'oldest': { | |
$s->Sort([ 'Oldest' => 'o.obj_time_created' ],Verse::SortAsc); | |
break; | |
} | |
case 'modified': { | |
$s->Sort([ 'Modified' => 'o.obj_time_modified' ],Verse::SortDesc); | |
break; | |
} | |
case 'hitcount': { | |
$s->Sort([ 'Hitcount' => 'o.obj_hit_count' ],Verse::SortDesc); | |
} | |
} | |
} | |
return; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment