Разрабатываем социальную сеть на MODx Revolution

в 12:06, , рубрики: modx, web-разработка, Веб-разработка, социальные сети, метки: , ,

MODx развивается стремительными темпами, и я решил попробовать сделать социальную сеть на этом замечательном движке. Ведь в нем давно уже есть возможность работать с пользователями (регистрация, авторизация и пр.), встроенный механизм сообщений пользователей, он умеет работать с изображениями и много чего еще.

Для начала давайте разберемся с пользователями, дадим им возможность писать статьи, например, или добавлять свои события.

Регистрация пользователей

Для регистрации мы будем использовать сниппет Login.

[[!Register? &postHooks=`addUser` &usergroups=`Users` &submittedResourceId=`9` &activationResourceId=`11` &activationEmailSubject=`Подтвердите регистрацию на сайте` &validate=`email:email:required`]]

О самом сниппете написано уже много, покажу, что делает наш хук addUser:

Сниппет addUser

Сниппет addUser

<?php
$output = "";
$parent = 2;
$template = 3;

// Создаем ресурс для пользователя (его личная страничка)

if ($id = $modx->runSnippet('addResource', array(
	  'pagetitle' => $hook->getValue('username'),
	  'parent' => $parent,
	  'template' => $template,
	  'isfolder' => 1,
	  'published' => 1,
  	  'hidemenu' => 1
	))) {

// Записываем id странички пользователя в поле website
// (хотя можно было использовать и User Extended)
	
  $userId = $hook->getValue('register.user')->get('id');
  $user = $modx->getObject('modUserProfile', array('id' => $userId));
  $user->set('website',$id);
  $user->save();

// А в для самого ресурса создаем TV-параметр, где указываем id пользователя
  
  $modx->runSnippet('tv', array('id' => $id, 'tv' => 1, 'value' => $userId));  

  $modx->cacheManager->refresh();

  $output = $id;

} else {
  
  print '<h1>Can not to create the new user</h1><p>Please, tell us about this</p><h2>Contacts</h2><p>E-mail: <a href="mailto:admin@site.ru">admin@site.ru</a></p>';
  die();

}

return $output;

Сниппет addResource

Сниппет addResource

<?php
// Сниппет будет получать данные из формы методом POST
if (!$pagetitle)   $pagetitle   =  $_POST['title'];
if (!$longtitle)   $longtitle   =  $_POST['longtitle'];
if (!$content)     $content     =  $_POST['content'];
if (!$introtext)   $introtext   =  $_POST['introtext'];
if (!$description) $description =  $_POST['description'];
if (!$parent)      $parent      =  $_POST['parent'];
if (!$isfolder)    $isfolder    =  $_POST['isfolder'];
if (!$hidemenu)    $hidemenu    =  $_POST['hidemenu'];
if (!$template)    $template    =  $_POST['template'];
if (!$menutitle)   $menutitle   =  $_POST['menutitle'];
if (!$published)   $published   =  $_POST['published'];
if (!$publishedon) $publishedon =  date('Y-m-d H:i:s');

// Если некоторые значения не будут указаны,
// они будут установлены по умолчанию
if (!$parent)      $parent = 1;
if (!$template)    $template = 1;

// Устанавливаем префикс для псевдонима
switch ($template) {
  case 1: $prefix = "art"; break;		// Статья
  case 2: $prefix = "id"; break;		// Пользователь
  case 3: $prefix = "id"; break;		// Пользователь
  case 4: $prefix = "event"; break;		// Событие
  case 5: $prefix = "animal"; break;       // Домашнее животное
  default: $prefix = "id"; break;
}

// Создаем ресурс
$newResource = $modx->newObject('modResource');

// Заполняем нужные значения
$newResource->set('pagetitle',$pagetitle);
$newResource->set('longtitle',$longtitle);
$newResource->set('description',$description);
$newResource->set('introtext',$introtext);
$newResource->set('content',$content);
$newResource->set('menutitle',$menutitle);
$newResource->set('template',$template);
$newResource->set('isfolder',$isfolder);
$newResource->set('hidemenu',$hidemenu);
$newResource->set('parent',$parent);
$newResource->set('published',$published);
$newResource->set('alias',$parent.date('YmdHis'));
if ($published) $newResource->set('publishedon',$publishedon);


// Сохраняем ресурс
if ($newResource->save()) {
  $id = $newResource->get('id');
  $newResource->set('alias',$prefix.$id);
  $newResource->save();
// Очищаем кеш, чтобы изменения были видны сразу
  $modx->cacheManager->refresh();
  return $id;
} 

return false;

Сниппет tv

Сниппет tv

<?php
if ($input) {
  // Либо выводим значение TV по id документа
  $q = $modx->newQuery('modTemplateVarResource');
  $q->select(array('value',
		   'tmplvarid',
		   'contentid'))->where(array('tmplvarid'=>$options,
					      'contentid'=>$input));	
  $r = $modx->getObject('modTemplateVarResource', $q);
  
  return $r->value;
  
} else {
  // либо устанавливаем значение TV
  if (!$id) {$id = $_POST['id'];}
  if (!$tv) $tv = $_POST['tv'];
  if (!$value) $value = $_POST['value'];
  if ($value == ' ') $value = '';
  
  if ($modx->getObject('modTemplateVarResource', array('contentid' => $id, 'tmplvarid' => $tv))) {
    $tvar = $modx->getObject('modTemplateVarResource', array('contentid' => $id, 'tmplvarid' => $tv));
    } else {
    $tvar = $modx->newObject('modTemplateVarResource');
    $tvar->set('contentid', $id);
    $tvar->set('tmplvarid', $tv);
  }
  
  $tvar->set('value', $value);
  
  $tvar->save();
  
}

После того, как пользователь подтвердил свой e-mail, направляем его на страничку редактирования информации о себе:

[[!FormIt? &hooks=`editUserPage` &successMessage=`Изменения сохранены`]]
[[$editPage]]

Соответственно, сниппет editUserPage

Сниппет editUserPage
Сниппет editUserPage

<?php
// Берем id ресурса из профиля пользователя
$id = $modx->user->getOne('Profile')->get('website');
$name = $_POST['name'];
if ($name == '') $name = ' ';

// И вносим изменения на страницу
if ($modx->runSnippet('editResource',array('resId' => $id, 'pagetitle' => $name, 'longtitle' => $name, 'menutitle' => $name, 'hidemenu' => 'show'))) {
foreach ($_POST as $key => $value) {
  switch ($key) {
    case 'com_address':  $tv = 2; break;
    case 'com_egrul': 	 $tv = 5; break;
    case 'com_email':	 $tv = 9; break;
    case 'com_federate': $tv = 4; break;
    case 'com_head':	 $tv = 10; break;
    case 'com_inn':	 $tv = 6; break;
    case 'com_kpp':	 $tv = 7; break;
    case 'com_phone':	 $tv = 3; break;
    case 'com_regon':	 $tv = 8; break;
    default: 		 $tv = 0; break;
  }
  if (!$value) $value = ' ';
  if ($tv) $modx->runSnippet('tv', array('id' => $id, 'tv' => $tv, 'value' => $value));
}
// Очищаем кеш, чтобы изменения были видны сразу
$modx->cacheManager->refresh();
return true;
}

Создаем статьи или события пользователя

Пусть у нас пользователи могут добавлять на свою страничку предстоящие и прошедшие события:

[[!FormIt? &hooks=`addEvent` &successMessage=`Изменения сохранены` &submitVar=`addEvent`]]
[[$addEventForm]]
Сниппет addEvent

Сниппет addEvent

<?php
// События будут дочерними ресурсами страницы пользователя
$parent = $modx->user->getOne('Profile')->get('website');
$name = $_POST['name'];
$date = explode('.',$_POST['event_date']);
$publishedon = $date[2]."-".$date[1]."-".$date[0]." 10:00:00";
$introtext = $_POST['description'];
if ($id = $modx->runSnippet('addResource',array('pagetitle' => $name, 'longtitle' => $name, 'introtext' => $introtext, 'menutitle' => $name, 'published' => 1, 'publishedon' => $publishedon, 'parent' => $parent, 'template' => 4, 'isfolder' => 1))) {

// Заполняем любые параметры события, которые нам нужны
foreach ($_POST as $key => $value) {
  switch ($key) {
    case 'event_address': 		$tv = 14; break;
    case 'event_type':			$tv = 12; break;
    case 'event_org':			$tv = 34; break;
    case 'event_peoples':		$tv = 24; break;
    default: 		  			$tv = 0; break;
  }
  if (!$value) $value = ' ';
  if ($tv) $modx->runSnippet('tv', array('id' => $id, 'tv' => $tv, 'value' => $value));
}

$modx->cacheManager->refresh();

// Переадресовываем на просмотр события
$url = "/companies/id".$parent."/event".$id;
header('location: '.$url); exit;
return true;
}

В итоге

На нашем сайте пользователи могут зарегистрироваться, разместить информацию о себе, создавать события или писать статьи.

Что я планирую с этим делать

Дальше я планирую сделать для пользователей возможность загрузки фотографий, добавить функционал для отправки и чтения личных сообщений, как писал об этом Goobs, а так же возможность пользователей регистрироваться на понравившиеся события.

Автор: ilyautkin

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js