00001 <?php
00007 namespace Habari;
00008
00016 class Update extends Singleton
00017 {
00018 const UPDATE_URL = 'https://beacon.habariproject.org/';
00019
00020 private $beacons = array();
00021 private $update;
00022
00028 protected static function instance()
00029 {
00030 return self::getInstanceOf( get_class() );
00031 }
00032
00042 public static function add( $name, $beaconid, $current_version )
00043 {
00044 try {
00045 if ( empty( $name ) || empty( $beaconid ) || empty( $current_version ) ) {
00046 if ( empty( $name ) ) {
00047 $name = "Unnamed plugin";
00048 }
00049
00050 throw new \Exception( _t( 'Invalid Beacon updater information added for %s. The plugin or theme cannot be identified. Check your plugin\'s or theme\'s XML.', array($name) ) );
00051 }
00052
00053 self::instance()->beacons[ (string) $beaconid] = array( 'name' => (string) $name, 'version' => (string) $current_version );
00054 }
00055 catch ( \Exception $e ) {
00056
00057 EventLog::log( _t( 'Beacon updater failed! %s', array($e->getMessage())), 'err', 'update', 'habari' );
00058
00059
00060 return false;
00061 }
00062 }
00063
00070 public static function filter_unchanged( $beacon )
00071 {
00072 return isset( $beacon['latest_version'] );
00073 }
00074
00075
00082 public static function check()
00083 {
00084
00085 try {
00086
00087
00088 $instance = self::instance();
00089
00090
00091 self::register_beacons();
00092
00093
00094 $request = new RemoteRequest( self::UPDATE_URL, 'POST' );
00095
00096
00097 $request->set_params(
00098 Utils::array_map_field($instance->beacons, 'version')
00099 );
00100
00101 $request->set_timeout( 5 );
00102
00103
00104 $result = $request->execute();
00105
00106
00107 $update_data = $request->get_response_body();
00108
00109
00110 $instance->update = new \SimpleXMLElement( $update_data );
00111
00112 foreach ( $instance->update as $beacon ) {
00113
00114 $beacon_id = (string)$beacon['id'];
00115 $beacon_url = (string)$beacon['url'];
00116 $beacon_type = isset( $beacon['type'] ) ? (string)$beacon['type'] : 'addon';
00117
00118
00119
00120 if ( empty( $instance->beacons[ $beacon_id ] ) ) {
00121 continue;
00122 }
00123
00124
00125 $instance->beacons[ $beacon_id ]['id'] = $beacon_id;
00126 $instance->beacons[ $beacon_id ]['url'] = $beacon_url;
00127 $instance->beacons[ $beacon_id ]['type'] = $beacon_type;
00128
00129 foreach ( $beacon->update as $update ) {
00130
00131
00132 $u = array(
00133 'severity' => (string)$update['severity'],
00134 'version' => (string)$update['version'],
00135 'date' => isset( $update['date'] ) ? (string)$update['date'] : '',
00136 'url' => isset( $update['url'] ) ? (string)$update['url'] : '',
00137 'text' => (string)$update,
00138 );
00139
00140
00141
00142 if ( version_compare( $u['version'], $instance->beacons[ $beacon_id ]['version'] ) > 0 ) {
00143
00144
00145 if ( !isset( $instance->beacons[ $beacon_id ]['latest_version'] ) || version_compare( $u['version'], $instance->beacons[ $beacon_id ]['latest_version'] ) > 0 ) {
00146
00147
00148 $instance->beacons[ $beacon_id ]['latest_version'] = $u['version'];
00149
00150 }
00151
00152
00153 $instance->beacons[ $beacon_id ]['updates'][ $u['version'] ] = $u;
00154
00155 }
00156
00157 }
00158
00159 }
00160
00161
00162 return array_filter( $instance->beacons, Method::create( '\Habari\Update', 'filter_unchanged' ) );
00163
00164 }
00165 catch ( \Exception $e ) {
00166
00167
00168 throw $e;
00169 }
00170
00171 }
00172
00176 private static function add_plugins()
00177 {
00178
00179 $plugins = Plugins::get_active();
00180
00181 foreach ( $plugins as $plugin ) {
00182
00183
00184 if ( !isset( $plugin->info->guid ) ) {
00185 continue;
00186 }
00187
00188 Update::add( $plugin->info->name, $plugin->info->guid, $plugin->info->version );
00189
00190 }
00191
00192 }
00193
00201 public static function cron( $cronjob = null )
00202 {
00203
00204
00205 self::register_beacons();
00206
00207
00208 Options::set( 'updates_beacons', self::instance()->beacons );
00209
00210 try {
00211
00212 $updates = Update::check();
00213
00214
00215 Options::set( 'updates_available', $updates );
00216
00217 EventLog::log( _t( 'Updates check CronJob completed successfully.' ), 'info', 'update', 'habari' );
00218
00219
00220 return true;
00221 }
00222 catch ( \Exception $e ) {
00223
00224
00225 EventLog::log( _t( 'Updates check CronJob failed!' ), 'err', 'update', 'habari', $e->getMessage() );
00226
00227
00228 return false;
00229 }
00230
00231 }
00232
00237 private static function register_beacons()
00238 {
00239
00240
00241 if ( count( self::instance()->beacons ) > 0 ) {
00242 return;
00243 }
00244
00245 Update::add( 'Habari', '7a0313be-d8e3-11db-8314-0800200c9a66', Version::get_habariversion() );
00246
00247
00248 self::add_theme();
00249
00250
00251 self::add_plugins();
00252
00253 Plugins::act( 'update_check' );
00254
00255 }
00256
00260 private static function add_theme()
00261 {
00262
00263
00264 $theme = Themes::get_active_data( true );
00265
00266
00267 if ( isset( $theme['info']->guid ) ) {
00268 Update::add( $theme['info']->name, $theme['info']->guid, $theme['info']->version );
00269 }
00270
00271 }
00272
00277 public static function check_plugins()
00278 {
00279
00280
00281 self::register_beacons();
00282
00283
00284 $checked_list = Options::get( 'updates_beacons' );
00285
00286
00287 if ( $checked_list != self::instance()->beacons ) {
00288
00289
00290 Options::delete( 'updates_available' );
00291
00292
00293 CronTab::add_single_cron( 'update_check_single', Method::create( '\Habari\Update', 'cron' ), DateTime::create()->int, _t( 'Perform a single check for plugin updates, the plugin set has changed.' ) );
00294
00295 }
00296
00297 }
00298
00307 public static function updates_available( $guid = null )
00308 {
00309
00310 $updates = Options::get( 'updates_available', array() );
00311
00312 if ( $guid == null ) {
00313 return $updates;
00314 }
00315 else {
00316
00317 if ( isset( $updates[ $guid ] ) ) {
00318 return $updates[ $guid ];
00319 }
00320 else {
00321 return false;
00322 }
00323
00324 }
00325
00326 }
00327
00328 }
00329
00330 ?>