PageRenderTime 658ms CodeModel.GetById 263ms app.highlight 173ms RepoModel.GetById 216ms app.codeStats 1ms

/elgg_language_packs.php

https://bitbucket.org/moodsdesign-ondemand/elgg_language_packs
PHP | 423 lines | 318 code | 23 blank | 82 comment | 113 complexity | b63fb74615954c1dc4932d52d97f06e4 MD5 | raw file
  1<?php
  2/*
  3 * This file contains common methods for both the 
  4 * Elgg Language Packs plugin and the
  5 * GlotPress Elgg hack for ElggTranslate.com
  6 */
  7
  8define('ELGGLP_VERSION',			'1.0.0');
  9
 10define('ELGGLP_OK',					   -1);
 11define('ELGGLP_ERR_STRUCTURE',			1);
 12define('ELGGLP_ERR_VERSION',		    2);
 13
 14function elgglp_create_languagepack_meta($meta, $filters) {
 15    // copy filter options used here into local variables
 16    $dstdir = $filters['dst_dir'];
 17    // if there no meta info yet, create an empty array
 18    if ( !is_array($meta) ) $meta = array();
 19    // add Elgg version to metadata
 20    $meta['elgg_version'] = $filters['elgg_release'];
 21    // add plugin version to metadata
 22    $meta['languagepack_version'] = ELGGLP_VERSION;
 23    // json-encode the meta info
 24    $contents = json_encode($meta);
 25    // write to language pack meta file
 26    file_put_contents("$dstdir/languagepack.meta", $contents);
 27}
 28
 29function elgglp_create_languagemod_meta($meta, $filters) {
 30    // work out the destination folder
 31    $dstdir = $filters['dst_dir'];
 32    if ( $meta['unique'] == 'install' ) {
 33        $dstdir = "$dstdir/install";
 34    } else if ( $meta['unique'] != 'core' ) {
 35        $dstdir = "$dstdir/mod/$meta[unique]";
 36    }
 37    // create directory if necessary
 38    @mkdir("$dstdir/languages", 0777, true);
 39    // json-encode the meta info
 40    $contents = json_encode($meta);
 41    // write to language mod meta file
 42    file_put_contents("$dstdir/languages/languagemod.meta", $contents);
 43}
 44
 45function elgglp_check_language_pack($dir, &$elgg_version, &$languagepack_version, $check_meta = true) {
 46    // if anything goes wrong, we return false for both out params
 47    $elgg_version = false;
 48    $languagepack_version = false;
 49    // install directory exists and has languages/ directory?
 50    $install = file_exists("$dir/install/languages") && is_dir("$dir/install/languages");
 51    // root directory has languages/ directory?
 52    $core = file_exists("$dir/languages") && is_dir("$dir/languages");
 53    // mod directory exists?
 54    $mod = file_exists("$dir/mod") && is_dir("$dir/mod");
 55    // need to check for language pack meta?
 56    if ( $check_meta ) {
 57        // we are looking at a language pack proper
 58        $meta = file_exists("$dir/languagepack.meta") && is_file("$dir/languagepack.meta");
 59        if ( $meta ) {
 60            $meta = json_decode(file_get_contents("$dir/languagepack.meta"), true);
 61            $elgg_version = $meta['elgg_version'];
 62            $languagepack_version = $meta['languagepack_version'];
 63        }
 64    } else {
 65        // we must be looking at an Ellg product folder
 66        $meta = file_exists("$dir/version.php") && is_file("$dir/version.php");
 67        if ( $meta ) {
 68            include "$dir/version.php";
 69            $elgg_version = $release;
 70            $languagepack_version = ELGGLP_VERSION;
 71        }
 72    }
 73    // return result
 74    return $install && $core && $mod && $meta;
 75}
 76
 77function elgglp_read_languagemod_meta($src_dir) {
 78    $meta_name = "$src_dir/languages/languagemod.meta";
 79    if ( !file_exists($meta_name) ) return false;
 80    $meta_contents = file_get_contents($meta_name);
 81    $info = json_decode($meta_contents, true);
 82    $slug = basename($src_dir);
 83    if ( $info['unique'] == $slug ) {
 84        return $info;
 85    } else {
 86        return false;
 87    }
 88}
 89
 90function elgglp_read_plugin_manifest($src_dir) {
 91    if ( !file_exists("$src_dir/languages") ) return false;
 92    $manifest_name = "$src_dir/manifest.xml";
 93    if ( !file_exists($manifest_name) ) return false;
 94    $manifest_contents = file_get_contents($manifest_name);
 95    try {
 96        $manifest = new SimpleXMLElement($manifest_contents);
 97    } catch ( Exception $e ) {
 98        error_log("elgglp_read_manifest: $manifest_name not valid");
 99        return false;
100    }
101    $slug = basename($src_dir);
102    $info = array(
103        'name' => (string)$manifest->name,
104        'version' => (string)$manifest->version,
105        'description' => (string)$manifest->description,
106        'unique' => $slug,
107    );
108    return $info;
109}
110
111/**
112 * Creates a directory with a unique directory name.
113 *
114 * @param string|boolean $dir The directory under which the new directory should be created. If empty, the system temporary folder will be used
115 * @param string $prefix A prefix to prepended to the generated directory name. If empty, no prefix will be added
116 * @return string|boolean The name of the newly created directory, of false if a directory could not be created
117 */
118function elgglp_tempdir($dir = false, $prefix = '') {
119    if ( !$dir ) $dir = sys_get_temp_dir();
120    if ( ($tempfile = tempnam($dir, $prefix)) ) {
121        unlink($tempfile);
122        if ( mkdir($tempfile) ) {
123            return $tempfile;
124        }
125    }
126    return false;
127}
128
129function elgglp_copy_languagemod($meta, $srcdir, $filters) {
130    if ( @elgglp_copy_languages($meta, $srcdir, $filters) ) {
131        if ( $filters['needs_manifest'] ) {
132            @elgglp_create_languagemod_meta($meta, $filters);
133        }
134    }
135}
136
137function elgglp_copy_languages($meta, $srcdir, $filters) {
138    return elgglp_recurse_languages($meta, $srcdir, $filters, 'elgglp_copy_file');
139}
140
141function elgglp_delete_file($meta, $file, $lang, $filters) {
142    return unlink($file);
143}
144
145function elgglp_delete_languages($meta, $srcdir, $filters) {
146    return elgglp_recurse_languages($meta, $srcdir, $filters, 'elgglp_delete_file');
147}
148
149function elgglp_recurse_languages($meta, $srcdir, $filters, $callback) {
150    // copy filter options used here into local variables
151    $langs = @$filters['langs'];
152    $ignore_en = (bool)@$filters['ignore_en'];
153    $return = $filters['return_array'];
154    if ( $return || !$callback ) {
155        // initialise the array for the list of detected languages
156        $found = array();
157    } else {
158        // keep track of whether any file was copied from this folder
159        $found = false;
160    }
161    // get all the files that match an Elgg language file and iterate
162    $all_files = array_merge(glob("$srcdir/languages/??.php"), glob("$srcdir/languages/??[-_]??.php"));
163    foreach ( $all_files as $file ) {
164        // basic name of the file is the locale name
165        $lang = basename($file, '.php');
166        // should the current locale be filtered out?
167        if ( $langs && !in_array($lang, $langs) ) {
168            continue;
169        }
170        // should we ignore this if it is the original English file?
171        if ( $ignore_en && $lang == 'en' ) {
172            continue;
173        }
174        if ( $return || !$callback ) {
175            $found[$lang] = $file;
176        } else {
177            if ( @call_user_func($callback, $meta, $file, $lang, $filters) ) {
178                $found = true;
179            }
180        }
181    }
182    // all done in this folder
183    return $found;
184}
185
186function elgglp_copy_file($meta, $file, $lang, $filters) {
187    // copy filter options used here into local variables
188    $dstdir = $filters['dst_dir'];
189    $needs_meta = $filters['$needs_meta'];
190    // work out the destination folder
191    if ( $meta['unique'] == 'install' ) {
192        $dstdir = "$dstdir/install";
193    } else if ( $meta['unique'] != 'core' ) {
194        $dstdir = "$dstdir/mod/$meta[unique]";
195    }
196    // if plugin directory is not there, skip this if importing
197    if ( $needs_meta && !file_exists($dstdir) ) {
198        return false;
199    }
200    // if there is not a JavaScript file for this language, create it if importing
201    $jsfile = "$dstdir/views/default/js/languages/$lang.php";
202    if ( $needs_meta && !file_exists($jsfile) ) {
203        //@mkdir("$dstdir/views/default/js/languages", 0777, true);
204        $jscode = "<?php
205echo elgg_view('js/languages', array('language' => '$lang'));
206";
207        file_put_contents($jsfile, $jscode);
208    }
209    // copy filter options used here into local variables
210    $overwrite = (bool)@$filters['overwrite'];
211    // the destination file we should write to
212    $to_file = "$dstdir/languages/" . basename($file);
213    // if it exists already, can we overwrite it?
214    if ( !$overwrite && file_exists($to_file) ) {
215        return false;
216    }
217    // create the folder if it does not exist
218    if ( !file_exists("$dstdir/languages") ) {
219        @mkdir("$dstdir/languages", 0777, true);
220    }
221    // copy the file
222    if ( @copy($file, $to_file) ) {
223        // signal at least one file was copied
224        return true;
225    }
226}
227
228/**
229 * Zip an entire folder into a given file
230 *
231 * @param type $source the folder to zip up
232 * @param type $destination the filename of the zip file to create
233 * @return boolean true if the zip file was successfully create, false otherwise
234 */
235function elgglp_zip_folder($source, $destination) {
236    $zip = new ZipArchive();
237    if ( !$zip->open($destination, ZIPARCHIVE::CREATE) ) {
238        return false;
239    }
240
241    $source = str_replace('\\', '/', realpath($source));
242
243    if ( is_dir($source) === true )
244    {
245        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
246
247        foreach ( $files as $file )
248        {
249            $file = str_replace('\\', '/', $file);
250
251            // Ignore all hidden files and folders
252            if ( $file[0] == '.' )
253                continue;
254
255            $file = realpath($file);
256
257            if ( is_dir($file) === true )
258            {
259                $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
260            }
261            else if (is_file($file) === true)
262            {
263                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
264            }
265        }
266    }
267    else if (is_file($source) === true)
268    {
269        $zip->addFromString(basename($source), file_get_contents($source));
270    }
271
272    return $zip->close();
273}
274
275/**
276 * Completely and recursively delete a directory
277 *
278 * @param type $dirname the directory to remove
279 * @return boolean true if the directory was removed successfully, false otherwise
280 */
281function elgglp_deltree($dirname) {
282    // Sanity check
283    if ( !file_exists($dirname) ) { return false; }
284    // Simple delete if it is an ordinary file or link
285    if ( is_file($dirname) || is_link($dirname) ) {
286        return unlink($dirname);
287    }
288    // Loop through each entry in the folder
289    $dir = dir($dirname);
290    while ( false !== ($entry = $dir->read()) ) {
291        // Skip special pointers
292        if ( $entry == '.' || $entry == '..' ) {
293            continue;
294        }
295        // Recurse - if $entry is a file, this method will delete it and return
296        elgglp_deltree("$dirname/$entry");
297    }
298    // Clean up
299    $dir->close();
300    return rmdir($dirname);
301}
302
303function elgglp_recurse_language_pack($srcdir, $filters, $callback) {
304    // remove possible trailing slash from source directory
305    $srcdir = rtrim($srcdir, '/');
306    // remove possible trailing slash from target directory if it exists
307    if ( $filters['dst_dir'] ) {
308        $filters['dst_dir'] = rtrim($filters['dst_dir'], '/');
309    }
310    // copy filter options used here into local variables
311    $projs = $filters['projs'];
312    $needs_meta = $filters['needs_meta'];
313    $needs_manifest = $filters['needs_manifest'];
314    $return = $filters['return_array'];
315    $releases = (array)$filters['elgg_release'];
316    // check whether it is a valid Elgg Language Pack
317    $elgg_version = null;
318    $languagepack_version = null;
319    if ( !elgglp_check_language_pack($srcdir, $elgg_version, $languagepack_version, $needs_meta) ) {
320        return ELGGLP_ERR_STRUCTURE;
321    }
322    // is the language pack for the right Language Pack or Elgg version?
323    if ( !in_array($elgg_version, $releases) || ELGGLP_VERSION != $languagepack_version ) {
324        return ELGGLP_ERR_VERSION;
325    }
326    // set the detected version into the filters data
327    $filters['elgg_release'] = $elgg_version;
328    // should return list of language mods?
329    if ( $return ) {
330        $allmods = array();
331    }
332    // unless filtered, process the core language files
333    if ( empty($projs) || in_array('core', $projs) ) {
334        $meta = array(
335            'version' => $elgg_version,
336            'name' => 'Elgg Core',
337            'description' => 'The core elements of the social networking engine',
338            'unique' => 'core',
339        );
340        if ( $return ) {
341            if ( ($alllangs = elgglp_recurse_languages($meta, $srcdir, $filters, null)) ) {
342                $meta['langs'] = $alllangs;
343                $allmods[] = $meta;
344            }
345        } else if ( $callback ) {
346            @call_user_func($callback, $meta, $srcdir, $filters);
347        }
348    }
349    // unless filtered, process the install language files
350    if ( empty($projs) || in_array('install', $projs) ) {
351        $meta = array(
352            'version' => $elgg_version,
353            'name' => 'Elgg Install',
354            'description' => 'Install wizard for setting up and configuring a new Elgg instance, or upgrading an existing one',
355            'unique' => 'install',
356        );
357        if ( $return ) {
358            if ( ($alllangs = elgglp_recurse_languages($meta, "$srcdir/install", $filters, null)) ) {
359                $meta['langs'] = $alllangs;
360                $allmods[] = $meta;
361            }
362        } else if ( $callback ) {
363            @call_user_func($callback, $meta, "$srcdir/install", $filters);
364        }
365    }
366    // loop through all directories in mod/ looking for language mods
367    $dir = dir("$srcdir/mod");
368    while ( false !== ($entry = $dir->read()) ) {
369        $curdir = "$srcdir/mod/$entry";
370        if ( $entry[0] != '.' && is_dir($curdir) ) {
371            // skip if filtered out by user
372            if ( !empty($projs) && !in_array($entry, $projs) ) continue;
373            // check whether at least one of meta and manifest files exist
374            $meta_file = "$curdir/languages/languagemod.meta";
375            $manifest_file = "$curdir/manifest.xml";
376            $meta_exists = file_exists($meta_file);
377            $manifest_exists = file_exists($manifest_file);
378            if ( !$meta_exists && !$manifest_exists ) continue;
379            // try and create meta data from either
380            if ( (!$needs_meta || $meta_exists) && (!$needs_manifest || $manifest_exists) ) {
381                if ( !$meta_exists || !is_array($meta = elgglp_read_languagemod_meta($curdir)) ) {
382                    if ( !$manifest_exists || !is_array($meta = elgglp_read_plugin_manifest($curdir)) ) {
383                        continue;
384                    }
385                }
386                if ( $return ) {
387                    if ( ($alllangs = elgglp_recurse_languages($meta, "$srcdir/mod/$entry", $filters, null)) ) {
388                        $meta['langs'] = $alllangs;
389                        $allmods[] = $meta;
390                    }
391                } else if ( $callback ) {
392                    @call_user_func($callback, $meta, "$srcdir/mod/$entry", $filters);
393                }
394            }
395        }
396    }
397    $dir->close();
398    if ( $return ) {
399        return $allmods;
400    } else {
401        return ELGGLP_OK;
402    }
403}
404
405function elgglp_core_plugins($version = null) {
406    static $cores = null;
407    if ( !$cores ) {
408        $cores = array(
409            '1.8.8' => array(
410                'core', 'install', // these ones are not real Elgg plugins
411                'blog', 'bookmarks', 'categories', 'custom_index', 'dashboard', 'developers', 'diagnostics', 'embed',
412                'externalpages', 'file', 'garbagecollector', 'groups', 'invitefriends', 'likes', 'logbrowser', 'logrotate',
413                'members', 'messageboard', 'messages', 'notifications', 'oauth_api', 'pages', 'profile', 'reportedcontent',
414                'search', 'tagcloud', 'thewire', 'tinymce', 'twitter', 'twitter_api', 'uservalidationbyemail', 'zaudio'
415            )
416        );
417    }
418    if ( $version ) {
419        return $cores[$version];
420    } else {
421        return $cores;
422    }
423}