Skip to content

Instantly share code, notes, and snippets.

@jehkinen
Created December 8, 2015 21:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jehkinen/8c98e9e57db29f4276ba to your computer and use it in GitHub Desktop.
Save jehkinen/8c98e9e57db29f4276ba to your computer and use it in GitHub Desktop.
<?php
use vendori\traits\FindModelTrait;
/**
* Class DocumentController
*
* Manage document actions
*
* @method Document findModel($id)
*/
class DocumentController extends ExtendedController
{
use FindModelTrait;
private $modelClass = 'Document';
public $bodyClass = 'white-bg';
public function filters()
{
return [
'checkProfileFilled',
'accessControl',
];
}
public function profileMustBeFilled()
{
return [
'upload',
];
}
public function accessRules()
{
return [
['allow',
'actions' => ['autocomplete', 'thumb', 'ajaxGetPage', 'ajaxSearch', 'view', 'ajaxGet'],
'users' => ['*'],
'deniedCallback' => [$this, 'deniedAccessFunction'],
],
['allow',
'actions' => ['requestAccess', 'ajaxRequestAccess', 'allowAccess', 'ajaxUpload',
'ajaxCreate', 'delete', 'download', 'edit', 'addCredit', 'removeCredit', 'getFileViewer'
],
'roles' => [Role::ROLE_USER],
'deniedCallback' => [$this, 'deniedAccessFunction'],
],
['allow',
'actions' => ['upload', 'uploadFinish', 'sendDocumentAccess'],
'roles' => [Role::ROLE_USER, Role::ROLE_ADMIN],
'deniedCallback' => [$this, 'deniedAccessFunction'],
],
['deny',
'users' => ['*'],
'deniedCallback' => [$this, 'deniedAccessFunction'],
],
];
}
public function behaviors()
{
return [
'seo' => ['class' => 'ext.seo.components.SeoControllerBehavior'],
];
}
public function actionAutocomplete()
{
$this->_autocompleteByTerm();
}
/**
* Upload new document
* @access public
* @param int $id - id document with parameters
* @return void
*/
public function actionUpload($id = null)
{
$user = $this->getCurrentUser();
$model = new DocumentUploadForm();
$model->setUser($user);
if (null !== $id) {
$documentModel = $this->findModel($id);
if (!Yii::app()->user->checkAccess(AccessRule::UPDATE_DOCUMENT, ['document' => $documentModel])) {
throw new CHttpException(403);
}
// Upload more
$model->setUploadAttributes($documentModel);
}
if (Yii::app()->getRequest()->getIsAjaxRequest()) {
$model->setAttributes(Yii::app()->request->getPost(CHtml::modelName($model)));
if ($document = $model->saveDocument($user->current_company_id)) {
Yii::app()->user->setFlash('success', "Document {$document->name} has been successfully saved.");
Yii::app()->session['document_id'] = $document->id;
$this->returnJson([]);
Yii::app()->end();
} else {
$result = [];
foreach ($model->getErrors() as $attribute => $errors) {
$result[CHtml::activeId($model, $attribute)] = $errors;
}
$this->returnJson($result);
Yii::app()->end();
}
}
$this->render('upload', [
'user' => $user,
'model' => $model,
]);
}
/**
* Request access to document
* @param $id
*/
public function actionAjaxRequestAccess($id)
{
$access = Document::requestAccess($id);
echo CJSON::encode(
['result' => $access]
);
}
public function actionAllowAccess($document_id, $user)
{
$currentUser = $this->getCurrentUser();
$document = Document::model()->findByPk($document_id);
$hasAccess = $document->user_id == $currentUser->id;
$requestedUser = User::model()->findByPk($user);
$allow = Yii::app()->request->getPost('allow');
if (Yii::app()->request->isAjaxRequest) {
if (!empty($document) && $hasAccess) {
$toEmail = $requestedUser->work_email;
if ($allow == 1) {
$isAccessAllowed = FileUser::allowAccess($document, $user);
if ($isAccessAllowed) {
Document::sentAccessAllowedMail($toEmail, $document);
echo CJSON::encode(['message' => 'Access has successfully allowed']);
} else {
echo CJSON::encode(['message' => 'An error occurred. Please try again']);
}
} else {
Document::sentAccessRestrictedMail($toEmail, $document->id);
echo CJSON::encode(['message' => 'Access Denied, notification to user has been sent']);
}
}
Yii::app()->end();
}
if (!$hasAccess) {
throw new CHttpException(403, 'Access denied. You are not owner of this document');
}
if (!empty($document)) {
$documentUrl = Yii::app()->createUrl("/{$document->type}/view", ['id' => $document->id]);
$alreadyHasAccess = FileUser::checkHasAccess($user, $document->id);
$this->render('approve_access', [
'document' => $document,
'user' => $requestedUser,
'alreadyHasAccess' => $alreadyHasAccess,
'documentUrl' => $documentUrl
]);
Yii::app()->end();
}
throw new CHttpException(404, 'Document not found');
}
/**
* Delete document
* @param $id
* @throws CDbException
* @throws CHttpException
* @throws Exception
*/
public function actionDelete($id)
{
$model = $this->loadModel($id);
if (!Yii::app()->user->checkAccess(AccessRule::DELETE_DOCUMENT, ['document' => $model])) {
throw new CHttpException(405);
}
$url = Yii::app()->request->urlReferrer;
if ($model->delete()) {
$messageType = 'success';
$message = $this->getModelClassName() . ' was deleted.';
$url = '/company/content';
} else {
$messageType = 'error';
$message = 'Unable to delete ' . $this->getModelClassName() . '.';
}
Yii::app()->user->setFlash($messageType, $message);
$this->redirect($url);
}
/**
* Document view action
* @param $id
*/
public function actionView($id)
{
$model = $this->findModel($id);
/* @var $model Document */
if (!Yii::app()->user->checkAccess(AccessRule::VIEW_DOCUMENT, ['document' => $model])) {
$url = $this->createUrl('/document/requestAccess', ['documentId' => $model->id]);
$this->redirect($url);
}
// SEO
$this->metaKeywords = $model->getTagsString(',');
$this->metaDescription = $model->description;
$this->pageTitle = ucfirst($model->name);
$view = $model->type == Document::TYPE_VIDEO ? 'view_video' : 'view';
$this->render($view, [
'model' => $model,
]);
}
public function actionRequestAccess($documentId)
{
$model = $this->loadModel($documentId);
if (!Yii::app()->user->checkAccess(AccessRule::VIEW_DOCUMENT, ['document' => $model])) {
$requestAccessUrl = Yii::app()->createUrl('/document/ajaxRequestAccess', ['id' => $documentId]);
$this->render('request_access', ['requestAccessUrl' => $requestAccessUrl, 'model' => $model]);
} else {
$url = $this->createUrl('/document/view', ['id' => $model->id]);
$this->redirect($url);
}
}
public function getEmbed($id)
{
$model = $this->findModel($id);
if($model->is_public) {
if($model->type == Document::TYPE_VIDEO) {
return $model->getCode();
} else {
return $model->getEmbeddedUrl();
}
} else {
throw new CHttpException(405);
}
}
protected function resolveUploadToPostVariableName()
{
return 'upload_to_scribd';
}
public function actionAjaxSearch($type)
{
$compiler = $this->resolveAjaxSearchCompiler();
echo $this->$compiler($this->ajaxSearch($type));
Yii::app()->end(0, false);
}
protected function resolveAjaxSearchCompiler()
{
return 'compileAjaxSearchOutputThroughRowFormatter';
}
protected function compileAjaxSearchOutputThroughRowFormatter(array $records)
{
$modelClassName = $this->getModelClassName();
$str = '';
foreach ($records as $row) {
$str .= $this->renderInternal('protected/views/company/_' . strtolower($modelClassName) . '_row.php',
[strtolower($modelClassName) => $row], true);
}
return $str;
}
protected function compileAjaxSearchOutput(array $records)
{
$limit = $this->resolveAjaxSearchResultLimit();
$companyId = Yii::app()->request->getParam('id');
$count = count($records);
$pages = new CPagination($count);
$pages->setPageSize($limit);
$data = [
'documents' => $records,
'item_count' => $count,
'page_size' => $limit,
'pages' => $pages,
'modelId' => $companyId,
];
return $this->renderInternal('protected/components/widgets/views/CompaniesDocuments/' . $this->resolveWidgetViewFilePath() . '.php', $data, true);
}
protected function resolveWidgetViewFilePath()
{
switch ($this->id) {
case 'deck':
return 'decks';
case 'video':
return 'videos';
default:
return 'casestudies_whitepapers';
}
}
protected function ajaxSearch($type)
{
$companyId = Yii::app()->request->getParam('id');
$term = Yii::app()->request->getParam('term');
$type = Document::getTypeByLabel($type);
$criteria = new CDbCriteria();
$criteria->condition = "company_id = :companyId AND type = :type AND (name LIKE :term OR description LIKE :term)";
$criteria->params = [
':companyId' => $companyId,
':type' => $type,
':term' => "%{$term}%"
];
$criteria->limit = $this->resolveAjaxSearchResultLimit();
$criteria->order = 't.id desc';
return Document::model()->findAll($criteria);
}
/**
* Get company documents
* @param $type
* @throws Exception
*/
public function actionAjaxGetPage($type)
{
$companyId = Yii::app()->request->getParam('id');
$page = Yii::app()->request->getParam('page');
$company = $this->loadModel($companyId, 'Company');
$type = Document::getTypeByLabel($type, 2);
$pluralLabel = Document::labelByType($type, 2);
$this->widget('application.components.widgets.Companies' . $pluralLabel, [
'user' => $this->getCurrentUser(),
'model' => $company,
'pageNumber' => $page,
]);
Yii::app()->end(0, false);
}
public function actionEdit($id)
{
$modelClassName = 'Document';
$model = $this->findModel($id);
/* @var $model Document */
if (!Yii::app()->user->checkAccess(AccessRule::UPDATE_DOCUMENT, ['document' => $model])) {
throw new CHttpException(405);
}
if (Yii::app()->request->isPostRequest) {
if (isset($_POST[$modelClassName])) {
$model->setAttributes($_POST[$modelClassName]);
if ($model->save()) {
if ($model->is_default) {
$model->setDefault();
}
if (isset($_POST['brands'])) {
$brandNames = !empty($_POST['brands']) ? explode(VendoriActiveRecord::ENTITY_DELIMITER, $_POST['brands']) : [];
$model->setBrands($brandNames);
}
if (isset($_POST['solutions'])) {
$solutionNames = !empty($_POST['solutions']) ? explode(VendoriActiveRecord::ENTITY_DELIMITER, $_POST['solutions']) : [];
$model->setSolutions($solutionNames);
}
if (isset($_POST['channels'])) {
$channelNames = !empty($_POST['channels']) ? explode(VendoriActiveRecord::ENTITY_DELIMITER, $_POST['channels']) : [];
$model->setChannels($channelNames);
}
if (isset($_POST['companies'])) {
$companies = !empty($_POST['companies']) ? explode(VendoriActiveRecord::ENTITY_DELIMITER, $_POST['companies']) : [];
$model->setCompanies($companies);
}
if ($model->type == Document::TYPE_VIDEO && isset($_POST['videoThumb'])) {
$model->setThumb($_POST['videoThumb']);
}
/**
if ($permissions = Yii::app()->request->getPost('permissions')) {
$model->setPermissionsFromString($permissions);
}*/
Yii::app()->user->setFlash('success', $modelClassName . ' was updated');
$this->redirect(['edit', 'id' => $id]);
}
}
}
$this->layout = '//layouts/frontend';
$this->render('//document/edit', [
'model' => $model,
'relationName' => 'credit',
'relatedClassName' => 'FileUser',
'description' => 'Give credit to people featured or who helped create this content',
]);
}
/**
* Download file
* @param $id
* @throws CHttpException
* @throws Exception
*/
public function actionDownload($id)
{
$document = $this->findModel($id);
/* @var $document Document */
if (!Yii::app()->user->checkAccess(AccessRule::VIEW_DOCUMENT, ['document' => $document])) {
throw new CHttpException(405);
}
if ($document->documentS3) {
$url = $document->documentS3->getFileUrl(strtotime("+10 minute"), true);
$this->redirect($url);
Yii::app()->end();
} elseif (in_array($document->type, [Document::TYPE_SIMPLE_DOCUMENT, Document::TYPE_PRESENTATION])) {
$content = Yii::app()->boxcom->getOriginalContent($document->box_com_id);
Yii::app()->request->sendFile($document->name, $content);
Yii::app()->end();
} elseif ($document->type == Document::TYPE_VIDEO) {
$mediaData = Yii::app()->wistia->getMediaData($document->wistia_media_id);
if (!empty($mediaData['assets'])) {
$this->redirect($mediaData['assets'][0]['url']);
}
} else {
throw new CHttpException(404, 'Requested file does not exist');
}
}
public function actionGetFileViewer($id)
{
$model = $this->findModel($id);
if (!$model) {
throw new CHttpException(404, "Document does not exist");
}
$url = $model->getEmbededUrl();
if (Util::checkStatus($url)) {
echo '<div class="doc-viewer-wrapper" id="doc-viewer-wrapper"></div>';
} else {
echo '<img src="/images/edit-content-error.gif" alt="" width="357" height="357">';
}
Yii::app()->end();
}
protected function resolveAjaxSearchResultLimit()
{
return 8;
}
public function actionSendDocumentAccess()
{
$id = Yii::app()->session['document_id'];
if (!$id) throw new CHttpException(404, 'Document not found');
if (!empty($_POST['EmailForm']) && $_POST['EmailForm']['email']) {
$document = $this->findModel($id);
$emailsString = $_POST['EmailForm']['email'];
$message = $_POST['EmailForm']['message'];
$emails = $this->fromStringToArray($emailsString);
$document->setUserAccess($emails, FileUser::USER_TYPE_CONTRIBUTORS, true, $message );
Yii::app()->user->setFlash('shared_message', "{$document->labelByType($document->type)} {$document->name}
has been successfully shared to {$emailsString} emails");
}
$this->redirect('/document/uploadFinish');
}
public function fromStringToArray($string)
{
$result = [];
if (!empty($string)) {
$result = explode(VendoriActiveRecord::ENTITY_DELIMITER, $string);
}
return $result;
}
public function getTaggedRelatedModelUrl(VendoriActiveRecord $model)
{
$modelClassName = get_class($model);
if ($modelClassName === 'Company') {
return $this->createUrl('/company/overview', ['id' => $model->id, 'name' => $model->name]);
} else if (in_array($modelClassName, ['Brand', 'Solution', 'Channel'])) {
return $this->createUrl('/search/company', [strtolower($modelClassName) => $model->id]);
}
}
public function actionUploadFinish()
{
$id = Yii::app()->session['document_id'];
if (!$id) throw new CHttpException(404, 'Document not found');
$model = $this->findModel($id);
if (!Yii::app()->user->checkAccess(AccessRule::VIEW_DOCUMENT, ['document' => $model])) {
throw new CHttpException(405);
}
$user = $this->getCurrentUser();
$emailForm = new EmailForm();
$this->render('upload/finish', compact('model', 'user', 'emailForm'));
}
/*
@todo @radzserg - those actions must be moved to DocumentUserController
public function actionAddCredit()
{
if (Yii::app()->request->isPostRequest && !Yii::app()->user->isGuest) {
$data = [];
$id = isset($_POST['id']) ? $_POST['id'] : '';
$email = isset($_POST['email']) ? $_POST['email'] : '';
$name = isset($_POST['name']) ? $_POST['name'] : '';
if (is_numeric($email)) {
$userId = $email;
/* @var $user User
$this->doesCreditAlreadyExist($id, FileUser::USER_TYPE_PRESENTED_TO, $user->id);
if (!FileUser::addByUserId($id, $user->id, FileUser::USER_TYPE_PRESENTED_TO)) {
$this->ajaxSaveFailed();
}
$userData = $user->assembleUserInformationForCreditsControl();
} else {
$validator = new CEmailValidator;
if (!$validator->validateValue($email)) {
$this->ajaxError('email error');
}
if (!FileUser::addByUserEmail($id, $email, FileUser::USER_TYPE_PRESENTED_TO, $name)) {
$this->ajaxSaveFailed();
}
$userData = User::assembleNonRegisteredUserForCreditsControl($name, $email);
}
$this->mapUserDataArrayToCreditsData($userData, $data);
print_r(CJSON::encode($data));
}
Yii::app()->end();
}
public function actionRemoveCredit()
{
if (Yii::app()->request->isPostRequest && !Yii::app()->user->isGuest) {
$type = isset($_POST['type']) ? $_POST['type'] : '';
$id = isset($_POST['id']) ? $_POST['id'] : '';
$typeModel = ucfirst($type);
$document = $typeModel::model()->findByPk($id);
if (!$document) {
return $this->ajaxError('Document ID is invalid');
}
$uid = isset($_POST['uid']) ? $_POST['uid'] : '';
$name = isset($_POST['name']) ? $_POST['name'] : '';
if (is_numeric($uid)) {
$user = $this->isValidUserId($uid);
FileUser::model()->deleteAllByAttributes(['file_id' => $id, 'user_id' => $user->id]);
} else {
list($email, $name) = $this->extractEmailAndName($name);
FileUser::model()->deleteAllByAttributes(['file_id' => $id, 'email' => $email, 'name' => $name]);
}
}
Yii::app()->end();
}
protected function doesCreditAlreadyExist($id, $userId, $type = FileUser::USER_TYPE_PRESENTED_TO)
{
if (FileUser::model()->findByAttributes(['file_id' => $id, 'user_id' => $userId, 'user_type' => $type])) {
$this->ajaxError('credit exists');
}
}
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment