导图 1
news-OA-uml
  Adapter
    INewsAdapter.class.php
      extends
        IEnableAbleAdapter
        ITopAbleAdapter
        IFetchAbleAdapter
        IAsyncAdapter
    NewsRestfulAdapter.class.php
      extends
        GuzzleAdapter
      implements
        INewsAdapter
      use
        EnableAbleRestfulAdapterTrait
        AsyncFetchAbleRestfulAdapterTrait
        FetchAbleRestfulAdapterTrait
        TopAbleRestfulAdapterTrait
      parameter
        $translator
          private
        $resource
          private
        const SCENARIOS = [
'NEWS_LIST'=>[
'fields'=>[
'news'=>'title,source,updateTime,status,category,stick',
'crews'=>'name'
],
'include'=>'crew'
],
'NEWS_FETCH_ONE'=>[
'fields'=>['crews'=>'name'],
'include'=>'crew'
]
];
      method
        public function __construct()
          parent::__construct(Core::$container->get('services.backend.url'))
          $this->translator = new NewsRestfulTranslator();
          $this->resource = 'news';
          $this->scenario = array();
        protected function getTranslator() : Translator
          return $this->translator;
        protected function getResource() : string
          return $this->resource;
        public function scenario($scenario) : void
          $this->scenario = isset(self::SCENARIOS[$scenario]) ? self::SCENARIOS[$scenario] : array();
        public function fetchOne($id)
          return $this->fetchOneAction($id, new NullNews());
        public function add(News $news) : bool
          $data = $this->getTranslator()->objectToArray(
$news,
array('title', 'source', 'content', 'image', 'attachments', 'category', 'crew', 'description')
);
          $this->post(
$this->getResource(),
$data
);
          if ($this->isSuccess())
            $this->translateToObject($news);
            return true;
            }
          return false;
        public function edit(News $news) : bool
          $data = $this->getTranslator()->objectToArray(
$news,
array('title', 'source', 'content', 'image', 'attachments', 'category','crew', 'description')
)
          $this->patch(
$this->getResource().'/'.$news->getId(),
$data
);
          if ($this->isSuccess())
            $this->translateToObject($news);
            return true;
          return false;
  Command
    AddNewsCommand.class.php
      implements
        ICommand
      parameter
        $title
        $source
        $description
        $content
        $image
        $attachments
        $category
        $id
      method
        public function __construct(
string $title,
string $source,
string $description,
string $content,
string $image,
array $attachments = array(),
int $category = 0,
int $id = 0
)
          $this->title = $title;
          $this->source = $source;
          $this->description = $description;
          $this->content = $content;
          $this->image = $image;
          $this->attachments = $attachments;
          $this->category = $category;
          $this->id = $id;
    EditNewsCommand.class.php
      implements
        ICommand
      parameter
        $title
        $source
        $description
        $content
        $image
        $attachments
        $category
        $id
      method
        public function __construct(
string $title,
string $source,
string $description,
string $content,
string $image,
array $attachments = array(),
int $category = 0,
int $id = 0
)
          $this->title = $title;
          $this->source = $source;
          $this->description = $description;
          $this->content = $content;
          $this->image = $image;
          $this->attachments = $attachments;
          $this->category = $category;
          $this->id = $id;
    EnableNewsCommand.class.php
      extends
        EnableCommand
      implements
        ICommand
    DisableNewsCommand.class.php
      extends
        DisableCommand
      implements
        ICommand
    TopNewsCommand.class.php
      extends
        TopCommand
      implements
        ICommand
    CancelTopNewsCommand.class.php
      extends
        CancelTopCommand
      implements
        ICommand
  CommandHandler
    AddNewsCommandHandler.class.php
      implements
        ICommandHandler
        ILogable
      parameter
        $news
          private
      method
        public function __construct()
          $this->news = new News();
        public function __destruct()
          unset($this->news);
        protected function getNews() : News
          return $this->news;
        public function execute(ICommand $command)
          return $this->executeAction($command);
        protected function executeAction($command)
          if (!($command instanceof AddNewsCommand))
            throw new \InvalidArgumentException;
          $news = $this->getNews();
          $news->setTitle($command->title);
          $news->setSource($command->source);
          $news->setDescription($command->description);
          $news->setContent($command->content);
          $news->setImage($command->image);
          $news->setAttachments($command->attachments);
          $news->setCategory(CategoryModelFactory::create($command->category, TYPE['NEWS_CATEGORY_CN']));
          return $news->add();
        public function getLog() : Log
    EditNewsCommandHandler.class.php
      implements
        ICommandHandler
        ILogable
      parameter
        $repository
        $news
      method
        public function __construct()
          $this->repository = new NewsRepository();
          $this->news = new NullNews();
        public function __destruct()
          unset($this->repository);
          unset($this->news);
        protected function getRepository() : NewsRepository
          return $this->repository;
        protected function getNews() : News
          return $this->news;
        protected function fetchNews($id) : News
          return $this->getRepository()->fetchOne($id);
        public function execute(ICommand $command)
          return $this->executeAction($command);
        protected function executeAction($command)
          if (!($command instanceof EditNewsCommand))
            throw new \InvalidArgumentException;
          $this->news = $this->fetchNews($command->id);
          $this->news->setTitle($command->title);
          $this->news->setSource($command->source);
          $this->news->setDescription($command->description);
          $this->news->setContent($command->content);
          $this->news->setImage($command->image);
          $this->news->setAttachments($command->attachments);
          return $this->news->edit();
        public function getLog() : Log
    EnableNewsCommandHandler.class.php
      extends
        EnableCommandHandler
      implements
        ICommandHandler
        ILogable
      parameter
        $repository
        $enableAble
      method
        public function __construct()
          $this->repository = new NewsRepository();
          $this->enableAble = new NullNews();
        public function __destruct()
          unset($this->repository);
          unset($this->enableAble);
        protected function getRepository() : NewsRepository
          return $this->repository;
        protected function getEnableAble() : IEnableAble
          return $this->enableAble;
        protected function fetchIEnableObject($id) : IEnableAble
          return $this->getRepository()->scenario(NewsRepository::FETCH_ONE_MODEL_UN)->fetchOne($id);
        public function getLog() : Log
    DisableNewsCommandHandler.class.php
      extends
        DisableCommandHandler
      implements
        ICommandHandler
        ILogable
      parameter
        $repository
        $enableAble
      method
        public function __construct()
          $this->repository = new NewsRepository();
          $this->enableAble = new NullNews();
        public function __destruct()
          unset($this->repository);
          unset($this->enableAble);
        protected function getEnableAble() : IEnableAble
          return $this->enableAble;
        protected function getRepository() : NewsRepository
          return $this->repository;
        protected function fetchIEnableObject($id) : IEnableAble
          return $this->getRepository()->scenario(NewsRepository::FETCH_ONE_MODEL_UN)->fetchOne($id);
        public function getLog() : Log
    TopNewsCommandHandler.class.php
      extends
        TopCommandHandler
      implements
        ICommandHandler
        ILogable
      parameter
        $repository
          private
        $topAble
          protected
      method
        public function __construct()
          $this->repository = new NewsRepository();
          $this->topAble = new NullNews();
        public function __destruct()
          unset($this->repository);
          unset($this->topAble);
        protected function getRepository() : NewsRepository
          return $this->repository;
        protected function getTopAble() : ITopAble
          return $this->topAble;
        protected function fetchITopObject($id) : ITopAble
        return $this->getRepository()->scenario(NewsRepository::FETCH_ONE_MODEL_UN)->fetchOne($id);
        public function getLog() : Log
    CancelTopNewsCommandHandler.class.php
      extends
        CancelTopCommandHandler
      implements
        ICommandHandler
        ILogable
      parameter
        $repository
          private
        $topAble
          protected
      method
        public function __construct()
          $this->repository = new NewsRepository();
          $this->topAble = new NullNews();
        public function __destruct()
          unset($this->repository);
          unset($this->topAble);
        protected function getTopAble() : ITopAble
          return $this->topAble;
        protected function getRepository() : NewsRepository
          return $this->repository;
        protected function fetchITopObject($id) : ITopAble
          return $this->getRepository()->scenario(NewsRepository::FETCH_ONE_MODEL_UN)->fetchOne($id);
        public function getLog() : Log
    NewsCommandHandlerFactory.class.php
      implements
        ICommandHandlerFactory
      parameter
        const MAPS = array(
'News\Command\News\AddNewsCommand'=>'News\CommandHandler\News\AddNewsCommandHandler',
'News\Command\News\CancelTopNewsCommand'=>'News\CommandHandler\News\CancelTopNewsCommandHandler',
'News\Command\News\EditNewsCommand'=>'News\CommandHandler\News\EditNewsCommandHandler',
'News\Command\News\DisableNewsCommand'=>'News\CommandHandler\News\DisableNewsCommandHandler',
'News\Command\News\EnableNewsCommand'=>'News\CommandHandler\News\EnableNewsCommandHandler',
'News\Command\News\TopNewsCommand'=>'News\CommandHandler\News\TopNewsCommandHandler'
);
      method
        public function getHandler(ICommand $command) : ICommandHandler
          $commandClass = get_class($command);
          $commandHandler = isset(self::MAPS[$commandClass]) ? self::MAPS[$commandClass] : '';
          return class_exists($commandHandler) ? new $commandHandler : new NullCommandHandler();
  Controller
    EnableController.class.php
      extends
        Controller
      implements
        IEnableAbleController
      use
        EnableControllerTrait
      parameter
        $commandBus
          private
      method
        public function __construct()
          parent::__construct();
          $this->commandBus = new CommandBus(new NewsCommandHandlerFactory());
        public function __destruct()
          parent::__destruct();
          unset($this->commandBus);
        protected function getCommandBus() : CommandBus
          return $this->commandBus;
        protected function enableAction(int $id) : bool
          return $this->getCommandBus()->send(new EnableNewsCommand($id));
        protected function disableAction(int $id) : bool
          return $this->getCommandBus()->send(new DisableNewsCommand($id));
    FetchController.class.php
      extends
        Controller
      implements
        IFetchAbleController
      use
        FetchControllerTrait;
      parameter
        $repository
        $news
        $newsInputWidgetRules
      method
        public function __construct()
          parent::__construct();
          $this->repository = new NewsRepository();
          $this->news = new News();
          $this->newsInputWidgetRules = new NewsInputWidgetRules();
        public function __destruct()
          parent::__destruct();
          unset($this->repository);
          unset($this->news);
          unset($this->newsInputWidgetRules);
        protected function getRepository() : NewsRepository
          return $this->repository;
        protected function getNewsInputWidgetRules() : NewsInputWidgetRules
          return $this->newsInputWidgetRules;
        protected function getNews() : News
          return $this->news;
        protected function filterAction()
          $sort = $this->getRequest()->get('sort', array());
          $category = $this->getRequest()->get('category', '');
          $category = marmot_decode($category);
          $search = $this->getRequest()->get('search', array());
          $scene = $this->getRequest()->get('scene', '');
          $scene = marmot_decode($scene);
          if (!in_array($scene, IFetchAbleController::LIST_SCENE))
            Core::setLastError(ROUTE_NOT_EXIST);
            return false;
          if (!$this->validateFilterScenario($category))
            Core::setLastError(ROUTE_NOT_EXIST);
            return false;
          list($size,$page) = $this->getPageAndSize();
          list($filter, $sort) = $this->filterFormatChange($sort, $search, $scene, $category);
          $newsList = array();
          list($count, $newsList) =$this->getRepository()->scenario(NewsRepository::LIST_MODEL_UN)->search($filter, $sort, $page, $size);
          $this->getResponse()->view(new NewsListView($newsList, $count))->render();
          return true;
        protected function validateFilterScenario($category) : bool
          return $this->getNewsInputWidgetRules()->category($category);
        protected function filterFormatChange($sort, $search, $scene, $category)
          $sort = ['-updateTime'];
          $filter = array();
          $filter['category'] = $category;
          if (!empty($search[0]))
            $filter['title'] = $search[0];
          if ($scene == self::LIST_SCENE['MY_LIST'])
            $filter['crew'] = Core::$container->get('user')->getCrew()->getId();
          return [$filter, $sort];
        protected function fetchOneAction(int $id)
          if (empty($id))
            Core::setLastError(RESOURCE_NOT_EXIST);
            return false;
          $news = $this->getRepository()->scenario(NewsRepository::FETCH_ONE_MODEL_UN)->fetchOne($id);
          if ($news instanceof INull)
            Core::setLastError(RESOURCE_NOT_EXIST);
            return false;
          $this->getResponse()->view(new NewsView($news))->render();
          return true;
    OperationController.class.php
      extends
        Controller
      implements
        IOperatAbleController
      use
        OperatControllerTrait
      parameter
        $commandBus
        $commonInputWidgetRules
        $newsInputWidgetRules
        $repository
      method
        public function __construct()
          parent::__construct();
          $this->commandBus = new CommandBus(new NewsCommandHandlerFactory());
          $this->commonInputWidgetRules = new CommonInputWidgetRules();
          $this->newsInputWidgetRules = new NewsInputWidgetRules();
          $this->repository = new NewsRepository();
        protected function getCommandBus() : CommandBus
          return $this->commandBus;
        protected function getCommonInputWidgetRules() : CommonInputWidgetRules
          return $this->commonInputWidgetRules;
        protected function getNewsInputWidgetRules() : NewsInputWidgetRules
          return $this->newsInputWidgetRules;
        protected function getRepository() : NewsRepository
          return $this->repository;
        protected function addView() : bool
          Core::setLastError(ROUTE_NOT_EXIST);
          $this->displayError();
          return false;
        protected function addAction()
          $request = $this->getRequest();
          $title = $request->post('title', '');
          $source = $request->post('source', '');
          $description = $request->post('description', '');
          $content = $request->post('content', '');
          $image = $request->post('image', '');
          $attachments = $request->post('attachments', array());
          $category = $request->post('category', '');
          $category = marmot_decode($category);
          if ($this->validateAddScenario(
$title,
$source,
$content,
$image,
$category,
$attachments
))
            $command = new AddNewsCommand(
$title,
$source,
$description,
$content,
$image,
$attachments,
$category
);
            if ($this->getCommandBus()->send($command))
              $this->displaySuccess();
              return true;
          $this->displayError();
          return false;
        protected function validateAddScenario(
$title,
$source,
$content,
$image,
$category,
$attachments
) : bool
          return $this->getCommonInputWidgetRules()->title($title)
          && $this->getCommonInputWidgetRules()->source($source)
          && $this->getCommonInputWidgetRules()->content($content)
          && (empty($image) ? true : $this->getCommonInputWidgetRules()->image($image, 'image'))
          && $this->getNewsInputWidgetRules()->category($category)
          && $this->getCommonInputWidgetRules()->attachments($attachments);
        protected function validateEditScenario(
$title,
$source,
$image,
$attachments
) : bool
          return $this->getCommonInputWidgetRules()->title($title)
          && $this->getCommonInputWidgetRules()->source($source)
          && (empty($image) ? true : $this->getCommonInputWidgetRules()->image($image, 'image'))
          && $this->getCommonInputWidgetRules()->attachments($attachments);
        protected function editView(int $id) : bool
          $news = $this->getRepository()->scenario(NewsRepository::FETCH_ONE_MODEL_UN)->fetchOne($id);
          if ($news instanceof INull)
            Core::setLastError(RESOURCE_NOT_EXIST);
            return false;
          $this->getResponse()->view(new NewsView($news))->render();
          return true;
        protected function editAction(int $id)
          $title = $this->getRequest()->post('title', '');
          $source = $this->getRequest()->post('source', '');
          $description = $this->getRequest()->post('description', '');
          $content = $this->getRequest()->post('content', '');
          $image = $this->getRequest()->post('image', '');
          $attachments = $this->getRequest()->post('attachments', array());
          if ($this->validateEditScenario(
$title,
$source,
$image,
$attachments
))
            $command = new EditNewsCommand(
$title,
$source,
$content,
$description,
$image,
$attachments,
$id
);
            if ($this->getCommandBus()->send($command))
              $this->displaySuccess();
              return true;
          $this->displayError();
          return false;
    TopController.class.php
      extends
        Controller
      implements
        ITopAbleController
      use
        TopControllerTrait
      parameter
        $commandBus
          private
      method
        public function __construct()
          parent::__construct();
          $this->commandBus = new CommandBus(new NewsCommandHandlerFactory());
        public function __destruct()
          parent::__destruct();
          unset($this->commandBus);
        protected function getCommandBus() : CommandBus
          return $this->commandBus;
        protected function topAction(int $id) : bool
          return $this->getCommandBus()->send(new TopNewsCommand($id));
        protected function cancelTopAction(int $id) : bool
          return $this->getCommandBus()->send(new CancelTopNewsCommand($id));
  Model
    CategoryModelFactory.class.php
      parameter
        const NEWS_CATEGORY_CN = array(
'1'=>'通知通告',
'2'=>'调查研究',
'3'=>'政策法规',
'4'=>'办事指南',
);
        const NEWS_CATEGORY = array(
'NOTICE_ANNOUNCEMENT' => 1,
'INVESTIGATION_RESEARCH' => 2,
'POLICY_STATUTE' => 3,
'WORK_GUIDE' => 4,
);
      method
        public static function create(int $id, $type) : NewsCategory
          $type = self::NEWS_CATEGORY_CN;
          return in_array($id, array_keys($type))
          ? new NewsCategory($id, $type[$id])
          : new NullNewsCategory(0, '');
    News.class.php
      implements
        IEnableAble
        ITopAble
        IOperatAble
        IObject
      use
        EnableAbleTrait
        TopAbleTrait
        OperatAbleTrait
        Object
      parameter
        $id
        $title
        $source
        $description
        $content
        $attachments
        $image
        $crew
        $category
        $stick
        $repository
      method
        public function __construct(int $id = 0)
          $this->id = !empty($id) ? $id : 0;
          $this->title = '';
          $this->source = '';
          $this->description = '';
          $this->content = '';
          $this->category = NullNewsCategory::getInstance();
          $this->attachments = array();
          $this->image = array();
          $this->crew = Core::$container->has('user') ? Core::$container->get('user') : new Crew();
          $this->statusTime = 0;
          $this->createTime = 0;
          $this->updateTime = 0;
          $this->status = IEnableAble::STATUS['ENABLED'];
          $this->stick = ITopAble::STICK['CANCELTOP'];
          $this->repository = new NewsRepository();
        public function __destruct()
    NewsCategory.class.php
      extends
        Category
    NullNews.class.php
      extends
        News
      implements
        INull
      parameter
        $instance
          private static
      method
        public function add() : bool
          return $this->resourceNotExist();
        public function edit() : bool
          return $this->resourceNotExist();
        private function resourceNotExist() : bool
          Core::setLastError(RESOURCE_NOT_EXIST);
          return false;
  Repository
    NewsRepository.class.php
      implements
        INewsAdapter
      use
        FetchRepositoryTrait
        AsyncRepositoryTrait
        EnableAbleRepositoryTrait
        TopAbleRepositoryTrait
      parameter
        $adapter
          private
        const LIST_MODEL_UN = 'NEWS_LIST';
        const FETCH_ONE_MODEL_UN = 'NEWS_FETCH_ONE';
      method
        public function __construct()
          $this->adapter = new NewsRestfulAdapter();
        protected function getAdapter()
          return $this->adapter;
        public function scenario($scenario)
          $this->getAdapter()->scenario($scenario);
          return $this;
        public function add(News $news) : bool
          return $this->getAdapter()->add($news);
        public function edit(News $news) : bool
          return $this->getAdapter()->edit($news);
  Translator
    NewsCategoryTranslator.class.php
      extends
        CategoryTranslator
      method
        public function arrayToObject(array $expression, $category = null)
          unset($category);
          unset($expression);
          return new NullNewsCategory(0, '');
    NewsRestfulTranslator.class.php
      extends
        Translator
      use
        RestfulTranslatorTrait
      method
        protected function getCrew() : Crew
          return new Crew();
        public function arrayToObject(array $expression, $news = null)
          return $this->translateToObject($expression, $news);
        protected function translateToObject(array $expression, $news = null)
          if (empty($expression))
            return new NullNews();
          if ($news == null)
            $news = new News();
          $data = $expression['data'];
          $id = $data['id'];
          $news->setId($id);
          $attributes = isset($data['attributes']) ? $data['attributes'] : '';
          if (isset($attributes['title']))
            $news->setTitle($attributes['title']);
          if (isset($attributes['source']))
            $news->setSource($attributes['source'])
          if (isset($attributes['description']))
            $news->setDescription($attributes['description'])
          if (isset($attributes['content']))
            $news->setContent($attributes['content']);
          if (isset($attributes['category']))
            $news->setCategory(CategoryModelFactory::create($attributes['category'], TYPE['NEWS_CATEGORY_CN']));
          if (isset($attributes['image']))
            $news->setImage($attributes['image']);
          if (isset($attributes['attachments']))
            $news->setAttachments($attributes['attachments']);
          if (isset($attributes['status']))
            $news->setStatus($attributes['status']);
          if (isset($attributes['stick']))
            $news->setStick($attributes['stick']);
          if (isset($attributes['statusTime']))
            $news->setStatusTime($attributes['statusTime']);
          $relationships = isset($data['relationships']) ? $data['relationships'] : array();
          if (isset($expression['included']))
            $relationships = $this->relationship($expression['included'], $relationships);
          return $news;
        public function objectToArray($news, array $keys = array())
          if (!$news instanceof News)
            return array();
          if (empty($keys))
            $keys = array(
'id',
'title',
'source',
'content',
'category',
'description',
'image',
'attachments',
'crew'
);
          $expression = array('data'=>array('type'=>'news'));
          if (in_array('id', $keys))
            $expression['data']['id'] = $news->getId();
          $attributes = array();
          if (in_array('title', $keys))
            $attributes['title'] = $news->getTitle();
          if (in_array('source', $keys))
            $attributes['source'] = $news->getSource();
          if (in_array('description', $keys))
            $attributes['description'] = $news->getDescription();
          if (in_array('content', $keys))
            $attributes['content'] = $news->getContent();
          if (in_array('category', $keys))
            $attributes['category'] = $news->getCategory()->getId();
          if (in_array('image', $keys))
            $attributes['image'] = $news->getImage();
          if (in_array('attachments', $keys))
            $attributes['attachments'] = $news->getAttachments();
          $expression['data']['attributes'] = $attributes;
          if (in_array('crew', $keys))
            $expression['data']['relationships']['applyCrew']['data'] = array(
array(
'type' => 'crews',
'id' => $news->getCrew()->getId()
)
);
          return $expression;
    NewsTranslator.class.php
      extends
        Translator
      method
        public function arrayToObject(array $expression, $news = null)
          unset($news);
          unset($expression);
          return new NullNews();
        public function arrayToObjects(array $expression) : array
          unset($expression);
          return array();
        protected function getNewsCategoryTranslator() : NewsCategoryTranslator
          return new NewsCategoryTranslator();
        public function objectToArray($news, array $keys = array())
          if (!$news instanceof News)
            return array();
          if (empty($keys))
            $keys = array(
'id',
'title',
'source',
'createTime',
'updateTime',
'status',
'content',
'category'=>[],
'description',
'image',
'attachments',
'stick',
'crew'=>['id', 'name']
);
          $expression = array();
          if (in_array('id', $keys))
            $expression['id'] = marmot_encode($news->getId());
          if (in_array('title', $keys))
            $expression['title'] = $news->getTitle();
          if (in_array('source', $keys))
            $expression['source'] = $news->getSource();
          if (in_array('createTime', $keys))
            $expression['createTime'] = $news->getCreateTime();
          if (in_array('updateTime', $keys))
            $expression['updateTime'] = $news->getUpdateTime();
          if (in_array('status', $keys))
            $expression['status'] = $news->getStatus();
          if (in_array('stick', $keys))
            $expression['stick'] = $news->getStick();
          if (in_array('content', $keys))
            $expression['content'] = Filter::dhtmlspecialchars($news->getContent());
          if (in_array('description', $keys))
            $expression['description'] = $news->getDescription();
          if (isset($keys['category']))
            $expression['category'] = $this->getNewsCategoryTranslator()->objectToArray(
$news->getCategory(),
$keys['category']
);
          if (in_array('image', $keys))
            $expression['image'] = $news->getImage();
          if (in_array('attachments', $keys))
            $expression['attachments'] = $news->getAttachments();
          return $expression;