fix #7737 - support for powerpoint files in translations
authorAlan <alan@roojs.com>
Thu, 3 Aug 2023 04:31:14 +0000 (12:31 +0800)
committerAlan <alan@roojs.com>
Thu, 3 Aug 2023 04:31:14 +0000 (12:31 +0800)
Pman.Tab.CmsTranslateTemplates.bjs
UpdateBjsTemplates.php

index 10e06b5..eb8f09c 100644 (file)
  "modOrder" : "800",
  "name" : "Pman.Tab.CmsTranslateTemplates",
  "parent" : "Pman.Tab.Cms",
- "path" : "/home/alan/gitlive/Pman.Cms/Pman.Tab.CmsTranslateTemplates.bjs",
+ "path" : "/home/leon/gitlive/Pman.Cms/Pman.Tab.CmsTranslateTemplates.bjs",
  "permname" : "",
  "strings" : {
   "03c2e7e41ffc181a4e84080b4710e81e" : "New",
index 3a8cd4e..f7e8ffa 100644 (file)
@@ -43,8 +43,12 @@ class Pman_Cms_UpdateBjsTemplates extends Pman_Admin_UpdateBjsTemplates
     
     function updateData()
     {   
+         
+        if (empty($ff->Pman_Cms)) {
+            $this->jerr("config[Pman_Cms] is not set");
+        }
+        $this->scanPowerpoint();
         $this->scanFiles();
-        
         $this->scanTables();
         $this->syncLanguage();
         
@@ -57,9 +61,7 @@ class Pman_Cms_UpdateBjsTemplates extends Pman_Admin_UpdateBjsTemplates
     {
         $ff = HTML_FlexyFramework::get();
         
-        if (empty($ff->Pman_Cms)) {
-            $this->jerr("config[Pman_Cms] is not set");
-        }
+        
         
        
         foreach(explode(',', $ff->Pman_Cms['project_name']) as $base) {
@@ -187,30 +189,142 @@ class Pman_Cms_UpdateBjsTemplates extends Pman_Admin_UpdateBjsTemplates
         }
         
     }
+
+    function scanPowerpoint()
+    {
+        $ff = HTML_FlexyFramework::get();
+        
+         
+        
+        if(!isset($ff->Pman_Cms['powerpoint'])) {
+            return;
+        }
+        foreach($ff->Pman_Cms['powerpoint'] as $base => $dir) {
+            $strings = $this->scanPowerpointText($dir);
+
+            foreach($strings as $slide => $words) {
+                $ct = DB_DataObject::factory('cms_template');
+                $temp = $ct->syncPowerpointXMLText(array(
+                    'template' => $slide . '.xml',
+                    'template_dir' => $dir . '/ppt/slides',
+                    'base' => $base,
+                    'words' => $words
+                ));
+
+                if($temp) {
+                    $ids[] = $temp->id;
+                }
+            }
+
+            $del = DB_DataObject::factory('cms_template');
+            $del->whereAddIn('!id', $ids, 'int');
+            $del->view_name = $base;
+            $del->filetype = 'xml';
+            $delids = $del->fetchAll('id');
+            if ($delids) {
+                DB_DataObject::factory('core_template')->query(
+                    'update cms_template set is_deleted =  1 where id in('. implode(',', $delids). ')'
+                );
+            }
+
+        }
+        
+    }
+
+    /**
+     * scan translatable text items in a powerpoint folder
+     * translatable text items should have names starting with 'tr-'
+     * 
+     * @param String $path path of the powerpoint folder to be scanned
+     * @return Array $strings 2d array containing translatable strings grouped by slide name
+     * 
+     */
+    static function scanPowerpointText($path)
+    {
+
+        // get id of slides from presentation xml
+        $slideRids = array();
+
+        $xmlString = file_get_contents($path . '/ppt/presentation.xml');
+        $sxe = new SimpleXMLElement($xmlString);
+        $slides = $sxe->xpath('./p:sldIdLst/p:sldId');
+
+        foreach($slides as $slide) {
+            $slideRids[] = $slide->attributes('r', true)->id->__toString();
+
+        }
+
+        // get id and name of slides from presentation xml rels
+        $slideNames = array();
+
+         $xmlString = file_get_contents($path . '/ppt/_rels/presentation.xml.rels');
+        $sxe = new SimpleXMLElement($xmlString);
+        $relationships = $sxe->xpath('.')[0];
+
+        foreach($relationships->children() as $relationship) {
+            // a slide
+            if($relationship->attributes()->Type->__toString() == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide") {
+                $target = $relationship->attributes()->Target->__toString();
+                $slideName = substr(substr($target, 0 , strlen($target) - strlen('.xml')), strlen('slides/'));
+                $slideNames[$relationship->attributes()->Id->__toString()] = $slideName;
+            }
+        }
+        
+        // get strings from slides
+        $strings = array();
+
+        foreach($slideRids as $slideRid) {
+            $slide = $slideNames[$slideRid];
+            $strings[$slide] = array();
+
+            $xmlString = file_get_contents($path . '/ppt/slides/' . $slide . '.xml');
+            $sxe = new SimpleXMLElement($xmlString);
+            $texts = $sxe->xpath('./p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:t');
+
+            foreach($texts as $text) {
+                $property = $text->xpath('../../../../p:nvSpPr/p:cNvPr');
+
+                // cannot find property (It won't happen in theory)
+                if(empty($property)) { 
+                    continue;
+                }
+
+                $textName = $property[0]->attributes()->name->__toString();
+
+                $textValue = $text->__toString();
+
+                // a text is translatable if its name starts with 'tr-'
+                if(strpos($textName, 'tr-') === 0 && !in_array($textValue, $strings[$slide])) {
+                    $strings[$slide][] = $textValue;
+                }
+            }
+        }
+
+        return $strings;
+    }
      
     
     function scanTables()
     {
         $ff = HTML_FlexyFramework::get();
         
-        if (empty($ff->Pman_Cms)) {
-            $this->jerr("config[Pman_Cms] is not set");
+        
+        if(!isset($ff->Pman_Cms['DataObjects_Cms_templatestr']['tables'])){
+            return;
         }
+        $cts = DB_DataObject::factory('cms_templatestr');
         
-        if(isset($ff->Pman_Cms['DataObjects_Cms_templatestr']['tables'])){
-            $cts = DB_DataObject::factory('cms_templatestr');
-            
-            if($this->cli){
-                echo "Sync tables.....\n";
-            }
-            
-            foreach($ff->Pman_Cms['DataObjects_Cms_templatestr']['tables'] as $table=>$cols){
-                $t = DB_DataObject::factory($table);
-                foreach($t->fetchAll() as $d) {
-                    $cts->onTableChange($this, $d, 'update');
-                }
+        if($this->cli){
+            echo "Sync tables.....\n";
+        }
+        
+        foreach($ff->Pman_Cms['DataObjects_Cms_templatestr']['tables'] as $table=>$cols){
+            $t = DB_DataObject::factory($table);
+            foreach($t->fetchAll() as $d) {
+                $cts->onTableChange($this, $d, 'update');
             }
         }
+        
     }
     
     function syncLanguage()