%PDF- %PDF-
| Direktori : /home/vacivi36/public_bakcup/old/wp-content/plugins/loco-translate/old/lib/ |
| Current File : /home/vacivi36/public_bakcup/old/wp-content/plugins/loco-translate/old/lib/loco-packages.php |
<?php
/**
* Object representing a theme, plugin or domain within core code.
* Packages are identified uniquely by a type (e.g. "theme") and internal wordpress name, e.g. "loco-translate".
*/
abstract class LocoPackage {
/**
* Internal identifier, could be name, or path, or anything in future
* @var string
*/
private $handle;
/**
* Default text domain, e.g. "loco"
* @var string
*/
private $domain;
/**
* Default domain path relative to package root, e.g. "/languages"
* @var string
*/
protected $domainpath = '/languages';
/**
* Nice descriptive name, e.g. "Loco Translate"
* @var string
*/
private $name;
/**
* Locales with available translations
* @var array
*/
private $locales = array();
/**
* POT files, per domain
* @var array
*/
private $pot = array();
/**
* PO files, per domain, per locale
* @var array
*/
private $po = array();
/**
* Paths under which there may be source code in any of our domains
* @var array
*/
private $src = array();
/**
* Directories last modification times, used for cache invalidation
* @var array
*/
private $dirs = array();
/**
* @var int
*/
private $mtime = 0;
/**
* number of PO or POT files present
* @var int
*/
private $nfiles = 0;
/**
* Cached meta data
* @var array
*/
private $_meta;
/**
* Get package subclass type
* @return string theme, plugin or core
*/
abstract public function get_type();
/**
* Get original data about package stored in WordPress
*/
abstract public function get_original( $header );
/**
* Get primary file containing package headers
*/
abstract public function get_default_file();
/**
* Construct package from name, root and domain
*/
protected function __construct( $name_or_path, $domain, $name, $dpath = '' ){
$this->handle = $name_or_path;
$this->domain = $domain;
$this->name = $name or $this->name = $domain;
if( $dpath ){
$this->domainpath = '/'.trim($dpath,'/');
}
}
/**
* Get translatable header tags
*/
public function get_headers(){
return array();
}
/**
* Get default system languages directory
*/
public function global_lang_dir(){
return WP_LANG_DIR;
}
/**
* Test if provided path is under global lang dir
*/
public function is_global_path($path){
return 0 === strpos( $path, $this->global_lang_dir() );
}
/**
* Test if package has a writable global lang dir
*/
public function is_global_writable(){
$dir = $this->global_lang_dir();
return $dir && is_dir($dir) && is_writable( $dir );
}
/**
* Get identifying pair of arguments for fetching this object
* @return array
*/
public function get_query(){
return array (
'name' => $this->handle,
'type' => $this->get_type(),
);
}
/**
* Get package handle used for retreiving theme or plugin via wordpress functions
*/
public function get_handle(){
return $this->handle;
}
/**
* Get descriptive package name
*/
public function get_name(){
return $this->name;
}
/**
* Get all text domains with PO or POT files.
*/
private function get_domains(){
return array_unique( array_merge( array_keys($this->pot), array_keys($this->po) ) );
}
/**
* Get default text domain
*/
public function get_domain(){
if( ! $this->domain ){
$this->domain = $this->handle;
}
if( $this->domain === $this->handle ){
// if text domain defaulted and existing files disagree, try to correct primary domain
$candidates = $this->get_domains();
if( $candidates && ! in_array( $this->domain, $candidates, true ) ){
$this->domain = $candidates[0];
}
}
return $this->domain;
}
/**
* Get time most recent PO/POT file was updated
*/
public function get_modified(){
return $this->mtime;
}
/**
* Add PO or POT file and set modified state
*/
private function add_file( $path ){
if( filesize($path) ){
$this->mtime = max( $this->mtime, filemtime($path) );
$this->nfiles++;
$this->add_dir( dirname($path) );
return true;
}
}
/**
* Add directory and remember last modification time
*/
private function add_dir( $path ){
if( ! isset($this->dirs[$path]) ){
$this->dirs[$path] = filemtime($path);
}
}
/**
* find additional plugin PO under WP_LANG_DIR
*/
private function add_lang_dir( $langdir, $domain ){
$nfiles = $this->nfiles;
$files = LocoAdmin::find_grouped( $langdir, '/(?:-[^\.]+\.po|\.pot)$/' ) and
$this->add_po( $files, $domain );
// add $langdir if files added
if( $nfiles !== $this->nfiles ){
$this->add_dir( $langdir );
}
}
/**
* Add multiple locations from found PO and POT files
* @param array file paths collected with LocoAdmin::find_po
* @param string specific text domain to add
* @return LocoPackage
*/
private function add_po( array $files, $domain ){
if( isset($files['pot']) && is_array($files['pot']) ){
foreach( $files['pot'] as $path ){
$key = LocoAdmin::resolve_file_domain($path) or $key = $this->get_domain();
if( ( ! $domain || $key === $domain ) && $this->add_file($path) ){
$this->pot[$key] = $path;
}
}
}
if( isset($files['po']) && is_array($files['po']) ){
foreach( $files['po'] as $path ){
// catch namings like "default.po", "en.po" etc..
$name = basename($path);
if( false === strpos($name,'-') ){
// PO file has no locale suffix, we might need to use this as a POT if there is none
if( 'default' === $domain ){
$key = 'default'; // <- core
}
else {
$key = $this->get_domain();
if( ! isset($this->pot[$key]) ){
$this->pot[$key] = $path;
continue;
}
}
}
else {
$key = LocoAdmin::resolve_file_domain($path) or $key = $this->get_domain();
}
if( ! $domain || $key !== $domain ){
continue;
}
$locale = LocoAdmin::resolve_file_locale($path);
$code = $locale->get_code() or $code = 'xx_XX';
if( $this->add_file($path) ){
$this->po[ $key ][ $code ] = $path;
}
}
}
return $this;
}
/**
* Add any MO files for which PO files are missing
*/
private function add_mo( array $files, $domain = '' ){
foreach( $files as $mo_path ){
$domain or $domain = LocoAdmin::resolve_file_domain($mo_path) or $domain = $this->get_domain();
$locale = LocoAdmin::resolve_file_locale($mo_path);
$code = $locale->get_code() or $code = 'xx_XX';
if( isset($this->po[$domain][$code]) ){
// PO matched, ignore this MO
// @todo better matching as PO may not be in same location as MO
continue;
}
// add MO in place of PO, but only if locale code is valid
if( 'xx_XX' !== $code ){
$this->add_file($mo_path) and $this->po[$domain][$code] = $mo_path;
}
}
}
/**
* Add a location under which there may be PHP source files for one or more of our domains
* @return LocoPackage
*/
private function add_source( $path ){
$this->src[] = $path;
return $this;
}
/**
* Get most likely intended language folder
*/
public function lang_dir( $domain = '', $skip_global = false ){
$dirs = array();
// check location of POT in domain
foreach( $this->pot as $d => $path ){
if( ! $domain || $d === $domain ){
if( $skip_global && $this->is_global_path($path) ){
continue;
}
$path = dirname($path);
if( is_writable($path) ){
return $path;
}
$dirs[] = $path;
}
}
// check location of all PO files in domain
foreach( $this->po as $d => $paths ){
if( ! $domain || $d === $domain ){
foreach( $paths as $path ){
if( $skip_global && $this->is_global_path($path) ){
continue;
}
$path = dirname($path);
if( is_writable($path) ){
return $path;
}
$dirs[] = $path;
}
}
}
// check languages subfolder of all source file locations
foreach( $this->src as $path ){
if( $skip_global && $this->is_global_path($path) ){
continue;
}
$pref = $path.$this->domainpath;
if( is_writable($pref) ){
return $pref;
}
if( is_writable($path) ){
return $path;
}
if( is_dir($pref) ){
$dirs[] = $pref;
}
else {
$dirs[] = $path;
}
}
// check global languages location
if( ! $skip_global ){
$path = $this->global_lang_dir();
if( is_writable($path) ){
return $path;
}
$dirs[] = $path;
}
// failed to get writable directory, so we'll just return the highest priority
return array_shift( $dirs );
}
/**
* Build name of PO file for given or default domain
*/
public function create_po_path( LocoLocale $locale, $domain = '', $force_global = null ){
if( ! $domain ){
$domain = $this->get_domain();
}
// get best directory
if( is_null($force_global) ){
$dir = $this->lang_dir( $domain );
$force_global = $this->is_global_path( $dir );
}
// else use global directory by force
else if( $force_global ){
$dir = $this->global_lang_dir();
}
// else use best, but skipping global directory
else {
$dir = $this->lang_dir( $domain, true );
}
$name = $locale->get_code().'.po';
// core default package has no file prefix
$type = $this->get_type();
if( 'core' === $type && 'default' === $domain ){
$prefix = '';
}
// only prefix with text domain for plugins and files in global lang directory
else if( 'plugin' === $type || $force_global ){
$prefix = $domain.'-';
}
else {
$prefix = '';
}
// if PO files exist, copy their naming format and use location if writable
if( is_null($force_global) && ! empty($this->po[$domain]) ){
foreach( $this->po[$domain] as $code => $path ){
$info = pathinfo( $path );
$prefix = str_replace( $code.'.'.$info['extension'], '', $info['basename'] );
if( is_writable($info['dirname']) ){
$dir = $info['dirname'];
break;
}
}
}
return $dir.'/'.$prefix.$name;
}
/**
* Get root of package
*/
public function get_root(){
foreach( $this->src as $path ){
return $path;
}
return WP_LANG_DIR;
}
/**
* Get all PO an POT files
*/
public function get_gettext_files(){
$files = array();
foreach( $this->pot as $domain => $path ){
$files[] = $path;
}
foreach( $this->po as $domain => $paths ){
foreach( $paths as $path ){
$files[] = $path;
}
}
return $files;
}
/**
* Check PO/POT paths are writable.
* Called when generating root list view for simple error indicators.
*/
public function check_permissions(){
$dirs = array();
foreach( $this->pot as $path ){
$dirs[ dirname($path) ] = 1;
if( ! is_writable($path) ){
throw new Exception( __('Some files not writable','loco-translate') );
}
}
foreach( $this->po as $paths ){
foreach( $paths as $path ){
$dirs[ dirname($path) ] = 1;
if( ! is_writable($path) ){
throw new Exception( __('Some files not writable','loco-translate') );
}
if( ! file_exists( preg_replace('/\.po$/', '.mo', $path) ) ){
throw new Exception( __('Some files missing','loco-translate') );
}
}
}
$dir = $this->lang_dir();
if( ! is_writable($dir) ){
throw new Exception( sprintf( __('"%s" folder not writable','loco-translate'), basename($dir) ) );
}
foreach( array_keys($dirs) as $path ){
if( ! is_writable($path) ){
throw new Exception( sprintf( __('"%s" folder not writable','loco-translate'), basename($dir) ) );
}
}
}
/**
* Get file permission for every important file path in package
*/
public function get_permission_errors(){
$dirs = array();
// add common directories
$base = $this->get_root();
$dirs[ $base ] = 1;
$dirs[ $base.$this->domainpath ] = 1;
$dirs[ $this->lang_dir() ] = 1;
$dirs[ $this->global_lang_dir() ] = 1;
// add and check files, collecting additional directories along the way
$paths = array();
foreach( $this->pot as $path ){
$dirs[ dirname($path) ] = 1;
$paths[$path] = is_writable($path) ? '' : __('POT file not writable','loco-translate');
}
foreach( $this->po as $pos ){
foreach( $pos as $path ){
$dirs[ dirname($path) ] = 1;
$paths[$path] = is_writable($path) ? '' : __('PO file not writable','loco-translate');
$path = preg_replace('/\.po$/', '.mo', $path );
$paths[$path] = file_exists($path) ? ( is_writeable($path) ? '' : __('MO file not writable','loco-translate') ) : __('MO file not found','loco-translate');
}
}
// run directory checks and sort final list alphabetically
foreach( array_keys($dirs) as $dir ){
$paths[$dir] = is_writable($dir) ? '' : ( is_dir($dir) ? __('Folder not writable','loco-translate') : __('Folder not found','loco-translate') );
}
ksort( $paths );
return $paths;
}
/**
* Get package errors, or things that may cause problems displaying translations
*/
public function get_author_warnings(){
$warn = array();
$type = $this->get_type();
if( 'core' !== $type ){
$camelType = strtoupper($type{0}).substr($type,1);
// check package declares Text Domain
$domain = $this->get_original('TextDomain');
if( ! $domain ){
$domain = $this->get_domain();
$warn[] = sprintf(__('%s does not declare a "Text Domain"','loco-translate'),$camelType).' .. '.sprintf(__('Loco has guessed "%s"','loco-translate'), $domain );
}
// check package declares "Domain Path"
$path = $this->get_original('Domain Path');
if( ! $domain ){
$warn[] = sprintf(__('%s does not declare a "Domain Path"','loco-translate'),$camelType).' .. '.sprintf(__('Loco has guessed "%s"','loco-translate'), $this->domainpath );
}
// check POT exists and looks correct
$path = $this->get_pot($domain);
if( ! $path ){
$warn[] = sprintf( __('%s has no POT file. Create one at "%s/%s.pot" if you need one.','loco-translate'), $camelType, $this->domainpath, $domain );
}
else if( $domain.'.pot' !== basename($path) ){
$warn[] = sprintf( __('%s has a strange POT file name (%s). A better name would be "%s.pot"','loco-translate'), $camelType, basename($path), $domain );
}
// TODO check references to other domains in xgettext
}
// Check if any locale codes are not an official WordPress languages
$meta = $this->meta();
foreach( $meta['po'] as $po_data ){
$wplang = $po_data['locale']->get_code() or $wplang = $po_data['locale']->get_name();
if( ! LocoLocale::is_valid_wordpress($wplang) ){
$warn[] = sprintf( __('%s is not an official WordPress language','loco-translate'), $wplang );
}
}
return $warn;
}
/**
* Fetch POT file for given, or default domain
* @return string
*/
public function get_pot( $domain = '' ){
if( ! $domain ){
$domain = $this->get_domain();
}
if( ! empty($this->pot[$domain]) ){
return $this->pot[$domain];
}
// no POT, but some authors may use PO files incorrectly as a template
if( isset($this->po[$domain]) ){
foreach( array('','xx_XX','en_US','en_GB','en_EN') as $try ){
if( isset($this->po[$domain][$try]) ){
$pot = $this->po[$domain][$try];
unset( $this->po[$domain][$try] );
return $this->pot[$domain] = $pot;
}
}
}
// no template candidate
return '';
}
/**
* Check if given path is one of the package's POT files
* @return string related text domain if valid POT, else false
*/
public function is_pot( $path ){
return array_search( $path, $this->pot, true );
}
/**
* Fetch PO paths indexed by locale for given, or default domain
* @return array
*/
public function get_po( $domain = '' ){
if( ! $domain ){
$domain = $this->get_domain();
}
return isset($this->po[$domain]) ? $this->po[$domain] : array();
}
/**
* Find all source files, currently only PHP
*/
public function get_source_files(){
$found = array();
foreach( $this->src as $dir ){
foreach( LocoAdmin::find_php($dir) as $path ){
$found[] = $path;
}
}
return $found;
}
/**
* Get all source root directories
*/
public function get_source_dirs( $relative_to = '' ){
if( ! $relative_to ){
return $this->src;
}
// calculate path from location of given file (which may not exist)
if( pathinfo($relative_to,PATHINFO_EXTENSION) ){
$relative_to = dirname($relative_to);
}
$dirs = array();
foreach( $this->src as $target_dir ){
$dirs[] = loco_relative_path( $relative_to, $target_dir );
}
return $dirs;
}
/**
* Test if package has any source directories
*/
public function has_source_dirs(){
return ! empty( $this->src );
}
/**
* Export meta data used by templates.
* @return array
*/
public function meta(){
if( ! is_array($this->_meta) ){
$pot = $po = array();
// get POT files for all domains, fixing incorrect PO usage
foreach( $this->get_domains() as $domain ){
$path = $this->get_pot( $domain ) and
$pot[] = compact('domain','path');
}
// get progress and locale for each PO file
foreach( $this->po as $domain => $locales ){
foreach( $locales as $code => $path ){
try {
unset($headers);
$export = LocoAdmin::parse_po_with_headers( $path, $headers );
$po[] = array (
'path' => $path,
'domain' => $domain,
'name' => trim( str_replace( array('.po','.mo',$domain), array('','',''), basename($path) ), '-_'),
'stats' => loco_po_stats( $export ),
'length' => count( $export ),
'locale' => loco_locale_resolve($code),
'projid' => trim( $headers->{'project-id-version'} ),
);
}
catch( Exception $Ex ){
continue;
}
}
}
$this->_meta = compact('po','pot') + array(
'name' => $this->get_name(),
'root' => $this->get_root(),
'domain' => $this->get_domain(),
);
}
return $this->_meta;
}
/**
* Clear this package from the cache. Called to invalidate when something updates
* @return LocoPackage
*/
public function uncache(){
$key = $this->get_type().'_'.$this->handle;
Loco::uncache( $key );
$this->_meta = null;
return $this;
}
/**
* Invalidate cache based on last modification of directories
* @return bool whether cache should be invalidated
*/
private function invalidate(){
foreach( $this->dirs as $path => $mtime ){
if( ! is_dir($path) || filemtime($path) !== $mtime ){
return true;
}
}
}
/**
* Construct package object from theme data
* @return LocoPackage
*/
private static function get_theme( $handle ){
$theme = wp_get_theme( $handle );
if( $theme && $theme->exists() ){
$name = $theme->get('Name');
$domain = $theme->get('TextDomain') or $domain = $handle;
// create theme package with text domain defaulting to template name
$package = new LocoThemePackage( $handle, $domain, $name, $theme->get('DomainPath') );
$root = $theme->get_theme_root().'/'.$handle;
$package->add_source( $root );
// add PO and POT under theme root
if( $pofiles = LocoAdmin::find_po($root) ){
$package->add_po( $pofiles, $domain );
}
// pick up any MO files that have missing PO
if( $mofiles = LocoAdmin::find_mo($root) ){
$package->add_mo( $mofiles, $domain );
}
// find additional theme PO under WP_LANG_DIR/themes unless a child theme
$package->add_lang_dir( WP_LANG_DIR.'/themes', $domain );
// child theme inherits parent, but keeps its own domain
if( $parent = $theme->get_template() ){
if( $parent !== $handle ){
$package->inherit( $parent );
}
}
// fall back to all POT matches if no exact domain match
if( ! $package->pot ){
unset( $pofiles['po'] );
$package->add_po( $pofiles, null );
}
return $package;
}
}
/**
* Construct package object from plugin array
* note that handle is file path for plugins in WordPress
*/
private static function get_plugin( $handle ){
$plugins = get_plugins();
if( isset($plugins[$handle]) && is_array($plugins[$handle]) ){
$plugin = $plugins[$handle];
$domain = $plugin['TextDomain'] or $domain = str_replace('/','-',dirname($handle));
if( '.' === $domain ){
// single-file plugin has no directory to take a domain from
$domain = substr( basename($handle),0,-4);
}
$package = new LocoPluginPackage( $handle, $domain, $plugin['Name'], $plugin['DomainPath'] );
// single-file plugins have no root, or anywhere to save POT file.
if( false !== strpos($handle,'/') ){
$root = WP_PLUGIN_DIR.'/'.dirname($handle);
$package->add_source( $root );
// add PO and POT under plugin root
if( $pofiles = LocoAdmin::find_po($root) ){
$package->add_po( $pofiles, $domain );
}
// pick up any MO files that have missing PO
if( $mofiles = LocoAdmin::find_mo($root) ){
$package->add_mo( $mofiles, $domain );
}
}
// find additional plugin PO under WP_LANG_DIR/plugin
$package->add_lang_dir( WP_LANG_DIR.'/plugins', $domain );
// fall back to all POT matches if no exact domain match
if( ! $package->pot && isset($pofiles) ){
unset( $pofiles['po'] );
$package->add_po( $pofiles, null );
}
return $package;
}
}
/**
* construct a core package object from name
* @return LocoPackage
*/
private static function get_core( $handle ){
static $grouped;
if( ! isset($grouped) ){
$grouped = array();
foreach( LocoAdmin::find_grouped( WP_LANG_DIR, '/\.pot?$/' ) as $ext => $files ){
foreach( $files as $path ){
$domain = LocoAdmin::resolve_file_domain( $path );
$grouped[ $domain ][ $ext ][] = $path;
}
}
}
$domain = $handle or $domain = 'default';
$package = new LocoCorePackage( $handle, $domain, '' );
if( isset($grouped[$handle]) ){
// add PO file and POT files for this component
$package->add_po( $grouped[$handle], $domain );
// get name from po file
$meta = $package->meta();
foreach( $meta['po'] as $pmeta ){
if( $pmeta['projid'] ){
$package->name = $pmeta['projid'];
}
}
// disable source directories as Core packages cannot be synced
$package->src = array();
}
return $package;
}
/**
* Get all core pseudo packages
*/
public static function get_core_packages(){
static $names = array( '', 'admin', 'admin-network', 'continents-cities', 'ms' );
$packages = array();
foreach( $names as $handle ){
$packages[$handle] = self::get( $handle, 'core' );
}
return $packages;
}
/**
* Get a package - from cache if possible
* @param string unique name or identifier known to WordPress
* @param string "core", "theme" or "plugin"
* @return LocoPackage
*/
public static function get( $handle, $type ){
$key = $type.'_'.$handle;
$package = Loco::cached($key);
if( $package instanceof LocoPackage ){
if( $package->invalidate() ){
$package = null;
}
}
if( ! $package instanceof LocoPackage ){
$getter = array( __CLASS__, 'get_'.$type );
$package = call_user_func( $getter, $handle );
if( $package ){
$package->meta();
Loco::cache( $key, $package );
}
}
return $package;
}
/**
* @internal
*/
private static function _sort_modified( LocoPackage $a, LocoPackage $b ){
$a = $a->get_modified();
$b = $b->get_modified();
if( $a > $b ){
return -1;
}
if( $b > $a ){
return 1;
}
return 0;
}
/**
* Sort packages according to most recently updated language files
*/
public static function sort_modified( array $packages ){
static $sorter = array( __CLASS__, '_sort_modified' );
usort( $packages, $sorter );
return $packages;
}
}
/**
* Extended package class for themes
*/
class LocoThemePackage extends LocoPackage {
private $parent;
public function global_lang_dir(){
return WP_LANG_DIR.'/themes';
}
protected function inherit( $template ){
$parent = wp_get_theme( $template );
if( $parent && $parent->exists() ){
$this->parent = $template;
}
}
protected function is_child(){
return ! empty($this->parent);
}
protected function get_parent(){
return $this->parent ? LocoPackage::get( $this->parent, 'theme' ) : null;
}
public function meta(){
$meta = parent::meta();
if( $parent = $this->get_parent() ){
$pmeta = $parent->meta();
$meta['parent'] = $parent->get_name();
// merge parent resources unless child has its own domain
if( $meta['domain'] === $pmeta['domain'] ){
$meta['po'] = array_merge( $meta['po'], $pmeta['po'] );
$meta['pot'] = array_merge( $meta['pot'], $pmeta['pot'] );
}
}
return $meta;
}
public function check_permissions(){
parent::check_permissions();
if( $parent = $this->get_parent() ){
$parent->check_permissions();
}
}
public function get_permission_errors(){
$paths = parent::get_permission_errors();
// check parent theme if exists
if( $parent = $this->get_parent() ){
// recurse if child theme uses same domain as parent
if( $this->get_domain() === $parent->get_domain() ){
$paths += $parent->get_permission_errors( true );
}
}
return $paths;
}
public function get_pot( $domain = '' ){
if( ( $parent = $this->get_parent() ) && ( $pot = $parent->get_pot($domain) ) ){
return $pot;
}
return parent::get_pot( $domain );
}
public function get_type(){
return 'theme';
}
public function get_original( $tag ){
$theme = wp_get_theme( $this->get_handle() );
return $theme->get( $tag );
}
public function get_headers(){
$headers = array();
$theme = wp_get_theme( $this->get_handle() );
foreach( array('Name','ThemeURI','Description','Author','AuthorURI') as $tag ){
$headers[$tag] = $theme->get($tag) or $headers[$tag] = '';
}
return $headers;
}
public function get_default_file(){
return $this->get_root().'/style.css';
}
}
/**
* Extended package class for plugins
*/
class LocoPluginPackage extends LocoPackage {
public function global_lang_dir(){
return WP_LANG_DIR.'/plugins';
}
public function get_type(){
return 'plugin';
}
public function get_original( $tag ){
$plugins = get_plugins();
$plugin = $plugins[ $this->get_handle() ];
return isset($plugin[$tag]) ? $plugin[$tag] : '';
}
public function get_headers(){
$headers = array();
$plugins = get_plugins();
$plugin = $plugins[ $this->get_handle() ];
foreach( array('Name','PluginURI','Description','Author','AuthorURI') as $tag ){
$headers[$tag] = isset($plugin[$tag]) ? $plugin[$tag] : '';
}
return $headers;
}
public function get_default_file(){
return WP_PLUGIN_DIR.'/'.$this->get_handle();
}
}
/**
* Extended package class for core pseudo packages
*/
class LocoCorePackage extends LocoPackage {
protected $domainpath = '';
public function get_type(){
return 'core';
}
public function get_original( $header ){
return null;
}
public function get_default_file(){
return null;
}
}