public function installApp($app_id)
 {
     $app = Mysql::getInstance()->from('apps')->where(array('id' => $app_id))->get()->first();
     if (empty($app)) {
         return false;
     }
     $repo = new GitHub($app['url']);
     $versions = $repo->getReleases(1);
     $info = $repo->getFileContent('package.json');
     if (count($versions) == 0) {
         return false;
     }
     $latest_release = $versions[0];
     if ($latest_release['tag_name'] == $app['current_version']) {
         return false;
     }
     $tmp_file = '/tmp/' . uniqid('app_') . '.zip';
     $zip_url = 'https://github.com/' . $repo->getOwner() . '/' . $repo->getRepository() . '/archive/' . $latest_release['tag_name'] . '.zip';
     file_put_contents($tmp_file, fopen($zip_url, 'r', false, stream_context_create(array('http' => array('header' => "User-Agent: stalker_portal\r\n")))));
     $path = PROJECT_PATH . '/../../' . Config::getSafe('apps_path', 'stalker_apps/') . self::safeFilename($info['name']);
     umask(0);
     if (!is_dir($path)) {
         mkdir($path, 0755, true);
     }
     $archive = new ZipArchive();
     if ($archive->open($tmp_file) === true) {
         $entry = $archive->getNameIndex(0);
         $dir = substr($entry, 0, strpos($entry, '/'));
         $result = $archive->extractTo($path);
         $archive->close();
         rename($path . '/' . $dir, $path . '/' . $latest_release['tag_name']);
     } else {
         return false;
     }
     unlink($tmp_file);
     if (!empty($result)) {
         $update_data = array('current_version' => $latest_release['name']);
         if (empty($app['alias'])) {
             $update_data['alias'] = self::safeFilename($info['name']);
             if (empty($app['name'])) {
                 $update_data['name'] = $info['name'];
             }
         }
         if (!empty($info['description'])) {
             $update_data['description'] = $info['description'];
         }
         if (!empty($info['config']['icons'])) {
             $update_data['icons'] = $info['config']['icons'];
         } else {
             $update_data['icons'] = 'icons';
         }
         if (!empty($info['config']['backgroundColor'])) {
             $update_data['icon_color'] = $info['config']['backgroundColor'];
         }
         Mysql::getInstance()->update('apps', $update_data, array('id' => $app_id));
     }
     return $result;
 }