Changeset 1720

Show
Ignore:
Timestamp:
05/16/08 00:10:49 (7 months ago)
Author:
ringmaster
Message:

Adding searches on admin manage posts and comments pages. Fixes #335. Thanks, bjohnson.

Location:
trunk/htdocs/system
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • trunk/htdocs/system/admin/comments.php

    r1702 r1720  
    44    <span class="older pct10"><a href="#" onclick="timeline.skipLoupeLeft();return false">&laquo; Older</a></span> 
    55    <span class="currentposition pct15 minor">0-0 of 0</span> 
    6     <span class="search pct50"><input type="search" placeholder="Type and wait to search for any entry component" autosave="habaricontent" results="10"></span> 
     6    <span class="search pct50"><input type="search" placeholder="Type and wait to search for any entry component" autosave="habaricontent" results="10" value="<?php echo $search_args ?>"></span> 
    77    <span class="nothing pct15">&nbsp;</span> 
    88    <span class="newer pct10"><a href="#" onclick="timeline.skipLoupeRight();return false">Newer &raquo;</a></span> 
     
    3131    <input type="hidden" name="search" value="<?php echo $search; ?>"> 
    3232    <input type="hidden" name="limit" value="<?php echo $limit; ?>"> 
    33     <input type="hidden" name="index" value="<?php echo $index; ?>"> 
    3433    <input type="hidden" name="search_status" value="<?php echo $search_status; ?>"> 
    3534    <input type="hidden" id="nonce" name="nonce" value="<?php echo $wsse['nonce']; ?>"> 
  • trunk/htdocs/system/admin/entries.php

    r1702 r1720  
    55    <span class="older pct10"><a href="#" onclick="timeline.skipLoupeLeft();return false">&laquo; Older</a></span> 
    66    <span class="currentposition pct15 minor">0-0 of 0</span> 
    7     <span class="search pct50"><input type="search" placeholder="Type and wait to search for any entry component" autosave="habaricontent" results="10"></span> 
     7    <span class="search pct50"><input type="search" placeholder="Type and wait to search for any entry component" autosave="habaricontent" results="10" value="<?php echo $search_args ?>"></span> 
    88    <span class="nothing pct15">&nbsp;</span> 
    99    <span class="newer pct10"><a href="#" onclick="timeline.skipLoupeRight();return false">Newer &raquo;</a></span> 
  • trunk/htdocs/system/classes/adminhandler.php

    r1711 r1720  
    589589            'mass_spam_delete' => null, 
    590590            'mass_delete' => null, 
    591  
    592             'type' => Comment::type( 'comment' ), 
    593             'status' => Comment::status( 'approved' ), 
    594             'limit' => 30, 
    595             'orderby' => 'date DESC', 
    596             'default_radio' => array( 'approve'=>'', 'delete'=>'', 'spam'=>'', 'unapprove'=>'', 'edit' =>'' ), 
    597             'show' => '0', 
     591            'type' => 'All', 
     592            'limit' => 20, 
     593            'offset' => 0, 
    598594            'search' => '', 
    599             'search_fields' => array( 'content' ), 
    600             'search_status' => 1, 
    601             'search_type' => null, 
    602             'do_search' => false, 
    603             'index' => 1, 
    604             'offset' => 0, 
     595            'search_status' => 'All', 
    605596        ); 
    606597        foreach ( $locals as $varname => $default ) { 
     
    725716        } 
    726717 
    727         // Set up the limits select box 
    728         $limits= array( 5, 10, 20, 50, 100 ); 
    729         $limits= array_combine( $limits, $limits ); 
    730         $this->theme->limits= $limits; 
    731  
    732         // Set up the type select box 
    733         $types_tmp= Comment::list_comment_types(); 
    734         $types['All']= 'All'; 
    735         foreach ( $types_tmp as $type_key => $type_val  ) { 
    736             $types[$type_key]= $type_val; 
    737         } 
    738         $this->theme->types= $types; 
    739  
    740         // Set up the status select box 
    741         $statuses_tmp= Comment::list_comment_statuses(); 
    742         $statuses['All']= 'All'; 
    743         foreach ( $statuses_tmp as $status_key => $status_val  ) { 
    744             $statuses[$status_key]= $status_val; 
    745         } 
    746         $this->theme->statuses= $statuses; 
    747  
    748718        // we load the WSSE tokens 
    749719        // for use in the delete button 
     
    751721 
    752722        $arguments= array( 
     723            'type' => $type, 
     724            'status' => $search_status, 
    753725            'limit' => $limit, 
    754             'offset' => isset($offset) ? $offset : 0, 
     726            'offset' => $offset, 
    755727        ); 
    756728 
    757         // Decide what to display 
    758         $arguments['status']= intval( $search_status ); 
    759         switch ( $search_status ) { 
    760             case 'All': 
    761                 $this->theme->mass_delete= ''; 
    762                 unset( $arguments['status'] ); 
    763                 break; 
    764             case Comment::STATUS_SPAM: 
    765                 $this->theme->mass_delete= 'mass_spam_delete'; 
    766                 $default_radio['spam']= ' checked'; 
    767                 break; 
    768             case Comment::STATUS_APPROVED: 
    769                 $this->theme->mass_delete= ''; 
    770                 $default_radio['approve']= ' checked'; 
    771                 break; 
    772             case Comment::STATUS_UNAPPROVED: 
    773                 $this->theme->mass_delete= 'mass_delete'; 
    774                 $default_radio['unapprove']= ' checked'; 
    775                 break; 
    776             default: 
    777                 $this->theme->mass_delete= ''; 
    778                 break; 
    779         } 
    780         $this->theme->default_radio= $default_radio; 
    781  
    782         if($search_type != 'All') { 
    783             $arguments['type']= intval( $search_type ); 
     729        // there is no explicit 'all' type/status for comments, so we need to unset these arguments 
     730        // if that's what we want. At the same time we can set up the search field 
     731        $this->theme->search_args= ''; 
     732        if ( $type == 'All') {  
     733            unset( $arguments['type'] ); 
     734        } 
     735        else { 
     736            $this->theme->search_args= 'type:' . Comment::type_name( $type ) . ' '; 
     737        } 
     738        if ( $search_status == 'All') { 
     739            unset ( $arguments['status'] ); 
     740        } 
     741        else { 
     742            $this->theme->search_args.= 'status:' . Comment::status_name( $search_status ); 
    784743        } 
    785744 
    786745        if ( '' != $search ) { 
    787             $arguments['criteria']= $search; 
    788             $arguments['criteria_fields']= $search_fields; 
    789         } 
    790  
    791         if ( $search_type == 'All' ) { 
    792             unset( $arguments['type'] ); 
    793         } 
     746            $arguments= array_merge( $arguments, Comments::search_to_get( $search ) ); 
     747        } 
     748 
    794749        $this->theme->comments= Comments::get( $arguments ); 
    795750 
    796         // Get the page count 
    797         $arguments['count']= 'id'; 
    798         unset( $arguments['limit'] ); 
    799         unset( $arguments['offset'] ); 
    800         $totalpages= Comments::get( $arguments ); 
    801         $pagecount= ceil( $totalpages / $limit ); 
    802  
    803         // Put page numbers into an array for the page controls to output. 
    804         $pages= array(); 
    805         for ( $z= 1; $z <= $pagecount; $z++ ) { 
    806             $pages[$z]= $z; 
    807         } 
    808         $this->theme->pagecount= $pagecount; 
    809         $this->theme->pages= $pages; 
    810751        $this->theme->monthcomments= DB::get_results( 'SELECT MONTH(date) AS month, YEAR(date) AS year, COUNT(id) AS ct FROM {comments} GROUP BY year, month ORDER BY year, month', array() ); 
    811752    } 
     
    888829            'PasswordDigest' => '', 
    889830            'change' => '', 
    890  
    891831            'author' => 0, 
    892832            'type' => Post::type( 'entry' ), 
    893             'status' => Post::status( 'published' ), 
     833            'status' => Post::status( 'any' ), 
    894834            'limit' => 20, 
    895835            'offset' => 0, 
    896             'year_month' => 'Any', 
    897836            'search' => '', 
    898             'do_search' => false, 
    899             'index' => 1, 
    900837        ); 
    901838        foreach ( $locals as $varname => $default ) { 
     
    947884        } 
    948885 
    949         // Set up Authors select box 
    950         $authors_temp= DB::get_results( 'SELECT DISTINCT username, user_id FROM {users} JOIN {posts} ON {users}.id = {posts}.user_id ORDER BY username ASC' ); 
    951         array_unshift( $authors_temp, new QueryRecord( array( 'username' => 'All', 'user_id' => 0 ) ) ); 
    952         $authors= array(); 
    953         foreach ( $authors_temp as $author ) { 
    954             $authors[$author->user_id]= $author->username; 
    955         } 
    956         $this->theme->authors= $authors; 
    957  
    958         // Set up the dates select box 
    959         $dates= DB::get_column( "SELECT pubdate FROM " . DB::table( 'posts' ) . ' ORDER BY pubdate DESC' ); 
    960         $dates= array_map( create_function( '$date', 'return strftime( "%Y-%m", strtotime( $date ) );' ), $dates ); 
    961         array_unshift( $dates, 'Any' ); 
    962         $dates= array_combine( $dates, $dates ); 
    963         $this->theme->dates= $dates; 
    964  
    965         // Set up the limits select box 
    966         $limits= array( 5, 10, 20, 50, 100 ); 
    967         $limits= array_combine( $limits, $limits ); 
    968         $this->theme->limits= $limits; 
    969  
    970886        // we load the WSSE tokens 
    971887        // for use in the delete button 
     
    978894            'offset' => $offset, 
    979895        ); 
    980         if ( 'any' != strtolower( $year_month ) ) { 
    981             list( $arguments['year'], $arguments['month'] )= explode( '-', $year_month ); 
    982         } 
     896 
    983897        if ( '' != $search ) { 
    984             $arguments['criteria']= $search; 
     898            $arguments= array_merge( $arguments, Posts::search_to_get( $search ) ); 
    985899        } 
    986900        $this->theme->posts= Posts::get( $arguments ); 
    987901 
    988         // Get the page count 
    989         $arguments['count']= 'id'; 
    990         unset( $arguments['limit'] ); 
    991         unset( $arguments['offset'] ); 
    992         $totalpages= Posts::get( $arguments ); 
    993         $pagecount= ceil( $totalpages / $limit ); 
    994  
    995         // Put page numbers into an array for the page controls to output. 
    996         $pages= array(); 
    997         for ( $z= 1; $z <= $pagecount; $z++ ) { 
    998             $pages[$z]= $z; 
    999         } 
    1000         $this->theme->pagecount= $pagecount; 
    1001         $this->theme->pages= $pages; 
     902        // setup keyword in search field if a status or type was passed in POST 
     903        $this->theme->search_args= ''; 
     904        if ( $status != Post::status( 'any' ) ) { 
     905            $this->theme->search_args= 'status:' . Post::status_name( $status ) . ' '; 
     906        } 
     907        if ( $type != Post::type( 'any' ) ) { 
     908            $this->theme->search_args.= 'type:' . Post::type_name( $type ); 
     909        } 
     910 
    1002911        $this->theme->monthposts= DB::get_results( 'SELECT MONTH(pubdate) AS month, YEAR(pubdate) AS year, COUNT(id) AS ct FROM {posts} WHERE content_type = ? GROUP BY year, month ORDER BY year, month', array( $type ) ); 
    1003912    } 
  • trunk/htdocs/system/classes/comments.php

    r1688 r1720  
    574574        DB::query( 'DELETE FROM {commentinfo} WHERE comment_id NOT IN ( SELECT id FROM {comments} )' ); 
    575575    } 
     576 
     577    /** 
     578     * Parses a search string for status, type, author, and tag keywords. Returns 
     579     * an associative array which can be passed to Comments::get(). If multiple 
     580     * authors, statuses, or types are specified, we assume an implicit OR 
     581     * such that (e.g.) any author that matches would be returned. 
     582     * 
     583     * @param string $search_string The search string 
     584     * @return array An associative array which can be passed to Comments::get() 
     585     */ 
     586    public static function search_to_get( $search_string ) { 
     587        $keywords= array('author' => 1, 'status' => 1, 'type' => 1 ); 
     588        // Comments::list_comment_statuses and list_comment_types return associative arrays with key/values 
     589        // in the opposite order of the equivalent functions in Posts. Maybe we should change this? 
     590        // In any case, we need to flip them for our purposes 
     591        $statuses= array_flip( Comment::list_comment_statuses() ); 
     592        $types= array_flip( Comment::list_comment_types() ); 
     593        $arguments= array( 
     594                        'name' => array(), 
     595                        'status' => array(), 
     596                        'type' => array() 
     597                        ); 
     598        $criteria= ''; 
     599         
     600        $tokens= explode( ' ', $search_string ); 
     601         
     602        foreach( $tokens as $token ) { 
     603            // check for a keyword:value pair 
     604            if ( preg_match( '/^\w+:\S+$/', $token ) ) { 
     605                list( $keyword, $value )= explode( ':', $token ); 
     606 
     607                $keyword= strtolower( $keyword ); 
     608                switch ( $keyword ) { 
     609                    case 'author': 
     610                        $arguments['name'][]= $value; 
     611                        break; 
     612                    case 'status': 
     613                        if ( isset( $statuses[ucfirst( $value )] ) ) { 
     614                            $arguments['status'][]= (int) $statuses[ucfirst( $value )]; 
     615                        } 
     616                        break; 
     617                    case 'type': 
     618                        if ( isset( $types[ucfirst( $value )] ) ) { 
     619                            $arguments['type'][]= (int) $types[ucfirst( $value )]; 
     620                        } 
     621                        break; 
     622                } 
     623            } 
     624            else { 
     625                $criteria .= $token . ' '; 
     626            } 
     627        } 
     628        // flatten keys that have single-element or no-element arrays 
     629        foreach ( $arguments as $key => $arg ) { 
     630            switch ( count( $arg ) ) { 
     631                case 0: 
     632                    unset( $arguments[$key] ); 
     633                    break; 
     634                case 1: 
     635                    $arguments[$key]= $arg[0]; 
     636                    break; 
     637            } 
     638        } 
     639 
     640        if ( $criteria != '' ) { 
     641            $arguments['criteria']= $criteria; 
     642        } 
     643         
     644        return $arguments; 
     645 
     646    } 
    576647} 
    577648?> 
  • trunk/htdocs/system/classes/posts.php

    r1672 r1720  
    659659        return array_search( $needle, $this->getArrayCopy() ); 
    660660    } 
     661     
     662    /** 
     663     * Parses a search string for status, type, author, and tag keywords. Returns 
     664     * an associative array which can be passed to Posts::get(). If multiple 
     665     * authors, statuses, tags, or types are specified, we assume an implicit OR 
     666     * such that (e.g.) any author that matches would be returned. 
     667     * 
     668     * @param string $search_string The search string 
     669     * @return array An associative array which can be passed to Posts::get() 
     670     */ 
     671    public static function search_to_get( $search_string ) 
     672    { 
     673        $keywords= array( 'author' => 1, 'status' => 1, 'type' => 1, 'tag' => 1 ); 
     674        $statuses= Post::list_post_statuses(); 
     675        $types= Post::list_active_post_types(); 
     676        $arguments= array( 
     677                        'user_id' => array(), 
     678                        'status' => array(), 
     679                        'content_type' => array(), 
     680                        'tag' => array() 
     681                        ); 
     682        $criteria= ''; 
     683         
     684        $tokens= explode( ' ', $search_string ); 
     685         
     686        foreach( $tokens as $token ) { 
     687            // check for a keyword:value pair 
     688            if ( preg_match( '/^\w+:\S+$/', $token ) ) { 
     689                list( $keyword, $value )= explode( ':', $token ); 
     690 
     691                $keyword= strtolower( $keyword ); 
     692                switch ( $keyword ) { 
     693                    case 'author': 
     694                        if ( $u= User::get( $value ) ) { 
     695                            $arguments['user_id'][]= (int) $u->id; 
     696                        } 
     697                        break; 
     698                    case 'tag': 
     699                        $arguments['tag'][]= $value; 
     700                        break; 
     701                    case 'status': 
     702                        if ( isset( $statuses[$value] ) ) { 
     703                            $arguments['status'][]= (int) $statuses[$value]; 
     704                        } 
     705                        break; 
     706                    case 'type': 
     707                        if ( isset( $types[$value] ) ) { 
     708                            $arguments['content_type'][]= (int) $types[$value]; 
     709                        } 
     710                        break; 
     711                } 
     712            } 
     713            else { 
     714                $criteria .= $token . ' '; 
     715            } 
     716        } 
     717 
     718        // flatten keys that have single-element or no-element arrays 
     719        foreach ( $arguments as $key => $arg ) { 
     720            switch ( count( $arg ) ) { 
     721                case 0: 
     722                    unset( $arguments[$key] ); 
     723                    break; 
     724                case 1: 
     725                    $arguments[$key]= $arg[0]; 
     726                    break; 
     727            } 
     728        } 
     729 
     730        if ( $criteria != '' ) { 
     731            $arguments['criteria']= $criteria; 
     732        } 
     733         
     734        return $arguments; 
     735    } 
    661736 
    662737}