public function executeImpl($partner_id, $subp_id, $puser_id, $partner_prefix, $puser_kuser)
 {
     $entry_id = $this->getP("entry_id");
     $kshow_id = $this->getP("kshow_id");
     list($kshow, $entry, $error, $error_obj) = myKshowUtils::getKshowAndEntry($kshow_id, $entry_id);
     if ($error_obj) {
         $this->addError($error_obj);
         return;
     }
     $kshow_id = $kshow->getId();
     if ($kshow_id === kshow::SANDBOX_ID) {
         $this->addError(APIErrors::SANDBOX_ALERT);
         return;
     }
     // TODO -  think what is the best way to verify the privileges - names and parameters that are initially set by the partner at
     // startsession time
     if (!$this->isOwnedBy($kshow, $puser_kuser->getKuserId())) {
         $this->verifyPrivileges("edit", $kshow_id);
     }
     // user was granted explicit permissions when initiatd the ks
     // this part overhere should be in a more generic place - part of the services
     $multiple_roghcuts = Partner::allowMultipleRoughcuts($partner_id);
     $likuser_id = $puser_kuser->getKuserId();
     $isIntro = $kshow->getIntroId() == $entry->getId();
     if ($multiple_roghcuts) {
         // create a new entry in two cases:
         // 1. the user saving the roughcut isnt the owner of the entry
         // 2. the entry is an intro and the current entry is not show (probably an image or video)
         if ($entry->getKuserId() != $likuser_id || $isIntro && $entry->getMediaType() != entry::ENTRY_MEDIA_TYPE_SHOW) {
             // TODO: add security check to whether multiple roughcuts are allowed
             // create a new roughcut entry by cloning the original entry
             $entry = myEntryUtils::deepClone($entry, $kshow_id, false);
             $entry->setKuserId($likuser_id);
             $entry->setCreatorKuserId($puser_kuser->getKuserId());
             $entry->setCreatedAt(time());
             $entry->setMediaType(entry::ENTRY_MEDIA_TYPE_SHOW);
             $entry->save();
         }
     }
     $xml_content = "<xml><EntryID>" . $entry->getId() . "</EntryID></xml>";
     if ($isIntro) {
         $kshow->setIntroId($entry->getId());
     } else {
         $kshow->setShowEntryId($entry->getId());
         $has_roughcut = $this->getP("HasRoughCut", "1", true);
         if ($has_roughcut === "0") {
             $kshow->setHasRoughcut(false);
             $kshow->save();
             $this->addMsg("saved_entry", $entry->getId());
             return;
         }
     }
     $content = $this->getP("xml");
     $update_kshow = false;
     if ($content != NULL) {
         $version_info = array();
         $version_info["KuserId"] = $puser_kuser->getKuserId();
         $version_info["PuserId"] = $puser_id;
         $version_info["ScreenName"] = $puser_kuser->getPuserName();
         list($xml_content, $comments, $update_kshow) = myMetadataUtils::setMetadata($content, $kshow, $entry, false, $version_info);
     } else {
         $comments = "";
         // if there is no xml - receive it from the user
         $this->debug = true;
         return "text/html; charset=utf-8";
     }
     $this->addMsg("xml", $xml_content);
     $this->addMsg("saved_entry", $entry->getId());
     $this->addDebug("comment", $comments);
 }
 public static function createKEditorMetadata($kshow, $show_entry, $entries)
 {
     $vidassets = '';
     $overlays = '';
     $totalTime = 0;
     $soundTimes = array();
     $lastSoundTime = 0;
     $isPrevVideo = null;
     $addLastFadeoutTime = 0;
     foreach ($entries as $entry) {
         $assetStartTime = $totalTime;
         $media_type = $entry->getMediaType();
         if ($media_type == entry::ENTRY_MEDIA_TYPE_IMAGE || $media_type == entry::ENTRY_MEDIA_TYPE_VIDEO) {
             $startTime = 0;
             $lenTime = $entry->getLengthInMsecs() / 1000;
             if ($media_type == entry::ENTRY_MEDIA_TYPE_VIDEO) {
                 $isVideo = true;
                 $media_type_str = 'VIDEO';
             } else {
                 if ($media_type == entry::ENTRY_MEDIA_TYPE_IMAGE) {
                     $isVideo = false;
                     $media_type_str = 'IMAGE';
                     $lenTime = 4;
                 } else {
                     continue;
                 }
             }
             $addLastFadeoutTime = 1;
             $totalTime += $lenTime - 1;
             $entry_id = $entry->getId();
             $media_name = $entry->getName();
             $media_url = $entry->getDataUrl();
             $relMedia_url = strstr($media_url, "/content");
             $vidassets .= '<vidAsset k_id="' . $entry_id . '" type="' . $media_type_str . '" name="' . $media_name . '" url="' . $media_url . '">' . '<StreamInfo file_name="' . $relMedia_url . '" start_time="' . $startTime . '" len_time="' . $lenTime . '" posX="0" posY="0" start_byte="-1" end_byte="-1" total_bytes="-1" real_seek_time="-1" volume="1" pan="0" isSingleFrame="0" real_start_byte="-1" real_end_byte="-1"/>' . '<EndTransition type="dissolve" StartTime="' . ($lenTime - 1) . '" length="1">' . '<arguments>' . '<name>dissolve</name>' . '<version>1.00</version>' . '<arguments/>' . '</arguments>' . '</EndTransition>' . '</vidAsset>';
         }
         if ($isPrevVideo === null) {
             $isPrevVideo = $isVideo;
         }
         if ($isVideo != $isPrevVideo) {
             $endTime = $isVideo ? $assetStartTime : $assetStartTime + 1;
             $soundTimes[] = array("type" => $isPrevVideo, "startTime" => $lastSoundTime, "endTime" => $endTime);
             $isPrevVideo = $isVideo;
             $lastSoundTime = $endTime;
         }
     }
     $totalTime += $addLastFadeoutTime;
     $soundTimes[] = array("type" => $isPrevVideo, "startTime" => $lastSoundTime, "endTime" => $totalTime);
     // add soundtrack
     //echo print_r($soundTimes, true);
     $audassets = '';
     $entry = entryPeer::retrieveByPK(209);
     $loop = true;
     $quiet = true;
     $volume = 1;
     $quietVolume = $quiet ? $volume * 0.2 : 0;
     $lenTime = $entry->getLengthInMsecs() / 1000;
     if ($entry && $totalTime) {
         $entry_id = $entry->getId();
         $media_name = $entry->getName();
         $media_url = $entry->getDataUrl();
         $relMedia_url = strstr($media_url, "/content");
         $startTime = 0;
         $soundTime = current($soundTimes);
         $currentVolume = $soundTime["type"] ? $quietVolume : $volume;
         // the first sound time is always at the start of the first clip.
         // because every clip gets a volPoint at its begining and end we can just skip this entry
         $soundTime = next($soundTimes);
         while ($startTime < $totalTime) {
             $clippedLenTime = min($totalTime - $startTime, $lenTime);
             $endTime = $startTime + $clippedLenTime;
             // always add the required volume at the start of the clip
             $volPoints = '<VolumePoints><VolumePoint time="0" volume="' . $currentVolume . '"/>';
             // add any volume changes found within the duration of the current clip
             while ($soundTime !== FALSE && $soundTime['startTime'] < $endTime) {
                 // make a spike by putting the current volume and then the next one within 0.1 seconds
                 $volPoints .= '<VolumePoint time="' . ($soundTime["startTime"] - $startTime - 0.1) . '" volume="' . $currentVolume . '"/>';
                 $currentVolume = $soundTime["type"] ? $quietVolume : $volume;
                 $volPoints .= '<VolumePoint time="' . ($soundTime["startTime"] - $startTime) . '" volume="' . $currentVolume . '"/>';
                 $soundTime = next($soundTimes);
             }
             // always add the required volume at the end of the clip
             $volPoints .= '<VolumePoint time="' . $clippedLenTime . '" volume="' . $currentVolume . '"/></VolumePoints>';
             $audassets .= '<AudAsset k_id="' . $entry_id . '" type="AUDIO" name="' . $media_name . '" url="' . $media_url . '">' . '<StreamInfo file_name="' . $relMedia_url . '" start_time="0" len_time="' . $clippedLenTime . '" posX="0" posY="0" start_byte="-1" end_byte="-1" total_bytes="-1" real_seek_time="-1" volume="' . $volume . '" pan="0" isSingleFrame="0" real_start_byte="-1" real_end_byte="-1"/>' . '<EndTransition type="None" StartTime="' . $lenTime . '" length="0"/>' . $volPoints . '</AudAsset>';
             if (!$loop) {
                 break;
             }
             $startTime += $lenTime;
         }
     }
     $xmlData = '<?xml version="1.0"?>' . "<xml>" . "<MetaData>" . "<SeqDuration>{$totalTime}</SeqDuration>" . "<ShowVersion></ShowVersion>" . "</MetaData>" . "<VideoAssets>{$vidassets}</VideoAssets><AudioAssets>{$audassets}</AudioAssets><VoiceAssets/><LoaderObjectAssets/>" . "<Plugins><Overlays>{$overlays}</Overlays></Plugins>" . "</xml>";
     myMetadataUtils::setMetadata($xmlData, $kshow, $show_entry);
 }
 /**
  * Executes addComment action, which returns a form enabling the insertion of a comment
  * The request may include 1 fields: entry id.
  */
 protected function executeImpl(kshow $kshow, entry &$entry)
 {
     $kshow_id = $kshow->getId();
     if ($this->partner_id != null) {
         // this part overhere should be in a more generic place - part of the services
         $multiple_roghcuts = Partner::allowMultipleRoughcuts($this->partner_id);
         $likuser_id = $this->getLoggedInUserId();
     } else {
         // 	is the logged-in-user is not an admin or the producer - check if show can be published
         $likuser_id = $this->getLoggedInUserId();
         $multiple_roghcuts = true;
     }
     if (!$likuser_id) {
         return $this->securityViolation($kshow->getId());
     }
     $isIntro = $kshow->getIntroId() == $entry->getId();
     if ($multiple_roghcuts) {
         // create a new entry in two cases:
         // 1. the user saving the roughcut isnt the owner of the entry
         // 2. the entry is an intro and the current entry is not show (probably an image or video)
         if ($entry->getKuserId() != $likuser_id || $isIntro && $entry->getMediaType() != entry::ENTRY_MEDIA_TYPE_SHOW) {
             // TODO: add security check to whether multiple roughcuts are allowed
             // create a new roughcut entry by cloning the original entry
             $entry = myEntryUtils::deepClone($entry, $kshow_id, false);
             $entry->setKuserId($likuser_id);
             $entry->setCreatorKuserId($likuser_id);
             $entry->setCreatedAt(time());
             $entry->setMediaType(entry::ENTRY_MEDIA_TYPE_SHOW);
             $entry->save();
         }
     }
     /*
     		$viewer_type = myKshowUtils::getViewerType($kshow, $likuser_id);
     		if ( $viewer_type != KshowKuser::KSHOWKUSER_VIEWER_PRODUCER && ( ! $kshow->getCanPublish() ) ) 
     		{
     			// ERROR - attempting to publish a non-publishable show
     			return $this->securityViolation( $kshow->getId() );
     		}
     */
     $this->xml_content = "<xml><EntryID>" . $entry->getId() . "</EntryID></xml>";
     if ($isIntro) {
         $kshow->setIntroId($entry->getId());
     } else {
         $kshow->setShowEntryId($entry->getId());
         $has_roughcut = @$_REQUEST["HasRoughCut"];
         if ($has_roughcut === "0") {
             $kshow->setHasRoughcut(false);
             $kshow->save();
             return;
         }
     }
     $content = @$_REQUEST["xml"];
     $update_kshow = false;
     if ($content != NULL) {
         list($xml_content, $this->comments, $update_kshow) = myMetadataUtils::setMetadata($content, $kshow, $entry);
         // Send an email alert to producer
         if ($kshow->getProducerId() != $likuser_id) {
             // don't send producer alerts when the producer is the editor
             alertPeer::sendEmailIfNeeded($kshow->getProducerId(), alert::KALTURAS_PRODUCED_ALERT_TYPE_ROUGHCUT_CREATED, array('screenname' => $this->getUser()->getAttribute('screenname'), 'kshow_name' => $kshow->getName(), 'kshow_id' => $kshow->getId()));
         }
         // TODO:  efficiency: see if there is a wa to search for contributors based on some other method than full entry table scan
         // Send email alerts to contributors
         $c = new Criteria();
         $c->add(entryPeer::KSHOW_ID, $kshow_id);
         $c->add(entryPeer::KUSER_ID, $likuser_id, Criteria::NOT_EQUAL);
         // the current user knows they just edited
         $c->addAnd(entryPeer::KUSER_ID, $kshow->getProducerId(), Criteria::NOT_EQUAL);
         // the producer knows they just edited
         $c->add(entryPeer::TYPE, entryType::MEDIA_CLIP);
         $c->addGroupByColumn(entryPeer::KUSER_ID);
         $entries = entryPeer::doSelect($c);
         $already_received_alert_array = array();
         foreach ($entries as $entry) {
             alertPeer::sendEmailIfNeeded($entry->getKuserId(), alert::KALTURAS_PARTOF_ALERT_TYPE_ROUGHCUT_CREATED, array('screenname' => $this->getUser()->getAttribute('screenname'), 'kshow_name' => $kshow->getName(), 'kshow_id' => $kshow->getId()));
             $already_received_alert_array[$entry->getKuserId()] = true;
         }
         // send email alert to subscribers
         $c = new Criteria();
         $c->add(KshowKuserPeer::KSHOW_ID, $kshow_id);
         //only subsribers of this show
         $c->add(KshowKuserPeer::KUSER_ID, $likuser_id, Criteria::NOT_EQUAL);
         // the current user knows they just edited
         $c->add(KshowKuserPeer::SUBSCRIPTION_TYPE, KshowKuser::KSHOW_SUBSCRIPTION_NORMAL);
         // this table stores other relations too
         $subscriptions = KshowKuserPeer::doSelect($c);
         foreach ($subscriptions as $subscription) {
             if (!isset($already_received_alert_array[$subscription->getKuserId()])) {
                 // don't send emails to subscribed users who are also contributors
                 alertPeer::sendEmailIfNeeded($subscription->getKuserId(), alert::KALTURAS_SUBSCRIBEDTO_ALERT_TYPE_ROUGHCUT_CREATED, array('screenname' => $this->getUser()->getAttribute('screenname'), 'kshow_name' => $kshow->getName(), 'kshow_id' => $kshow->getId()));
             }
         }
         if ($this->debug) {
             return "text/html; charset=utf-8";
         }
     } else {
         $this->comments = "";
         // if there is no xml - receive it from the user
         $this->debug = true;
         $file_name = myContentStorage::getFSContentRootPath() . "/" . $entry->getDataPath();
         //$this->xml_content = kFile::getFileContent( $file_name );
         return "text/html; charset=utf-8";
     }
 }