You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							88 lines
						
					
					
						
							2.5 KiB
						
					
					
				
			
		
		
	
	
							88 lines
						
					
					
						
							2.5 KiB
						
					
					
				<?php | 
						|
 | 
						|
namespace common\modules\blog\urls; | 
						|
 | 
						|
use common\modules\blog\repositories\read\BlogPostReadRepository; | 
						|
use yii\base\BaseObject; | 
						|
use yii\caching\Cache; | 
						|
use yii\caching\TagDependency; | 
						|
use yii\web\UrlNormalizerRedirectException; | 
						|
use yii\web\UrlRuleInterface; | 
						|
use InvalidArgumentException; | 
						|
 | 
						|
class BlogMainUrlRule extends BaseObject implements UrlRuleInterface | 
						|
{ | 
						|
	public $prefix = 'blog/post'; | 
						|
 | 
						|
    private $repository; | 
						|
    private $cache; | 
						|
 | 
						|
    public function __construct(BlogPostReadRepository $repository, Cache $cache, $config = []) | 
						|
    { | 
						|
        parent::__construct($config); | 
						|
        $this->repository = $repository; | 
						|
        $this->cache = $cache; | 
						|
    } | 
						|
 | 
						|
    public function parseRequest($manager, $request) | 
						|
    { | 
						|
	    if (preg_match('#^' . $this->prefix . '/(.*[a-z])$#is', $request->pathInfo, $matches)) { | 
						|
		    $path = $matches['1']; | 
						|
 | 
						|
		    $result = $this->cache->getOrSet( [ 'blog_main_route', 'path' => $path ], function () use ( $path ) { | 
						|
			    if ( ! $post = $this->repository->findBySlug($this->getPathSlug( $path ) ) ) { | 
						|
				    return [ 'id' => null, 'path' => null ]; | 
						|
			    } | 
						|
			    return [ 'id' => $post->id, 'path' => $post->slug ]; | 
						|
		    }, null, new TagDependency(['tags' => ['blog']]) ); | 
						|
 | 
						|
		    if ( empty( $result['id'] ) ) { | 
						|
			    return false; | 
						|
		    } | 
						|
 | 
						|
		    if ( $path != $result['path'] ) { | 
						|
			    throw new UrlNormalizerRedirectException( [ 'blog/post/post', 'id' => $result['id'] ], 301 ); | 
						|
		    } | 
						|
 | 
						|
		    return ['blog/post/post', ['id' => $result['id']]]; | 
						|
	    } | 
						|
	    return false; | 
						|
    } | 
						|
 | 
						|
    public function createUrl($manager, $route, $params) | 
						|
    { | 
						|
        if ($route == 'blog/post/post') { | 
						|
	        if (empty($params['id'])) { | 
						|
		        throw new InvalidArgumentException('Empty id.'); | 
						|
	        } | 
						|
	        $id = $params['id']; | 
						|
 | 
						|
            $url = $this->cache->getOrSet(['post_main_route', 'id' => $id], function () use ($id) { | 
						|
                if (!$post = $this->repository->find($id)) { | 
						|
                    return null; | 
						|
                } | 
						|
                return $post->slug; | 
						|
            }, null, new TagDependency(['tags' => ['blog']])); | 
						|
 | 
						|
            if (!$url) { | 
						|
            	return '#'; | 
						|
                //throw new InvalidArgumentException('Undefined id.'); | 
						|
            } | 
						|
 | 
						|
	        $url = $this->prefix . '/' . $url; | 
						|
	        unset($params['id']); | 
						|
	        if (!empty($params) && ($query = http_build_query($params)) !== '') { | 
						|
		        $url .= '?' . $query; | 
						|
	        } | 
						|
 | 
						|
	        return $url; | 
						|
        } | 
						|
        return false; | 
						|
    } | 
						|
 | 
						|
	private function getPathSlug($path): string | 
						|
	{ | 
						|
		$chunks = explode('/', $path); | 
						|
		return end($chunks); | 
						|
	} | 
						|
} |