00001 <?php
00015 $optionsWithArgs = array( 'concept', 'old', 's', 'e' );
00016
00017 require_once ( getenv( 'MW_INSTALL_PATH' ) !== false
00018 ? getenv( 'MW_INSTALL_PATH' ) . '/maintenance/commandLine.inc'
00019 : dirname( __FILE__ ) . '/../../../maintenance/commandLine.inc' );
00020
00021 $output_level = array_key_exists( 'quiet', $options ) ? 0 :
00022 ( array_key_exists( 'verbose', $options ) ? 2 : 1 );
00023
00024 if ( array_key_exists( 'help', $options ) ) {
00025 $action = 'help';
00026 } elseif ( array_key_exists( 'status', $options ) ) {
00027 $action = 'status';
00028 outputMessage( "\nDisplaying concept cache status information. Use CTRL-C to abort.\n\n" );
00029 } elseif ( array_key_exists( 'create', $options ) ) {
00030 $action = 'create';
00031 outputMessage( "\nCreating/updating concept caches. Use CTRL-C to abort.\n\n" );
00032 } elseif ( array_key_exists( 'delete', $options ) ) {
00033 $action = 'delete';
00034 outputMessage( "\nDeleting concept caches.\n\n" );
00035 $delay = 9;
00036 if ( outputMessage( "Abort with CTRL-C in the next $delay seconds ... " ) ) {
00037 wfCountDown( $delay );
00038 }
00039 } else {
00040 $action = 'help';
00041 }
00042
00043 if ( $action == 'help' ) {
00044 print <<<ENDS
00045
00046 This script is used to manage concept caches for Semantic MediaWiki. Concepts
00047 are semantic queries stored on Concept: pages. The elements of concepts can be
00048 computed online, or they can come from a pre-computed cache. The wiki may even
00049 be configured to display certain concepts only if they are available cached.
00050
00051 This script can create, delete and update these caches, or merely show their
00052 status.
00053
00054 Usage: php SMW_conceptCache.php <action> [<select concepts>] [<options>]
00055
00056 Actions:
00057 --help Show this message.
00058 --status Show the cache status of the selected concepts.
00059 --create Rebuild caches for the selected concepts.
00060 --delete Remove all caches for the selected concepts.
00061
00062 If no further options are given, all concepts in the wiki are processed.
00063
00064 Select concepts:
00065 --concept "Concept name" Process only this one concept.
00066 --hard Process only concepts that are not allowed to be computed
00067 online according to the current wiki settings.
00068 --update Process only concepts that already have some cache, i.e. do
00069 not create any new caches. For the opposite (only concepts
00070 without caches), use --old with a very high number.
00071 --old <min> Process only concepts with caches older than <min> minutes
00072 or with no caches at all.
00073 -s <startid> Process only concepts with page id of at least <startid>
00074 -e <endid> Process only concepts with page id of at most <endid>
00075
00076 Selection options can be combined to process only concepts that meet all the
00077 requirements at once. If --concept is given, then -s and -e are ignored.
00078
00079 Options:
00080 --quiet Do not give any output.
00081 --verbose Give additional output. No effect if --quiet is given.
00082
00083
00084 ENDS
00085 ;
00086 return;
00087 }
00088
00089 global $smwgIP;
00090 if ( !isset( $smwgIP ) ) {
00091 $smwgIP = dirname( __FILE__ ) . '/../';
00092 }
00093
00094 require_once( $smwgIP . 'includes/SMW_GlobalFunctions.php' );
00095
00096 $store = smwfGetStore();
00097 $db = wfGetDB( DB_SLAVE );
00098
00099 if ( !( $store instanceof SMWSQLStore2 ) ) {
00100 outputMessage( "Only SMWSQLStore2 supports this operation.\n Aborting." );
00101 return;
00102 }
00103
00104 $select_hard = array_key_exists( 'hard', $options );
00105 $select_update = array_key_exists( 'update', $options );
00106 $select_old = isset( $options['old'] ) ? intval( $options['old'] ) : false;
00107
00108 if ( isset( $options['concept'] ) ) {
00109 global $wgContLang;
00110 $concept = Title::newFromText( $wgContLang->getNsText( SMW_NS_CONCEPT ) . ':' . $options['concept'] );
00111
00112 if ( !is_null( $concept ) ) {
00113 doAction( $concept );
00114 }
00115 } else {
00116 if ( array_key_exists( 's', $options ) ) {
00117 $start = intval( $options['s'] );
00118 } else {
00119 $start = 0;
00120 }
00121
00122 $end = $db->selectField( 'page', 'MAX(page_id)', false, 'SMW_refreshData' );
00123
00124 if ( array_key_exists( 'e', $options ) ) {
00125 $end = min( intval( $options['e'] ), $end );
00126 }
00127
00128 $num_lines = 0;
00129
00130 for ( $id = $start; $id <= $end; $id++ ) {
00131 $title = Title::newFromID( $id );
00132
00133 if ( is_null( $title ) || ( $title->getNamespace() != SMW_NS_CONCEPT ) ) {
00134 continue;
00135 }
00136
00137 $num_lines += doAction( $title, $num_lines );
00138 }
00139 }
00140
00141 outputMessage( "\n\nDone.\n" );
00142
00143
00144 function doAction( $title, $numlines = false ) {
00145 global $action, $store, $select_hard, $select_old, $select_update, $smwgQMaxSize, $smwgQMaxDepth, $smwgQFeatures;
00146 $errors = array();
00147 $status = false;
00148 if ( $select_hard || $select_old || $select_update || ( $action == 'status' ) ) {
00149 $status = $store->getConceptCacheStatus( $title );
00150 }
00151 $skip = false;
00152 if ( ( $status !== false ) && ( $status['status'] == 'no' ) ) {
00153 $skip = 'page not cachable (no concept description, maybe a redirect)';
00154 } elseif ( ( $select_update ) && ( $status['status'] != 'full' ) ) {
00155 $skip = 'page not cached yet';
00156 } elseif ( ( $select_old ) && ( $status['status'] == 'full' ) && ( $status['date'] > ( strtotime( 'now' ) - $select_old * 60 ) ) ) {
00157 $skip = 'cache is not old yet';
00158 } elseif ( ( $select_hard ) && ( $smwgQMaxSize >= $status['size'] ) &&
00159 ( $smwgQMaxDepth >= $status['depth'] &&
00160 ( ( ~( ~( $status['features'] + 0 ) | $smwgQFeatures ) ) == 0 ) ) ) {
00161 $skip = 'concept is not "hard" according to wiki settings';
00162 }
00163 if ( $skip ) {
00164 $pref = ( $numlines !== false ) ? "($numlines) " : '';
00165 return ( outputMessage( $pref . 'Skipping concept "' . $title->getPrefixedText() . "\": $skip\n", 2 ) ) ? 1 : 0;
00166 }
00167 if ( $numlines !== false ) {
00168 outputMessage( "($numlines) " );
00169 }
00170 switch ( $action ) {
00171 case 'delete':
00172 outputMessage( 'Deleting cache for "' . $title->getPrefixedText() . "\" ...\n" );
00173 $errors = $store->deleteConceptCache( $title );
00174 break;
00175 case 'create':
00176 outputMessage( 'Creating cache for "' . $title->getPrefixedText() . "\" ...\n" );
00177 $errors = $store->refreshConceptCache( $title );
00178 break;
00179 default:
00180 outputMessage( 'Status of cache for "' . $title->getPrefixedText() . '": ' );
00181 if ( $status['status'] == 'no' ) {
00182 outputMessage( "Concept not known or redirect.\n" );
00183 } elseif ( $status['status'] == 'full' ) {
00184 outputMessage( 'Cache created at ' . date( 'Y-m-d H:i:s', $status['date'] ) . ' (' . floor( ( strtotime( 'now' ) - $status['date'] ) / 60 ) . ' minutes old), ' . $status['count'] . " elements in cache\n" );
00185 } else {
00186 outputMessage( "Not cached.\n" );
00187 }
00188 break;
00189 }
00190
00191 if ( count( $errors ) > 0 ) {
00192 outputMessage( ' ' . implode( $errors, "\n " ) . "\n" );
00193 }
00194
00195 return 1;
00196 }
00197
00198 function outputMessage( $message, $level = 1 ) {
00199 global $output_level;
00200 if ( $output_level < $level ) {
00201 return false;
00202 }
00203 print $message;
00204 return true;
00205 }