Обучаю битриксу программистов, интеграторов. Подробнee ⇒

Посчитать количество страниц pdf и положить в поле в смарт-процессе через БП



Коробка, Смарт-процессы
в поле смарт-процесса лежит ссылка на файл pdf в битриксе (общий диск, диск юзера)

Задача
в другое поле положить количество страниц. сделать через БП
используем для подсчета Imagick

функция, размещаем в init.php
function CalculatePdfPages($dinId,$authorId){
   //$dinId[2] = "DYNAMIC_175_1" получено $root->GetDocumentId();
   //$authorId = user_389

   $propFileLink = "UF_CRM_3_1705390834620"; //поле со ссылкой на файл
   $propPages = "UF_CRM_3_1705666582056"; // поле, куда положить количество страниц
   $host = explode(":",$_SERVER['HTTP_HOST']);
   $host = $host[0];
   
   
   $bError = true;
   $errorText = "";

   $b = true;
   while($b){//для простого выхода из проверок
      $b = false;   

      $temp = explode("_", $dinId[2]);
      if($temp[0] != "DYNAMIC"){
         $errorText = "Это не смарт-процесс";
         break;
      }
      $smTypeId = $temp[1];
      $smId = $temp[2];

      if(!CModule::IncludeModule("crm") || !CModule::IncludeModule("disk")){
         $errorText = "Не смогли подключить модули";
         break;
      }   
      $factory = Bitrix\Crm\Service\Container::getInstance()->getFactory($smTypeId);
      if(empty($factory)){
         $errorText = "Не смогли получить тип смарт-процесса";
         break;
      }
      $item = $factory->getItem($smId);
      if(empty($item)){
         $errorText = "Не смогли получить экземпляр смарт-процесса";
         break;
      }
      $data = $item->getData();
      $name = $data[$propFileLink]??"";      

      if(empty($name)){            
         $errorText = "поле с пдф пустое";
         break;
      }
      
         

      //смотрим по типам
      if(strpos($name,$host.'/company/personal/user/')!==false && strpos($name,'/disk/file/')!==false){             
         $name = urldecode($name);
         if(mb_substr($name,-4)!=".pdf"){
            //уведомление что файл не pdf   
            $errorText = "файл в поле не пдф";
            break;
         }            
         $uid = substr($name,strpos($name,'/company/personal/user/')+strlen('/company/personal/user/'));
         $uid = substr($uid,0,strpos($uid,"/"));
         $path = substr($name,strpos($name,'/disk/file/')+strlen('/disk/file/'));
         if(empty($uid) || intval($uid)!=$uid || empty($path)){
            $errorText = "не смогли обработать имя файла ".$name;
            break;
         }   
            
         $arPath = explode("/",$path);
         $cnt = count($arPath);
         $fileName = $arPath[($cnt-1)];
         unset($arPath[($cnt-1)]);
         $storage = \Bitrix\Disk\Driver::getInstance()->getStorageByUserId($uid); 
            if (!$storage){
               $errorText = "не смогли получить диск пользователя ".$uid;
            break;
            }   

         $folder = $storage->getRootObject(); 
         foreach($arPath as $folderName){            
            $folder = $folder->getChild([
                 '=NAME' => $folderName,  
                 'TYPE' => \Bitrix\Disk\Internals\FolderTable::TYPE_FOLDER 
              ]);
              if(empty($folder)){                     
               $errorText = "не смогли получить папку";
               break(2);

            }
         }
         $file = $folder->getChild( 
             array( 
               '=NAME' => $fileName,  
               'TYPE' => \Bitrix\Disk\Internals\FileTable::TYPE_FILE 
             ) 
         );               
            
         
      }
      elseif(strpos($name, $host.'/docs/')!==false){ //на общих дисках
         $name = urldecode($name);
         $code = substr($name,strpos($name,"/docs/")+1);
         $code = explode("/", $code);
         if(empty($code) || count($code)<2){
            $errorText = "не смогли получить общую папку из".$name;
            break;

         }
         $code = $code[0]."/".$code[1];
         $disks = \Bitrix\Disk\Storage::getList([
            "select"=>["ID","ENTITY_MISC_DATA"],
            "filter"=> [
               "ENTITY_TYPE"=>"Bitrix\Disk\ProxyType\Common",
               "ENTITY_MISC_DATA" => "%".$code."%"
            ]
         ]);
         if($disk = $disks->fetch()){
            //$t = unserialize($disk["ENTITY_MISC_DATA"]);
            //$t["BASE_URL"]

            $storage = \Bitrix\Disk\Storage::loadById($disk["ID"]);
            if (!$storage){
                  $errorText = "не смогли получить диск ".$disk["ID"];
               break;
               }
            $path = substr($name,strpos($name,"/".$code."/file/")+strlen("/".$code."/file/"));
            $arPath = explode("/",$path);
            $cnt = count($arPath);
            $fileName = $arPath[($cnt-1)];
            unset($arPath[($cnt-1)]);

            

            $folder = $storage->getRootObject(); 
            foreach($arPath as $folderName){            
               $folder = $folder->getChild([
                    '=NAME' => $folderName,  
                    'TYPE' => \Bitrix\Disk\Internals\FolderTable::TYPE_FOLDER 
                 ]);
                 if(empty($folder)){                     
                  $errorText = "не смогли получить папку ".$folderName." c общего диска";
                  break(2);

               }
            }
            echo $fileName;
            $file = $folder->getChild( 
                array( 
                  '=NAME' => $fileName,  
                  'TYPE' => \Bitrix\Disk\Internals\FileTable::TYPE_FILE 
                ) 
            );               
            
         }
         else{
            $errorText = "не нашли общий диск по коду ".$code." из ".$name;
            break;
         }



      }

      elseif(strpos($name,$host.'/bitrix/tools/disk/focus.php')!==false){ //objectId=56695
         $arUrl = parse_url($name);
         if(empty($arUrl["query"])){
            $errorText = "неправильная ссылка ".$name;
            break;
         }
         parse_str($arUrl["query"],$params);
         if(empty($params["objectId"]) || intval($params["objectId"])!=$params["objectId"]){
            $errorText = "неправильный параметр objectId в ссылкe ".$name;
            break;
         }
         $file = Bitrix\Disk\File::getById($params["objectId"]);

      }
      elseif(strpos($name,$host.'/disk/showFile/')!==false){ //вида /disk/showFile/56695/
         $fileId = substr($name, (strpos($name,'/disk/showFile/') + strlen('/disk/showFile/')));
         $fileId = substr($fileId,0,strpos($name,"/")-1);
         if(empty($fileId) || intval($fileId)!=$fileId){
            $errorText = "не смогли получить файл ID из ".$name;
            break;
         }
         $file = Bitrix\Disk\File::getById($fileId);
      }
      else{
         $errorText = "поле со ссылкой непонятного формата";
         break;
      }   
         
      if(empty($file)){
         $errorText = "не смогли получить файл ".$fileName;
         break;
      }    
      $info = $file->getFile();
      if(empty($info["CONTENT_TYPE"]) || ($info["CONTENT_TYPE"]!= "application/pdf")){
         $type = $info["CONTENT_TYPE"]??"";
         $errorText = "тип файла не pdf, a ".$type;
         break;
      }   
      /*$fp = fopen($_SERVER["DOCUMENT_ROOT"].$info["SRC"], 'r');
      if (!$fp) {
         $errorText = "не смогли открыть файл ".$_SERVER["DOCUMENT_ROOT"].$info["SRC"];
         break;
      }   
      $content = fread ($fp, filesize($_SERVER["DOCUMENT_ROOT"].$info["SRC"]));   
      if(!$content){
         $errorText = "не смогли прочитать файл ".$_SERVER["DOCUMENT_ROOT"].$info["SRC"];
         break;
      }
      $countPages = 0;
      $regex  = "/\/Count\s+(\d+)/";
      $regex2 = "/\/Page\W*(\d+)/";
      $regex3 = "/\/N\s+(\d+)/";
      if(preg_match_all($regex, $content, $matches))
         $countPages = max($matches);

      fclose($fp);   */
      $im = new Imagick();       
      $im->pingImage( $_SERVER["DOCUMENT_ROOT"].$info["SRC"] );
      $countPages = $im->getNumberImages();

      $item->set($propPages,$countPages);
      $item->save();
      //апдейтим поле в смарт-процессе
      //echo "количество страниц: ".$countPages;

      $bError = false;      
      
   }
   
   if($bError){
      //уведомление в чат автору с ошибкой
      //echo $errorText;
      if(strpos($authorId,"user_")!==false){
         $authorId = str_replace("user_", "",$authorId);
         if(CModule::IncludeModule('im')){
            $arFields = array(
               "NOTIFY_TITLE" => "Ошибка при подсчете страниц", //заголовок                 
               "MESSAGE" => $errorText,
               "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM, // IM_MESSAGE_PRIVATE, IM_MESSAGE_CHAT, IM_MESSAGE_OPEN, IM_MESSAGE_SYSTEM, IM_MESSAGE_OPEN_LINE
               "TO_USER_ID" => $authorId,
               "FROM_USER_ID" => $authorId,
               //"AUTHOR_ID" => $userIdOther, //может отличаться от FROM_USER_ID
               
               "NOTIFY_TYPE" => IM_NOTIFY_SYSTEM,  // IM_NOTIFY_CONFIRM, IM_NOTIFY_SYSTEM, IM_NOTIFY_FROM
               "NOTIFY_MODULE" => "main", // module id sender (ex: xmpp, main, etc)
               "NOTIFY_EVENT" => "manage",                   
            );
            CIMMessenger::Add($arFields);
         }
      }   
   }   
}
из БП php код
$root = $this->GetRootActivity();
$id = $root->GetDocumentId();
CalculatePdfPages($id,"{{Кем создан}}");

вариант, по id попроще
function CalculatePdfPagesByFileId($fileId){
    $result = 0;
    if(!empty($fileId) && (intval($fileId)==$fileId) && CModule::IncldeModule('disk')){
        $file = Bitrix\Disk\File::getById($fileId);
        $info = $file->getFile();
        $b = true;

        if(!empty($info["CONTENT_TYPE"]) && ($info["CONTENT_TYPE"]== "application/pdf")){
            $im = new Imagick();       
            $im->pingImage( $_SERVER["DOCUMENT_ROOT"].$info["SRC"] );
            $result = $im->getNumberImages();              
        }         
    }
    return $result;    
} 

из БП php код
$root = $this->GetRootActivity(); 
$cntPages = CalculatePdfPagesByFileId($root->GetVariable('Variable10'));
$root->SetVariable('Variable11', $cntPages);
Если блог был полезным, можете угостить меня "чашечкой кофе" :)

Сбер по номеру телефона +7 (953) 585-13-09 Вероника.
Спасибо!