2014-02-03 13:54:09 +00:00
< ? php
2019-07-05 15:15:38 +00:00
class ImageRelationshipSetEvent extends Event
{
public $child_id ;
public $parent_id ;
2019-09-29 13:30:55 +00:00
public function __construct ( int $child_id , int $parent_id )
2019-07-05 15:15:38 +00:00
{
$this -> child_id = $child_id ;
$this -> parent_id = $parent_id ;
}
}
2019-05-28 16:59:38 +00:00
class Relationships extends Extension
{
2019-07-05 15:15:38 +00:00
public const NAME = " Relationships " ;
2019-05-28 16:59:38 +00:00
public function onInitExt ( InitExtEvent $event )
{
global $config , $database ;
// Create the database tables
if ( $config -> get_int ( " ext_relationships_version " ) < 1 ) {
$database -> execute ( " ALTER TABLE images ADD parent_id INT " );
$database -> execute ( $database -> scoreql_to_sql ( " ALTER TABLE images ADD has_children SCORE_BOOL DEFAULT SCORE_BOOL_N NOT NULL " ));
$database -> execute ( " CREATE INDEX images__parent_id ON images(parent_id) " );
$config -> set_int ( " ext_relationships_version " , 1 );
log_info ( " relationships " , " extension installed " );
}
if ( $config -> get_int ( " ext_relationships_version " ) < 2 ) {
$database -> execute ( " CREATE INDEX images__has_children ON images(has_children) " );
$config -> set_int ( " ext_relationships_version " , 2 );
log_info ( " relationships " , " extension updated " );
}
}
public function onImageInfoSet ( ImageInfoSetEvent $event )
{
if ( isset ( $_POST [ 'tag_edit__tags' ]) ? ! preg_match ( '/parent[=|:]/' , $_POST [ " tag_edit__tags " ]) : true ) { //Ignore tag_edit__parent if tags contain parent metatag
if ( isset ( $_POST [ " tag_edit__parent " ]) ? ctype_digit ( $_POST [ " tag_edit__parent " ]) : false ) {
2019-09-29 13:30:55 +00:00
send_event ( new ImageRelationshipSetEvent ( $event -> image -> id , ( int ) $_POST [ " tag_edit__parent " ]));
2019-05-28 16:59:38 +00:00
} else {
$this -> remove_parent ( $event -> image -> id );
}
}
}
public function onDisplayingImage ( DisplayingImageEvent $event )
{
$this -> theme -> relationship_info ( $event -> image );
}
public function onSearchTermParse ( SearchTermParseEvent $event )
{
$matches = [];
if ( preg_match ( " /^parent[=|:]([0-9]+|any|none) $ / " , $event -> term , $matches )) {
$parentID = $matches [ 1 ];
if ( preg_match ( " /^(any|none) $ / " , $parentID )) {
$not = ( $parentID == " any " ? " NOT " : " " );
$event -> add_querylet ( new Querylet ( " images.parent_id IS $not NULL " ));
} else {
$event -> add_querylet ( new Querylet ( " images.parent_id = :pid " , [ " pid " => $parentID ]));
}
} elseif ( preg_match ( " /^child[=|:](any|none) $ / " , $event -> term , $matches )) {
$not = ( $matches [ 1 ] == " any " ? " = " : " != " );
$event -> add_querylet ( new Querylet ( " images.has_children $not TRUE " ));
}
}
2019-08-02 20:05:49 +00:00
public function onHelpPageBuilding ( HelpPageBuildingEvent $event )
{
2019-09-29 13:30:55 +00:00
if ( $event -> key === HelpPages :: SEARCH ) {
2019-08-02 20:05:49 +00:00
$block = new Block ();
$block -> header = " Relationships " ;
$block -> body = $this -> theme -> get_help_html ();
$event -> add_block ( $block );
}
}
2019-05-28 16:59:38 +00:00
public function onTagTermParse ( TagTermParseEvent $event )
{
$matches = [];
if ( preg_match ( " /^parent[=|:]([0-9]+|none) $ / " , $event -> term , $matches ) && $event -> parse ) {
$parentID = $matches [ 1 ];
if ( $parentID == " none " || $parentID == " 0 " ) {
$this -> remove_parent ( $event -> id );
} else {
2019-07-05 15:15:38 +00:00
send_event ( new ImageRelationshipSetEvent ( $event -> id , $parentID ));
2019-05-28 16:59:38 +00:00
}
} elseif ( preg_match ( " /^child[=|:]([0-9]+) $ / " , $event -> term , $matches ) && $event -> parse ) {
$childID = $matches [ 1 ];
2019-07-05 15:15:38 +00:00
send_event ( new ImageRelationshipSetEvent ( $childID , $event -> id ));
2019-05-28 16:59:38 +00:00
}
if ( ! empty ( $matches )) {
$event -> metatag = true ;
}
}
public function onImageInfoBoxBuilding ( ImageInfoBoxBuildingEvent $event )
{
$event -> add_part ( $this -> theme -> get_parent_editor_html ( $event -> image ), 45 );
}
public function onImageDeletion ( ImageDeletionEvent $event )
{
global $database ;
if ( bool_escape ( $event -> image -> has_children )) {
$database -> execute ( " UPDATE images SET parent_id = NULL WHERE parent_id = :iid " , [ " iid " => $event -> image -> id ]);
}
if ( $event -> image -> parent_id !== null ) {
2019-07-05 15:15:38 +00:00
$this -> set_has_children ( $event -> image -> parent_id );
2019-05-28 16:59:38 +00:00
}
}
2019-07-05 15:15:38 +00:00
public function onImageRelationshipSet ( ImageRelationshipSetEvent $event )
2019-05-28 16:59:38 +00:00
{
global $database ;
2019-07-05 15:15:38 +00:00
$old_parent = $database -> get_one ( " SELECT parent_id FROM images WHERE id = :cid " , [ " cid " => $event -> child_id ]);
2019-09-29 13:30:55 +00:00
if ( $old_parent != $event -> parent_id ) {
2019-07-05 15:15:38 +00:00
if ( $database -> get_row ( " SELECT 1 FROM images WHERE id = :pid " , [ " pid " => $event -> parent_id ])) {
$result = $database -> execute ( " UPDATE images SET parent_id = :pid WHERE id = :cid " , [ " pid " => $event -> parent_id , " cid " => $event -> child_id ]);
if ( $result -> rowCount () > 0 ) {
$database -> execute ( " UPDATE images SET has_children = TRUE WHERE id = :pid " , [ " pid " => $event -> parent_id ]);
2019-09-29 13:30:55 +00:00
if ( $old_parent != null ) {
2019-07-05 15:15:38 +00:00
$this -> set_has_children ( $old_parent );
}
}
}
2019-05-28 16:59:38 +00:00
}
}
2019-07-05 15:15:38 +00:00
public static function get_children ( Image $image , int $omit = null ) : array
2019-05-28 16:59:38 +00:00
{
global $database ;
2019-07-05 15:15:38 +00:00
$results = $database -> get_all_iterable ( " SELECT * FROM images WHERE parent_id = :pid " , [ " pid " => $image -> id ]);
$output = [];
foreach ( $results as $result ) {
2019-09-29 13:30:55 +00:00
if ( $result [ " id " ] == $omit ) {
2019-07-05 15:15:38 +00:00
continue ;
}
$output [] = new Image ( $result );
2019-05-28 16:59:38 +00:00
}
2019-07-05 15:15:38 +00:00
return $output ;
2019-05-28 16:59:38 +00:00
}
private function remove_parent ( int $imageID )
{
global $database ;
$parentID = $database -> get_one ( " SELECT parent_id FROM images WHERE id = :iid " , [ " iid " => $imageID ]);
if ( $parentID ) {
$database -> execute ( " UPDATE images SET parent_id = NULL WHERE id = :iid " , [ " iid " => $imageID ]);
2019-07-05 15:15:38 +00:00
$this -> set_has_children ( $parentID );
2019-05-28 16:59:38 +00:00
}
}
2019-07-05 15:15:38 +00:00
private function set_has_children ( int $parent_id )
{
global $database ;
// Doesn't work on pgsql
// $database->execute("UPDATE images SET has_children = (SELECT * FROM (SELECT CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END FROM images WHERE parent_id = :pid) AS sub)
2019-09-29 13:30:55 +00:00
// WHERE id = :pid", ["pid"=>$parentID]);
2019-07-05 15:15:38 +00:00
$database -> execute (
" UPDATE images SET has_children = EXISTS (SELECT 1 FROM images WHERE parent_id = :pid) WHERE id = :pid " ,
2019-09-29 13:30:55 +00:00
[ " pid " => $parent_id ]
);
2019-07-05 15:15:38 +00:00
}
2014-02-03 13:54:09 +00:00
}