inited=false; $this->site_path=getenv('DOCUMENT_ROOT'); wp_register_sidebar_widget('fdroid_latest', 'FDroid Latest', 'widget_fdroidlatest'); } // Register additional query variables. (Handler for the 'query_vars' filter) function queryvars($qvars) { $qvars[]='fdfilter'; $qvars[]='fdcategory'; $qvars[]='fdid'; $qvars[]='fdpage'; $qvars[]='fdstyle'; return $qvars; } // Lazy initialise. All non-trivial members should call this before doing anything else. function lazyinit() { if(!$this->inited) { load_plugin_textdomain($this->textdom, PLUGINDIR.'/'.dirname(plugin_basename(__FILE__)), dirname(plugin_basename(__FILE__))); $this->inited=true; } } // Gets a required query parameter by name. function getrequiredparam($name) { global $wp_query; if(!isset($wp_query->query_vars[$name])) wp_die("Missing parameter ".$name,"Error"); return $wp_query->query_vars[$name]; } // Handler for the 'fdroidrepo' shortcode. // $attribs - shortcode attributes // $content - optional content enclosed between the starting and // ending shortcode // Returns the generated content. function do_shortcode($attribs,$content=null) { global $wp_query,$wp_rewrite; $this->lazyinit(); // Init local query vars foreach($this->queryvars(array()) as $qv) { if(array_key_exists($qv,$wp_query->query_vars)) { $query_vars[$qv] = $wp_query->query_vars[$qv]; } else { $query_vars[$qv] = null; } } // Santiy check query vars if(!isset($query_vars['fdpage']) || !is_numeric($query_vars['fdpage']) || $query_vars['fdpage'] <= 0) { $query_vars['fdpage'] = 1; } $out = ''; if(isset($attribs['search']) && $query_vars['fdfilter']===null) { $query_vars['fdfilter'] = ''; } if($query_vars['fdcategory'] == 'All categories') { unset($query_vars['fdcategory']); } if($query_vars['fdid']!==null) { $out.=$this->get_app($query_vars); } else { if($query_vars['fdfilter'] !== null) { $out.='
'."\n"; } $out.=$this->get_apps($query_vars); } return $out; } // Get a URL for a full description of a license, as given by one of our // pre-defined license abbreviations. This is a temporary function, as this // needs to be data-driven so the same information can be used by the client, // the web site and the documentation. function getlicenseurl($license) { switch($license) { case 'MIT': return 'http://www.gnu.org/licenses/license-list.html#X11License'; case 'NewBSD': return 'http://www.gnu.org/licenses/license-list.html#ModifiedBSD'; case 'BSD': return 'http://www.gnu.org/licenses/license-list.html#OriginalBSD'; case 'GPLv3': case 'GPLv3+': return 'http://www.gnu.org/licenses/license-list.html#GNUGPL'; case 'GPLv2': case 'GPLv2+': return 'http://www.gnu.org/licenses/license-list.html#GPLv2'; case 'LGPL': return 'http://www.gnu.org/licenses/license-list.html#LGPL'; case 'Apache2': return 'http://www.gnu.org/licenses/license-list.html#apache2'; default: return null; } } function get_app($query_vars) { global $permissions_data; $permissions_object = new AndroidPermissions($this->site_path.'/wp-content/plugins/wp-fdroid/AndroidManifest.xml', $this->site_path.'/wp-content/plugins/wp-fdroid/strings.xml', sys_get_temp_dir().'/android-permissions.cache'); $permissions_data = $permissions_object->get_permissions_array(); // Get app data $xml = simplexml_load_file($this->site_path.'/repo/index.xml'); foreach($xml->children() as $app) { $attrs=$app->attributes(); if($attrs['id']==$query_vars['fdid']) { $apks=array();; foreach($app->children() as $el) { switch($el->getName()) { case "name": $name=$el; break; case "icon": $icon=$el; break; case "summary": $summary=$el; break; case "desc": $desc=$el; break; case "license": $license=$el; break; case "source": $source=$el; break; case "tracker": $issues=$el; break; case "donate": $donate=$el; break; case "web": $web=$el; break; case "antifeatures"; $antifeatures=$el; break; case "requirements"; $requirements=$el; break; case "package": $thisapk=array(); foreach($el->children() as $pel) { switch($pel->getName()) { case "version": $thisapk['version']=$pel; break; case "vercode": $thisapk['vercode']=$pel; break; case "apkname": $thisapk['apkname']=$pel; break; case "srcname": $thisapk['srcname']=$pel; break; case "hash": $thisapk['hash']=$pel; break; case "size": $thisapk['size']=$pel; break; case "sdkver": $thisapk['sdkver']=$pel; break; case "permissions": $thisapk['permissions']=$pel; break; } } $apks[]=$thisapk; } } // Generate app diff data foreach(array_reverse($apks, true) as $key=>$apk) { if(isset($previous)) { // Apk size $apks[$key]['diff']['size'] = $apk['size']-$previous['size']; } // Permissions $permissions = explode(',',$apk['permissions']); $permissionsPrevious = isset($previous['permissions'])?explode(',',$previous['permissions']):array(); $apks[$key]['diff']['permissions']['added'] = array_diff($permissions, $permissionsPrevious); $apks[$key]['diff']['permissions']['removed'] = array_diff($permissionsPrevious, $permissions); $previous = $apk; } // Output app information $out=''.$name."";
$out.="
".$summary."
'.$antifeatureDesctiption['name'].'
';
$out.=$antifeatureDesctiption['description'].'
";
$licenseurl=$this->getlicenseurl($license);
$out.="License: ";
if($licenseurl)
$out.='';
$out.=$license;
if($licenseurl)
$out.='';
if(isset($requirements)) {
$out.='
Additional requirements: '.$requirements;
}
$out.="
";
if(strlen($web)>0)
$out.='Website: '.$web.'
';
if(strlen($issues)>0)
$out.='Issue Tracker: '.$issues.'
';
if(strlen($source)>0)
$out.='Source Code: '.$source.'
';
if($donate && strlen($donate)>0)
$out.='Donate: '.$donate.'
';
$out.="
For full details and additional technical information, see "; $out.="this application's page on the F-Droid wiki.
"; $out.=''; $out.="Although APK downloads are available below to give "; $out.="you the choice, you should be aware that by installing that way you "; $out.="will not receive update notifications, and it's a less secure way "; $out.="to download. "; $out.="We recommend that you install the F-Droid client and use that.
"; $i=0; foreach($apks as $apk) { $first = $i+1==count($apks); $out.="Version ".$apk['version']."
";
// Is this source or binary?
$srcbuild = isset($apk['srcname']) && file_exists($this->site_path.'/repo/'.$apk['srcname']);
$out.="
This version is built and signed by "; if($srcbuild) { $out.="F-Droid, and guaranteed to correspond to the source tarball below.
"; } else { $out.="the original developer."; } $out.='download apk '; $out.=$this->human_readable_size($apk['size']); $diffSize = $apk['diff']['size']; if(abs($diffSize) > 500) { $out.=' ('; $out.=$diffSize>0?'+':''; $out.=$this->human_readable_size($diffSize, 1).')'; } if($srcbuild) { $out.='Application not found
"; } private function get_permission_list_string($permissions, $permissions_data, &$summary) { $out=''; usort($permissions, "permissions_cmp"); $permission_group_last = ''; foreach($permissions as $permission) { $permission_group = $permissions_data['permission'][$permission]['permissionGroup']; if($permission_group != $permission_group_last) { $permission_group_label = $permissions_data['permission-group'][$permission_group]['label']; if($permission_group_label=='') $permission_group_label = 'Extra/Custom'; $out.=''.strtoupper($permission_group_label).''.$permission.'
]'; $out.='
No matches
'; } return $out; } function makeformdata($query_vars) { $out=''; $out.=''; foreach($query_vars as $name => $value) { if($value !== null && $name != 'fdfilter' && !($name == 'fdpage' && (int)$value ==1)) $out.=''; } return $out; } function show_apps($xml,$query_vars,&$numpages) { $skipped=0; $got=0; $total=0; if($query_vars['fdstyle']=='grid') { $outputter = new FDOutGrid(); } else { $outputter = new FDOutList(); } $out = ""; $out.=$outputter->outputStart(); foreach($xml->children() as $app) { if($app->getName() == 'repo') continue; $appinfo['attrs']=$app->attributes(); $appinfo['id']=$appinfo['attrs']['id']; foreach($app->children() as $el) { switch($el->getName()) { case "name": $appinfo['name']=$el; break; case "icon": $appinfo['icon']=$el; break; case "summary": $appinfo['summary']=$el; break; case "desc": $appinfo['description']=$el; break; case "license": $appinfo['license']=$el; break; case "category": $appinfo['category']=$el; break; } } if(($query_vars['fdfilter']===null || $query_vars['fdfilter']!='' && (stristr($appinfo['name'],$query_vars['fdfilter']) || stristr($appinfo['summary'],$query_vars['fdfilter']) || stristr($appinfo['description'],$query_vars['fdfilter']))) && (!isset($query_vars['fdcategory']) || $query_vars['fdcategory'] && $query_vars['fdcategory']==$appinfo['category'])) { if($skipped<($query_vars['fdpage']-1)*$outputter->perpage) { $skipped++; } else if($got<$outputter->perpage) { $out.=$outputter->outputEntry($query_vars, $appinfo); $got++; } $total++; } } $out.=$outputter->outputEnd(); $numpages = ceil((float)$total/$outputter->perpage); return $out; } } // Class to output app entries in a detailed list format class FDOutList { var $perpage=30; function FDOutList() { } function outputStart() { return ''; } function outputEntry($query_vars, $appinfo) { $out=""; $out.='Details...
'; $out.="'.$appinfo['name']."";
$out.="
".$appinfo['summary']."
';
$out.=' '; $out.=' ';
$out.='';
$out.=' ";
$out.='';
$out.="'; $out.=$appinfo['name'].' '; $out.=''; $out.=" | \n";
$this->itemCount++;
return $out;
}
function outputEnd() {
return '