/**
  * Sets $this->data['packages'] for the template
  *
  * This function groups packages into applications, so e.g. 5 variants of
  * the same package will mean 1 item in the final array.
  *
  * @param array of com_meeg_package_details objects
  * @param string filter type: 'top' or 'staging': settings URL will depend on it
  * @param boolean if true then return info about older packages too
  *
  * @return array
  *
  */
 public function set_data(array $packages, $filter_type = 'top', $history = false)
 {
     $all = array();
     // a flag for tricky situations caused by additional hand imports
     $remember = false;
     // store guid for promoted apps (ie. apps that passed qa)
     $promotedtoguid = '';
     $promotedfromguid = '';
     $default_latest = array('packagescore' => '', 'packagename' => '', 'packageguid' => '', 'promotedfromguid' => '', 'promotedtoguid' => '', 'os' => '', 'version' => '', 'size' => 'n/a', 'promoted' => 'n/a', 'released' => 'n/a', 'lastupdate' => 'n/a', 'variants' => array(), 'iconurl' => '');
     $latest = $default_latest;
     $matched = $this->request->get_route()->get_matched();
     // this index will be used to grab the download URL of the appropriate arch variant of the package
     $index = 0;
     // this method is called from other classes too
     $this->isuser = $this->mvc->authentication->is_user();
     if (isset($matched['ux']) && array_key_exists($matched['ux'], $this->mvc->configuration->ux_arch_map)) {
         $index = $this->mvc->configuration->ux_arch_map[$matched['ux']];
     }
     foreach ($packages as $package) {
         if ($package->packagename != $latest['packagename']) {
             // processing a different package, so reset some internal arrays
             $all = array();
             $latest = $default_latest;
         }
         if (!isset($this->data['packages'][$package->packagename]['name'])) {
             // set the guid
             $this->data['packages'][$package->packagename]['packageguid'] = $package->packageguid;
             // set the name
             $this->data['packages'][$package->packagename]['name'] = $package->packagename;
             // set the title
             $this->data['packages'][$package->packagename]['title'] = $package->packagetitle;
             // get roles
             $this->data['packages'][$package->packagename]['roles'] = self::get_roles($package->packageguid);
             // gather some basic stats
             $stats = com_meego_packages_controllers_package::get_statistics($package->packagename);
             // set the total number of comments
             $this->data['packages'][$package->packagename]['number_of_comments'] = $stats['number_of_comments'];
             // figure out if there are posted forms for this app
             $this->data['packages'][$package->packagename]['posted_forms'] = count(com_meego_packages_forms::get_all_forms($package->packageguid));
             if (array_key_exists('number_of_rates', $stats)) {
                 // total number of rates
                 $this->data['packages'][$package->packagename]['number_of_rates'] = $stats['number_of_rates'];
             }
             // the stars as html snippet for the average rating; should be used as-is in the template
             $this->data['packages'][$package->packagename]['average_rating'] = $stats['average_rating'];
             $this->data['packages'][$package->packagename]['stars'] = com_meego_ratings_controllers_rating::draw_stars($stats['average_rating']);
             // collect ratings and comments (used in application detailed view)
             if (!array_key_exists('ratings', $this->data['packages'][$package->packagename])) {
                 $this->data['packages'][$package->packagename]['ratings'] = array();
             }
             $ratings = self::prepare_ratings($package->packagename, $history);
             $this->data['packages'][$package->packagename]['ratings'] = $ratings['ratings'];
             $this->data['packages'][$package->packagename]['is_there_comment'] = $history ? $history : $ratings['comment'];
             // set a summary
             $this->data['packages'][$package->packagename]['summary'] = $package->packagesummary;
             // set a longer description
             $this->data['packages'][$package->packagename]['description'] = $package->packagedescription;
             $this->data['packages'][$package->packagename]['basecategoryname'] = $package->basecategoryname;
             // base category name
             $this->data['packages'][$package->packagename]['iconurl'] = false;
             $this->data['packages'][$package->packagename]['screenshoturl'] = false;
             // a package may have multiple arches
             // but we should nominate one to be the default in order to support the new design
             $this->data['packages'][$package->packagename]['defaultdownloadurl'] = false;
             $_package = new com_meego_package($package->packageid);
             $attachments = $_package->list_attachments();
             $_icon_marker = 'icon.png';
             $_screenshot_marker = 'screenshot.png';
             $this->data['packages'][$package->packagename]['screenshots'] = false;
             foreach ($attachments as $attachment) {
                 if ($attachment->mimetype == 'image/png') {
                     if (strrpos($attachment->name, $_screenshot_marker) !== false) {
                         $this->data['packages'][$package->packagename]['screenshots'][] = $this->mvc->dispatcher->generate_url('attachmentserver_variant', array('guid' => $attachment->guid, 'variant' => 'prop480x300', 'filename' => $attachment->name), '/');
                     }
                     if (strrpos($attachment->name, $_icon_marker) !== false && !$this->data['packages'][$package->packagename]['iconurl']) {
                         $this->data['packages'][$package->packagename]['iconurl'] = $this->mvc->dispatcher->generate_url('attachmentserver_variant', array('guid' => $attachment->guid, 'variant' => 'icon', 'filename' => $attachment->name), '/');
                     }
                 }
             }
         }
         if (count($this->data['packages'][$package->packagename]['screenshots'])) {
             $this->data['packages'][$package->packagename]['screenshoturl'] = $this->data['packages'][$package->packagename]['screenshots'][0];
         }
         // if the UX is empty then we consider the package to be good for all UXes
         // this value is used in the template to show a proper icon
         $package->ux = $package->repoosux;
         if (!strlen($package->ux)) {
             $package->ux = 'universal';
         }
         $this->data['ux'] = $package->ux;
         // provide a link to visit the app page
         $package->localurl = self::get_localurl($package);
         // provide a link to visit the app's full history
         $this->data['packages'][$package->packagename]['historyurl'] = self::get_historyurl($package);
         $variant_info = array('ux' => $package->repoosux, 'repoos' => $package->repoos, 'repoarch' => $package->repoarch, 'packageid' => $package->packageid, 'packageguid' => $package->packageguid, 'packageinstallfileurl' => $package->packageinstallfileurl);
         //echo "current latest: " . $latest['packagename'] . ':' . $latest['version'] . ' vs package: ' . $package->packagename . ':' . $package->packageversion . "\n";
         if ($latest['version'] <= $package->packageversion) {
             $qarelease = $this->mvc->i18n->get('label_app_type_qarelease');
             $promoted = $this->mvc->i18n->get('label_app_type_promoted');
             $staging = $this->mvc->i18n->get('label_app_type_staging');
             //echo $package->packagename . ':' . $package->packageversion . ' from ' . $package->repoprojectname . " will be set as latest\n";
             //echo "latest score: " . $latest['packagescore'] . ', curtent package score: ' . $package->packagescore . "\n";
             if ($latest['packageguid']) {
                 if ($latest['version'] == $package->packageversion) {
                     if ($latest['repoid'] == $package->repoid && (int) $latest['packagescore'] > $package->packagescore) {
                         $remember = $latest;
                         //echo $package->packageversion . ' (score: ' . $remember['packagescore'] . ') from ' . $package->reponame .' repo id: ' . $package->repoid . " is already the latest, maybe it was reimported by hand for some reason\n";
                     } else {
                         //echo $package->packageversion . " is already the latest, this is probably from an other project; check if it was ever promoted\n";
                         $predecessors = self::get_predecessors($package->packageguid, 3);
                         if (count($predecessors)) {
                             foreach ($predecessors as $key => $guid) {
                                 //echo "compare: " . $guid . ' vs ' . $latest['packageguid'] . "\n";
                                 if ($guid == $latest['packageguid'] || isset($remember) && $guid == $remember['packageguid'] && $remember['packagescore'] > 0 && $remember['packagescore'] > $package->packagescore) {
                                     //echo "this version: " . $package->packageversion . ' was promoted on ' . $package->packagecreated->format('Y-m-d h:i e') . "\n";
                                     $promotedfromguid = $guid;
                                     if ($remember) {
                                         //echo "update history backwards";
                                         $all[$remember['released']]['promotedtoguid'] = $remember['packageguid'];
                                         $all[$remember['released']]['type'] = $promoted;
                                         $remember = false;
                                     } else {
                                         $promotedtoguid = $package->packageguid;
                                     }
                                 }
                             }
                         }
                     }
                 }
                 $all[$latest['released']] = array('size' => $latest['size'], 'repoid' => $latest['repoid'], 'version' => $latest['version'], 'variants' => $latest['variants'], 'released' => $latest['released'], 'packageid' => $latest['packageid'], 'packageguid' => $latest['packageguid'], 'packagescore' => $latest['packagescore'], 'hidden' => $latest['hidden'], 'publishers' => $latest['publishers'], 'localurl' => isset($latest['localurl']) ? $latest['localurl'] : false);
                 if ($latest['promotedfromguid']) {
                     $latest['type'] = $qarelease;
                     $all[$latest['released']]['promotedfromguid'] = $latest['promotedfromguid'];
                 } else {
                     if ($promotedtoguid) {
                         $latest['type'] = $promoted;
                         $all[$latest['released']]['promotedtoguid'] = $promotedtoguid;
                         $promotedtoguid = '';
                     } else {
                         $latest['type'] = $staging;
                     }
                 }
                 $all[$latest['released']]['type'] = $latest['type'];
                 $latest = $default_latest;
             }
             $latest['ux'] = $package->ux;
             $latest['size'] = $package->packagesize ? (int) ($package->packagesize / 1024) . ' kb' : 'n/a';
             $latest['publishers'] = self::get_roles($package->packageguid, 'downloader');
             $latest['repoid'] = $package->repoid;
             $latest['hidden'] = $package->packagehidden;
             $latest['version'] = $package->packageversion;
             $latest['released'] = $package->packagecreated->format('Y-m-d H:i');
             // @todo: this might not be needed
             $latest['variants'][$package->repoarch] = $variant_info;
             $latest['packageid'] = $package->packageid;
             $latest['lastupdate'] = $package->packagerevised->format('Y-m-d H:i');
             $latest['packageguid'] = $package->packageguid;
             $latest['packagename'] = $package->packagename;
             $latest['packagescore'] = $package->packagescore;
             if ($promotedfromguid) {
                 $latest['promotedfromguid'] = $promotedfromguid;
                 if (!$latest['hidden']) {
                     $latest['localurl'] = $package->localurl;
                 }
                 $promotedfromguid = '';
             } else {
                 if ($promotedtoguid) {
                     $latest['promotedtoguid'] = $promotedtoguid;
                     $promotedtoguid = '';
                 } else {
                     if (!$latest['hidden']) {
                         $latest['localurl'] = '/staging' . $package->localurl;
                     }
                 }
             }
         } elseif ($latest['version'] > $package->packageversion) {
             // this should not happen if the packages are ordered by version
             // anyway this package should go to all
             //echo $package->packageversion . ' from ' . $package->repoprojectname . ' goes to all' . "\n";
             $all[$package->packagecreated->format('Y-m-d H:i')] = $package->packageguid;
         }
         // add the latest to the all array
         $all[$latest['released']] = array('size' => $latest['size'], 'repoid' => $latest['repoid'], 'version' => $latest['version'], 'variants' => $latest['variants'], 'released' => $latest['released'], 'packageid' => $latest['packageid'], 'packageguid' => $latest['packageguid'], 'packagescore' => $latest['packagescore'], 'hidden' => $latest['hidden'], 'publishers' => $latest['publishers'], 'localurl' => isset($latest['localurl']) ? $latest['localurl'] : false);
         if ($latest['promotedfromguid']) {
             $all[$latest['released']]['type'] = $qarelease;
             $all[$latest['released']]['promotedfromguid'] = $latest['promotedfromguid'];
         } else {
             $all[$latest['released']]['type'] = $staging;
         }
         //echo "\n\n";
         //ob_flush();
         // set the default download url for the package
         if (array_key_exists($index, $latest['variants']) && !$this->data['packages'][$package->packagename]['defaultdownloadurl']) {
             // index was set at the beginning of this method
             $this->data['packages'][$package->packagename]['defaultdownloadurl'] = $latest['variants'][$index]['packageinstallfileurl'];
             // set a different downloadurl in case the configured download schema for this OS is 'apps'
             if (array_key_exists('download', $this->mvc->configuration->os_ux[$latest['variants'][$index]['repoos']]) && $this->mvc->configuration->os_ux[$latest['variants'][$index]['repoos']]['download'] == 'apps') {
                 $this->data['packages'][$package->packagename]['defaultdownloadurl'] = 'apps://' . $latest['variants'][$index]['packageid'];
             }
         }
         // set the latest of this package
         if (!array_key_exists('latest', $this->data['packages'][$package->packagename])) {
             $this->data['packages'][$package->packagename]['latest'] = array('version' => '', 'variants' => array());
         }
         if ($this->data['packages'][$package->packagename]['latest']['version'] <= $latest['version']) {
             $this->data['packages'][$package->packagename]['latest'] = $latest;
         }
         // always keep it up-to-date
         $this->data['packages'][$package->packagename]['all'] = $all;
         switch ($filter_type) {
             case 'staging':
                 $route_id = 'staging_apps_by_name';
                 break;
             case 'top':
             default:
                 $route_id = 'apps_by_name';
         }
         $this->data['packages'][$package->packagename]['localurl'] = $this->mvc->dispatcher->generate_url($route_id, array('os' => $package->repoos, 'version' => $package->repoosversion, 'ux' => is_array($matched) && array_key_exists('ux', $matched) ? $matched['ux'] : $package->ux, 'basecategory' => com_meego_packages_controllers_package::determine_base_category($package), 'packagename' => $package->packagename), $this->request);
         // do not bother any further for hidden instances
         if ($package->packagehidden) {
             continue;
         }
         // get the workflows for this package
         // todo: this will get workflows for all versions
         if (!array_key_exists('workflows', $this->data['packages'][$package->packagename])) {
             $this->data['packages'][$package->packagename]['workflows'] = array();
         }
         // get workflows, if any
         $workflows = self::get_workflows($package);
         if (is_array($workflows)) {
             $this->data['packages'][$package->packagename]['workflows'] = $workflows;
         }
     }
     //foreach
     if (isset($package)) {
         // let's unset the default variant, so we don't list it among the "other downloads"
         unset($this->data['packages'][$package->packagename]['latest']['variants'][$index]);
     }
     /*
             if (   isset($package)
                 && array_key_exists($package->packagename, $this->data['packages']))
             {
                 $latestversion = $this->data['packages'][$package->packagename]['latest']['version'];
                 if (array_key_exists($latestversion, $this->data['packages'][$package->packagename]['all']))
                 {
                     // always remove the latest from the all array
                     unset($this->data['packages'][$package->packagename]['all'][$latestversion]);
                 }
             }
     */
     // and we don't need this either
     unset($latest);
     if (isset($this->data['packages'])) {
         return $this->data['packages'];
     }
 }
Beispiel #2
0
 /**
  * Sets data for the template
  * It is used in two routes so that is why we have it as a separate function
  * @param array of packages
  */
 public function set_data(array $packages)
 {
     // let's do a smart grouping by package_title (ie. short names)
     $variant_counter = 0;
     foreach ($packages as $package) {
         $this->data['categorytree'] = self::determine_category_tree($package);
         $tree_url = $this->mvc->dispatcher->generate_url('package_overview_tree', array('categorytree' => $this->data['categorytree'], 'packagename' => $package->packagename), $this->request);
         // certain things must not be recorded in evert iteration of this loop
         // if we recorded the name, then we are pretty sure we recorded everything
         if (!isset($this->data['packages'][$package->packagename]['name'])) {
             // set the name
             $this->data['packages'][$package->packagename]['name'] = $package->packagename;
             if (isset($this->data['base']) && $this->data['base']) {
                 // if browsing by base categories, then we have to figure out the
                 // the category tree of the package
                 //$this->data['categorytree'] = self::determine_category_tree($package);
                 if (!strlen($this->data['basecategory'])) {
                     $this->data['basecategory'] = self::determine_base_category($package);
                 }
                 // if base category is still empty
                 // then it means that this package is not yet covered by any base category
                 // so we have to provide a different URL
                 if (!strlen($this->data['basecategory'])) {
                     // local url to a package index page
                     $this->data['packages'][$package->packagename]['localurl'] = $tree_url;
                 } else {
                     // ok, so we got a base category, let's form the url
                     // check if we have ux
                     if (!array_key_exists('ux', $this->data)) {
                         if ($package->repoosux == '') {
                             $this->data['ux'] = 'universal';
                         } else {
                             $this->data['ux'] = strtolower($package->repoosux);
                         }
                     }
                     // if could not figure out the ux then provide a tree url
                     if (!strlen($this->data['ux'])) {
                         $this->data['packages'][$package->packagename]['localurl'] = $tree_url;
                     } else {
                         $this->data['packages'][$package->packagename]['localurl'] = $this->mvc->dispatcher->generate_url('apps_by_name', array('os' => $package->repoos, 'version' => $package->repoosversion, 'ux' => $this->data['ux'], 'basecategory' => $this->data['basecategory'], 'packagename' => $package->packagename), $this->request);
                     }
                     $this->data['ux'] = '';
                     $this->data['basecategory'] = '';
                 }
             } else {
                 // local url to a package index page
                 $this->data['packages'][$package->packagename]['localurl'] = $tree_url;
             }
             // gather some basic stats
             $stats = self::get_statistics($package->packagename);
             // set the total number of comments
             $this->data['packages'][$package->packagename]['number_of_comments'] = $stats['number_of_comments'];
             // the stars as html snippet for the average rating; should be used as-is in the template
             $this->data['packages'][$package->packagename]['stars'] = com_meego_ratings_controllers_rating::draw_stars($stats['average_rating']);
             // set a longer description
             $this->data['packages'][$package->packagename]['description'] = $package->packagedescription;
             // set a screenshoturl if the package object has any
             $this->data['packages'][$package->packagename]['screenshoturl'] = false;
             $_package = new com_meego_package($package->packageid);
             $attachments = $_package->list_attachments();
             foreach ($attachments as $attachment) {
                 if ($attachment->mimetype == 'image/png' && !$this->data['packages'][$package->packagename]['screenshoturl']) {
                     $this->data['packages'][$package->packagename]['screenshoturl'] = $this->mvc->dispatcher->generate_url('attachmentserver_variant', array('guid' => $attachment->guid, 'variant' => 'prop480x300', 'filename' => $attachment->name), '/');
                     break;
                 }
             }
         }
         // we group the variants into providers. a provider is basically a project repository, e.g. home:fal
         $this->data['packages'][$package->packagename]['providers'][$package->repoprojectname]['projectname'] = $package->repoprojectname;
         // if the UX is empty then we consider the package to be good for all UXes
         // this value is used in the template to show a proper icon
         $package->ux = $package->repoosux;
         if (!strlen($package->ux)) {
             $package->ux = 'universal';
         }
         // provide a link to visit the page of a certain package variant
         /*
                     $package->localurl = $this->mvc->dispatcher->generate_url
                     (
                         'package_instance',
                         array
                         (
                             'package' => $package->packagename,
                             'version' => $package->packageversion,
                             'project' => $package->repoprojectname,
                             'repository' => $package->reponame,
                             'arch' => $package->repoarch
                         ),
                         $this->request
                     );
         */
         $basecategory = null;
         if (is_numeric($package->basecategory)) {
             $basecategory = self::determine_base_category($package);
         } else {
             $basecategory = $package->basecategory;
         }
         if ($basecategory) {
             $package->localurl = $this->mvc->dispatcher->generate_url('apps_by_name', array('os' => $package->repoos, 'version' => $package->repoosversion, 'ux' => $package->ux, 'basecategory' => $basecategory, 'packagename' => $package->packagename), $this->request);
         }
         // the variants are basically the versions built for different hardware architectures (not UXes)
         $this->data['packages'][$package->packagename]['providers'][$package->repoprojectname]['variants'][] = $package;
     }
 }
Beispiel #3
0
 /**
  * The main method to return list of packages
  *
  * @param array HTTP GET arguments
  */
 public function get_data(array $args)
 {
     $constraints = array();
     $query = $this->request->get_query();
     $storage = new midgard_query_storage('com_meego_package_details');
     $q = new midgard_query_select($storage);
     $qc = new midgard_query_constraint_group('OR');
     // filter all hidden packages
     $qc->add_constraint(new midgard_query_constraint(new midgard_query_property('packagehidden'), '=', new midgard_query_value(1)));
     // filter packages by their names
     foreach ($this->mvc->configuration->sql_package_filters as $filter) {
         $qc->add_constraint(new midgard_query_constraint(new midgard_query_property('packagename'), 'LIKE', new midgard_query_value($filter)));
         $qc->add_constraint(new midgard_query_constraint(new midgard_query_property('packagetitle'), 'LIKE', new midgard_query_value($filter)));
     }
     $q->set_constraint($qc);
     $q->execute();
     $filtered = array();
     foreach ($q->list_objects() as $package) {
         $filtered[] = $package->packageid;
     }
     if (count($filtered)) {
         $constraints[] = new midgard_query_constraint(new midgard_query_property('packageid'), 'NOT IN', new midgard_query_value($filtered));
     }
     if (count($query)) {
         if (array_key_exists('search', $query) && strlen($query['search'])) {
             $cnstr1 = new midgard_query_constraint(new midgard_query_property('packagename'), 'LIKE', new midgard_query_value('%' . $query['search'] . '%'));
             $cnstr2 = new midgard_query_constraint(new midgard_query_property('packagetitle'), 'LIKE', new midgard_query_value('%' . $query['search'] . '%'));
             $group_constraint = new midgard_query_constraint_group("OR", $cnstr1, $cnstr2);
             $constraints[] = $group_constraint;
         }
         if (array_key_exists('categories', $query) && strlen($query['categories'])) {
             $constraints[] = new midgard_query_constraint(new midgard_query_property('basecategory'), 'IN', new midgard_query_value(explode('x', $query['categories'])));
         }
         if (array_key_exists('license', $query) && strlen($query['license'])) {
             $constraints[] = new midgard_query_constraint(new midgard_query_property('packagelicenseid'), 'IN', new midgard_query_value(explode(',', $query['license'])));
         }
         if (array_key_exists('distribution', $query) && strlen($query['distribution'])) {
             $constraints[] = new midgard_query_constraint(new midgard_query_property('repoosversionid'), 'IN', new midgard_query_value(explode(',', $query['distribution'])));
         }
         if (array_key_exists('dependency', $query) && strlen($query['dependency'])) {
             $constraints[] = new midgard_query_constraint(new midgard_query_property('repoosuxid'), 'IN', new midgard_query_value(explode(',', $query['dependency'])));
         }
         if (array_key_exists('sortmode', $query) && strlen($query['sortmode'])) {
             switch ($query['sortmode']) {
                 case 'new':
                     $q->add_order(new midgard_query_property('packagecreated'), SORT_DESC);
                     break;
                 case 'high':
                     $q->add_order(new midgard_query_property('statscachedratingvalue'), SORT_DESC);
                     //sort by name too
                     $q->add_order(new midgard_query_property('packagetitle'), SORT_ASC);
                     break;
                 case 'down':
                     //sort by name too
                     $q->add_order(new midgard_query_property('statscachedratingvalue'), SORT_ASC);
                 case 'alpha':
                 default:
                     $q->add_order(new midgard_query_property('packagetitle'), SORT_ASC);
                     break;
             }
         }
     }
     if (isset($args['id'])) {
         $constraints[] = new midgard_query_constraint(new midgard_query_property('packageid'), '=', new midgard_query_value($args['id']));
     }
     $qc = null;
     if (count($constraints) > 1) {
         $qc = new midgard_query_constraint_group('AND');
         foreach ($constraints as $constraint) {
             $qc->add_constraint($constraint);
         }
     } else {
         if (isset($constraints[0])) {
             $qc = $constraints[0];
         }
     }
     if (is_object($qc)) {
         $q->set_constraint($qc);
     }
     // 1st execute to get the total number of records
     // required by OCS
     $q->execute();
     $total = $q->get_results_count();
     if (array_key_exists('pagesize', $query) && strlen($query['pagesize'])) {
         $this->pagesize = $query['pagesize'];
     }
     $q->set_limit($this->pagesize);
     $page = 0;
     if (array_key_exists('page', $query) && strlen($query['page'])) {
         $page = $query['page'];
     }
     $offset = $page * $this->pagesize;
     $q->set_offset($offset);
     if ($offset > $total) {
         $offset = $total - $this->pagesize;
     }
     // 2nd execute to limit pagesize
     $q->execute();
     $ocs = new com_meego_ocs_OCSWriter();
     if ($total > 0) {
         $packageids = array();
         $localpackages = array();
         $packages = $q->list_objects();
         $done = array();
         foreach ($packages as $package) {
             if (in_array($package->packageid, $packageids)) {
                 // mimic distinct (Midgard Ratatoskr does not support it on SQL level)
                 --$total;
                 continue;
             }
             // set a special flag if the package is from a testing repository
             $package->testing = false;
             foreach ($this->mvc->configuration->top_projects as $top_project) {
                 if ($top_project['staging'] == $package->repoprojectname) {
                     $package->testing = true;
                 }
             }
             $package->comments_count = 0;
             // get number of comments
             $comments_qs = new midgard_query_storage('com_meego_comments_comment');
             $comments_q = new midgard_query_select($comments_qs);
             $comments_q->set_constraint(new midgard_query_constraint(new midgard_query_property('to'), '=', new midgard_query_value($package->packageguid)));
             $comments_q->execute();
             $package->comments_count = $comments_q->get_results_count();
             // get attachments
             $origpackage = new com_meego_package($package->packageguid);
             $package->attachments = $origpackage->list_attachments();
             unset($origpackage);
             // get the voters (who rated the package)
             $package->ratings = '';
             $ratings = com_meego_packages_controllers_application::prepare_ratings($package->packagename, true);
             if (count($ratings['ratings'])) {
                 foreach ($ratings['ratings'] as $rating) {
                     $ratings_[] = array('user' => $rating->user, 'version' => $rating->version, 'rate' => $rating->rating, 'date' => $rating->date);
                 }
                 $package->ratings = serialize($ratings_);
             }
             // some attributes returned only if an exact package is queried
             if (isset($args['id'])) {
                 // generate the URL of the package instance
                 $path = midgardmvc_core::get_instance()->dispatcher->generate_url('package_instance', array('package' => $package->packagename, 'version' => $package->packageversion, 'project' => $package->repoprojectname, 'repository' => $package->reponame, 'arch' => $package->repoarch), '/');
                 $package->commentsurl = com_meego_ocs_controllers_providers::generate_url($path);
                 // get the roles
                 $package->roles = null;
                 $roles = com_meego_packages_controllers_application::get_roles($package->packageguid);
                 if (count($roles)) {
                     $package->roles = serialize($roles);
                 }
                 // get the forms
                 $package->qa = null;
                 $forms = com_meego_packages_utils::get_stripped_forms_for_package($package);
                 if (count($forms)) {
                     $package->qa = serialize($forms);
                 }
             }
             if ($package->packagename != '') {
                 //get history
                 $args = array('os' => $package->repoos, 'version' => $package->repoosversion, 'ux' => $package->repoosux, 'packagename' => $package->packagename);
                 if (!isset($done[$package->packagename])) {
                     $packagehistory = com_meego_packages_controllers_application::get_lightweight_history($args);
                     if (count($packagehistory)) {
                         $package->history = serialize($packagehistory);
                         $done[$package->packagename] = $package->history;
                         //die;
                     }
                 } else {
                     // just copy the history
                     $package->history = $done[$package->packagename];
                 }
             }
             $localpackages[] = $package;
             $packageids[] = $package->packageid;
         }
         // write the xml content
         $ocs->writeMeta($total, $this->pagesize);
         $ocs->writeContent(array_values($localpackages));
         unset($done, $packageids, $localpackages);
     } else {
         // item not found
         $ocs->writeMeta($total, $this->pagesize, 'content not found', 'failed', 101);
         $ocs->writeEmptyData();
     }
     $ocs->endDocument();
     self::output_xml($ocs);
 }