php.de

Zurück   php.de > Webentwicklung > Software-Design

Software-Design Diskussionen auf Profi-Niveau: PHP Lösungen auf konzeptioneller Ebene

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 01.09.2011, 15:45  
Erfahrener Benutzer
 
Registriert seit: 10.02.2009
Beiträge: 929
ragtek ist ein sehr geschätzer Menschragtek ist ein sehr geschätzer Menschragtek ist ein sehr geschätzer Menschragtek ist ein sehr geschätzer Mensch
Standard Modellaufbau

Gibt es eigentlich einen Namen für den Modelaufbau, wenn die Models "KEINE" Properties haben, sondern "alles" über Methodenparameter und den Controller geregelt wird?


zB:
Controller
PHP-Code:
$addonModel = new Foo();
$addons $addonModel->getAll();
$addonModel->dprepareAll($addons);


$smilies $smilieModel->getAllSmilies();
$smiliesModel->validate($smilies);
        
$viewParams = array(
            
'smilies' => $smilieModel->prepareSmiliesForList($smilies)
        );
// anstatt


$smilesModel->prepareSmilesForList() // und die Methode liest dann alle Smiles aus und verarbeitet alles andere 
ragtek ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 01.09.2011, 15:47  
Erfahrener Benutzer
 
Registriert seit: 30.07.2008
Beiträge: 1.169
PHP-Kenntnisse:
Fortgeschritten
xm22 sorgt für eine eindrucksvolle Atmosphärexm22 sorgt für eine eindrucksvolle Atmosphärexm22 sorgt für eine eindrucksvolle Atmosphäre
Standard

Ja - umständlich und wahrscheinlich nicht OOP entsprechend.
xm22 ist offline   Mit Zitat antworten
Alt 01.09.2011, 23:42  
Moderator
 
Benutzerbild von Chriz
 
Registriert seit: 11.05.2008
Beiträge: 6.269
Chriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer Anblick
Standard

Statische Klasse? Das ist halt Zustandslosigkeit mit Objekten. Davon willst du ja eher weg.

Ich benutz allerdings auch wenige Properties, hoechstens halt die Datenbankverbindung und ggf. Caching fuer schwere Methoden. Wobei das wohl eigentlich auch nicht Aufgabe des Models ist.

Mach doch mal ein konkreteres Beispiel und stell beide Vorgehensweisen hier gegenueber. Ich kann gerade wenig mit deinem Beispiel anfangen. Warum validierst du bspw. Smilies, die aus dem Model kommen? Speicherst du auch ungueltige Models? Leg das automatische validieren doch einfach ueber einen Parameter beim getter fest ..
__________________
"Nuschel ich?" - "Was?"
Chriz ist offline   Mit Zitat antworten
Alt 02.09.2011, 08:26  
Benutzer
 
Registriert seit: 25.01.2011
Beiträge: 59
PHP-Kenntnisse:
Fortgeschritten
Renner befindet sich auf einem aufstrebenden Ast
Standard

Models ohne Properties? Und was speichern die?
Renner ist offline   Mit Zitat antworten
Alt 02.09.2011, 08:55  
Erfahrener Benutzer
 
Registriert seit: 10.02.2009
Beiträge: 929
ragtek ist ein sehr geschätzer Menschragtek ist ein sehr geschätzer Menschragtek ist ein sehr geschätzer Menschragtek ist ein sehr geschätzer Mensch
Standard

Konkretes Beispiel:

(Bitte den Code entschuldigen, der ist schon etwas älter, daher Chaus pur, aber es geht nur um den Aufbau

Controller
PHP-Code:
        $catArticleHelper $this->_getHelper();
        list(
$article$category) = $catArticleHelper->assertArticleValidAndViewable($nodeId);

        
$article $this->getArticleModel()->prepareArticle($article);

        
$perms $this->getArticleModel()->getPermissionBasedArticleFetchConditions($category);

        
#$perms['article_not'] =  $article['article_id'];
        
$limit = array('limit' => 10);
        
$otherArticles $this->getArticleModel()->getArticlesFromAuthor($article['user_id'], $perms$limit);

        
$canDelete $this->getArticleModel()->canDeleteArticle($article);
        
$params = array(
            
'nodeBreadCrumbs' => $this->getModelFromCache('XenForo_Model_Node')->getNodeBreadCrumbs($categorytrue),
            
'article' => $article,
            
'otherArticles' => $otherArticles,
            
'category' => $category,
            
'canDelete' => $canDelete,
            
'canLike' => $this->getArticleModel()->canLikeArticle($article$category),
            
'author' => $this->getArticleModel()->getAuthor($article),
            
'attachments' => $article['attachments'],

        ); 
model
PHP-Code:
<?php
class Ragtek_AS_Model_Article extends XenForo_Model
{
    const 
FETCH_USER 0x01;
    const 
FETCH_CATEGORY 0x02;
    const 
FETCH_AVATAR 0x08;  // TODO do we really need this?

    
public function canEditArticle($artice, array $nodePermissions null, array $viewingUser null)
    {
        
$this->standardizeViewingUserReferenceForNode($artice['node_id'], $viewingUser$nodePermissions);

        if (!
$viewingUser['user_id']) {
            return 
false;
        }
        
// CAN EDIT ALL
        
if (
            
XenForo_Permission::hasContentPermission($nodePermissions'canEditAll')
            OR
            (
$artice['user_id'] == $viewingUser['user_id'] &&
             
XenForo_Permission::hasContentPermission($nodePermissions'canEditOwn')
            )
        ) {
            return 
true;
        }
        return 
false;
    }

    public function 
canDeleteArticle($artice, array $nodePermissions null, array $viewingUser null)
    {
        
$this->standardizeViewingUserReferenceForNode($artice['node_id'], $viewingUser$nodePermissions);

        if (!
$viewingUser['user_id']) {
            return 
false;
        }

        if (
XenForo_Permission::hasContentPermission($nodePermissions'canDeleteAll')) {
            return 
true;
        }
        else if (
$artice['user_id'] == $viewingUser['user_id'] &&
                 
XenForo_Permission::hasContentPermission($nodePermissions'canDeleteOwn')) {
            return 
true;
        }
        return 
false;
    }


    public function 
getArticleFromId($articleId, array $fetchOptions = array())
    {
        
$joinOptions $this->prepareArticleFetchOptions($fetchOptions);
        
$query '
        SELECT  article.*
        ' 
$joinOptions['selectFields'] . '
        FROM ragtek_article AS article
        ' 
$joinOptions['joinTables'] . '
        WHERE article.article_id = ?
  '
;

        
$article $this->_getDb()->fetchRow($query$articleId);
        if (
$article AND $article['attach_count'] > 0) {
            
$article['attachments'] = $this->getArticleAttachments($articleId);
        }
        return 
$article;
    }


    public function 
getArticles(array $conditions = array(), array $fetchOptions = array())
    {
        
$whereConditions $this->prepareArticleConditions($conditions$fetchOptions);

        
$sqlClauses $this->prepareArticleFetchOptions($fetchOptions);
        
$limitOptions $this->prepareLimitFetchOptions($fetchOptions);

        
$query '
        SELECT article.*
                    ' 
$sqlClauses['selectFields'] . '
                FROM ragtek_article AS article
                ' 
$sqlClauses['joinTables'] . '
                WHERE ' 
$whereConditions '
                ' 
$sqlClauses['orderClause'];

        return 
$this->fetchAllKeyed($this->limitQueryResults(
                                        
$query$limitOptions['limit'], $limitOptions['offset']
                                    ), 
'article_id');
    }

    public function 
getPermissionBasedArticleFetchConditions(array $category, array $nodePermissions null, array $viewingUser null)
    {
        
$this->standardizeViewingUserReferenceForNode($category['node_id'], $viewingUser$nodePermissions);

        if (
XenForo_Permission::hasContentPermission($nodePermissions'canModerate')) {
            
$viewModerated true;
        }
        else if (
$viewingUser['user_id']) {
            
$viewModerated $viewingUser['user_id'];
        }
        else
        {
            
$viewModerated false;
        }

        return array(
            
'deleted' => XenForo_Permission::hasContentPermission($nodePermissions'canSeeDeletedArticles'),
            
'moderated' => $viewModerated
        
);
    }

    public function 
getArticlesFromCategory(array $category, array $fetchOptions = array())
    {
        
$conditions $this->getPermissionBasedArticleFetchConditions($category);
        
$conditions['node_id'] = $category['node_id'];
        return 
$this->getArticles($conditions$fetchOptions);

    }


    public function 
prepareArticleFetchOptions(array $fetchOptions)
    {
        
$selectFields '';
        
$joinTables '';
        
$orderBy '';

        if (!empty(
$fetchOptions['order'])) {
            
$orderBySecondary '';

            switch (
$fetchOptions['order'])
            {
                case 
'title':
                case 
'view_count':
                case 
'position':
                    
$orderBy 'article.' $fetchOptions['order'];
                    break;
                    
                default:
                    
$orderBy 'article.post_date';
            }
            if (!isset(
$fetchOptions['orderDirection']) || $fetchOptions['orderDirection'] == 'desc') {
                
$orderBy .= ' DESC';
            }
            else
            {
                
$orderBy .= ' ASC';
            }

            
$orderBy .= $orderBySecondary;
        }

        if (!empty(
$fetchOptions['join'])) {

            if (
$fetchOptions['join'] & self::FETCH_USER) {

                
$selectFields .= ',
                    user.* '
;
                
$joinTables .= '
                    LEFT JOIN xf_user AS user ON
                        (user.user_id = article.user_id)'
;
            }
            else if (
$fetchOptions['join'] & self::FETCH_AVATAR) {
                
$selectFields .= ',
                    user.avatar_date, user.gravatar'
;
                
$joinTables .= '
                    LEFT JOIN xf_user AS user ON
                        (user.user_id = article.user_id)'
;
            }

            if (
$fetchOptions['join'] & self::FETCH_CATEGORY) {
                
$selectFields .= ',
                    node.title AS node_title'
;
                
$joinTables .= '
                    INNER JOIN xf_node AS node ON
                        (node.node_id = article.node_id)'
;
            }
        }


        if (!empty(
$fetchOptions['permissionCombinationId'])) {
            
$selectFields .= ',
                permission.cache_value AS node_permission_cache'
;
            
$joinTables .= '
                LEFT JOIN xf_permission_cache_content AS permission
                    ON (permission.permission_combination_id = ' 
$this->_getDb()->quote($fetchOptions['permissionCombinationId']) . '
                        AND permission.content_type = \'node\'
                        AND permission.content_id = article.node_id)'
;
        }

        if (isset(
$fetchOptions['likeUserId']))
        {
            if (empty(
$fetchOptions['likeUserId']))
            {
                
$selectFields .= ',
                    0 AS like_date'
;
            }
            else
            {
                
$selectFields .= ',
                    liked_content.like_date'
;
                
$joinTables .= '
                    LEFT JOIN xf_liked_content AS liked_content
                        ON (liked_content.content_type = \'' 
Ragtek_AS_Constants::CONTENT_TYPE '\'
                            AND liked_content.content_id = article.article_id
                            AND liked_content.like_user_id = ' 
.$this->_getDb()->quote($fetchOptions['likeUserId']) . ')';
            }
        }

        

        return array(
            
'selectFields' => $selectFields,
            
'joinTables' => $joinTables,
            
'orderClause' => ($orderBy "ORDER BY $orderBy" '')
        );
    }

    public function 
prepareArticleConditions(array $conditions)
    {
        
$sqlConditions = array();
        
$db $this->_getDb();

        if (!empty(
$conditions['node_id'])) {
            
$sqlConditions[] = 'article.node_id = ' $db->quote($conditions['node_id']);
        }

        if (isset(
$conditions['user_id'])) {
            
$sqlConditions[] = 'article.user_id = ' $db->quote($conditions['user_id']);
        }

        if (isset(
$conditions['deleted']) || isset($conditions['moderated'])) {

            
$sqlConditions[] = $this->prepareStateLimitFromConditions($conditions'article''status');
        }

        if (isset(
$conditions['article_not'])){
            
$sqlConditions[] = 'article.article_id != ' $db->quote($conditions['article_not']);

        }

        return 
$this->getConditionsForClause($sqlConditions);
    }

    public function 
getArticlesByIds($ids, array $fetchOptions = array())
    {
        
$sqlClauses $this->prepareArticleFetchOptions($fetchOptions);
        
$query '
        SELECT article.*
                   ' 
$sqlClauses['selectFields'] . '
        FROM ragtek_article as article
         ' 
$sqlClauses['joinTables'] . '
        WHERE article.article_id IN (' 
$this->_getDb()->quote($ids) . ')';

        return 
$this->fetchAllKeyed($query'article_id');
    }

    public function 
prepareArticle(array &$article$getAttachments true)
    {
        if (
$getAttachments) {
            if (
$article['attach_count'] > 0) {
                
$attachments $this->getArticleAttachments($article['article_id']);

                
/** @var $attachModel XenForo_Model_Attachment */
                
$attachModel $this->getModelFromCache('XenForo_Model_Attachment');
                foreach (
$attachments AS $attachment) {
                    
$article['attachments'][$attachment['attachment_id']] = $attachModel->prepareAttachment($attachment);
                }
            }
            else {
                
$article['attachments'] = array();
            }
        }
        if (
$article['likes']){
            
$article['likeUsers'] = unserialize($article['like_users']);
        }
        
$article['visible'] = $this->isVisible($article);
        
$article['isModerated'] = $this->isModerated($article);
        
$article['canEdit'] = $this->canEditArticle($article);

        return 
$article;
    }


    public function 
canViewArticle(array $article, &$errorPhraseKey '', array $nodePermissions null, array $viewingUser null)
    {
        
$this->standardizeViewingUserReferenceForNode($article['node_id'], $viewingUser$nodePermissions);

        if (!
XenForo_Permission::hasContentPermission($nodePermissions'canView')) {
            return 
false;
        }

        if (
$this->isModerated($article)) {
            if (!
XenForo_Permission::hasContentPermission($nodePermissions'canModerate')) {
                if (!
$viewingUser['user_id'] || $viewingUser['user_id'] != $article['user_id']) {
                    return 
false;
                }
            }
        }
        else if (
$this->isDeleted($article)) {
            if (!
XenForo_Permission::hasContentPermission($nodePermissions'canSeeDeletedArticles')) {
                return 
false;
            }
        }
        return 
true;
    }

    public function 
isModerated(array $article)
    {
        return (
$article['status'] == Ragtek_AS_Constants::ARTICLE_STATUS_MODERATE);
    }

    public function 
isVisible(array $article)
    {
        return (
$article['status'] == Ragtek_AS_Constants::ARTICLE_STATUS_OPEN);
    }

    public function 
isDeleted(array $article){
        return (
$article['status'] == Ragtek_AS_Constants::ARTICLE_STATUS_DELETED);
    }


    public function 
getAuthor(array $article)
    {

        return array(
            
'user_id' => $article['user_id'],
            
'username' => $article['username']);
    }


    public function 
getArticleAttachments($articleId)
    {
        
/** @var $atModel XenForo_Model_Attachment */
        
$atModel $this->getModelFromCache('XenForo_Model_Attachment');
        return 
$atModel->getAttachmentsByContentId(Ragtek_AS_Constants::CONTENT_TYPE$articleId);
    }

    public function 
getArticlesFromAuthor($authorId, &$condition = array(), &$fetchOptions = array()){
        
$condition['user_id'] =  $authorId;
        return 
$this->getArticles($condition$fetchOptions);
    }

    public function 
canLikeArticle(array $article,array $category, &$errorPhraseKey '', array $nodePermissions null, array $viewingUser null)
    {
        
$this->standardizeViewingUserReferenceForNode($article['node_id'], $viewingUser$nodePermissions);

        if (!
$viewingUser['user_id'])
        {
            return 
false;
        }

        if (
$article['status'] != Ragtek_AS_Constants::ARTICLE_STATUS_OPEN)
        {
            return 
false;
        }

        if (
$article['user_id'] == $viewingUser['user_id']){
            
$errorPhraseKey 'liking_own_content_cheating';
            return 
false;
        }
        return 
XenForo_Permission::hasContentPermission($nodePermissions'like');
    }


    public function 
getArticleIdsInRange($start$limit)
    {
        
$db $this->_getDb();

        return 
$db->fetchCol($db->limit('
            SELECT article_id
            FROM ragtek_article
            WHERE article_id > ?
            ORDER BY article_id
        '
$limit), $start);
    }
}
So, wie man hier sieht, wird die ArtikelId dem Model jedesmal mit übergeben, was ja auch per Property möglich wäre => $articlemodel = new Model($articleId); (und genau darum geht es mir^^)
ragtek ist offline   Mit Zitat antworten
Alt 02.09.2011, 09:22  
Benutzer
 
Registriert seit: 25.01.2011
Beiträge: 59
PHP-Kenntnisse:
Fortgeschritten
Renner befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von ragtek Beitrag anzeigen
PHP-Code:
    public function getArticleFromId($articleId, array $fetchOptions = array())
    {
        
$joinOptions $this->prepareArticleFetchOptions($fetchOptions);
        
$query '
        SELECT  article.*
        ' 
$joinOptions['selectFields'] . '
        FROM ragtek_article AS article
        ' 
$joinOptions['joinTables'] . '
        WHERE article.article_id = ?
  '
;

        
$article $this->_getDb()->fetchRow($query$articleId);
        if (
$article AND $article['attach_count'] > 0) {
            
$article['attachments'] = $this->getArticleAttachments($articleId);
        }
        return 
$article;
    } 
Also mal ohne den Code zu bewerten (AND !!!!), sage ich dir, dass deine Modelklasse kein Model darstellt sondern einen Datenbankadapter. Das eigentliche Model besteht in dem Fall aus einem assoziativen Array ($article).
Renner ist offline   Mit Zitat antworten
Alt 02.09.2011, 14:09  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.994
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Ganz genau. Eine sehr unelegante Kiste, weil Array und „Model“ dabei nur per Konvention kompatibel sind.
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist offline   Mit Zitat antworten
Alt 02.09.2011, 14:41  
Erfahrener Benutzer
 
Registriert seit: 12.05.2005
Beiträge: 1.038
PHP-Kenntnisse:
Fortgeschritten
notyyy befindet sich auf einem aufstrebenden Ast
Standard

ich nutze für Datenstrukturen keinerlei Arrays mehr sondern lasse mir Klassen generieren.
Kanns nur empfehlen.
notyyy ist offline   Mit Zitat antworten
Alt 29.09.2011, 21:30  
Neuer Benutzer
 
Registriert seit: 15.03.2011
Beiträge: 7
PHP-Kenntnisse:
Anfänger
Gruber's Hans befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von notyyy Beitrag anzeigen
ich nutze für Datenstrukturen keinerlei Arrays mehr sondern lasse mir Klassen generieren.
Kanns nur empfehlen.
Warum?
Gruber's Hans ist offline   Mit Zitat antworten
Alt 29.09.2011, 23:47  
Erfahrener Benutzer
 
Benutzerbild von mermshaus
 
Registriert seit: 14.06.2009
Beiträge: 1.733
PHP-Kenntnisse:
Fortgeschritten
mermshaus kann auf vieles stolz seinmermshaus kann auf vieles stolz seinmermshaus kann auf vieles stolz seinmermshaus kann auf vieles stolz seinmermshaus kann auf vieles stolz seinmermshaus kann auf vieles stolz seinmermshaus kann auf vieles stolz seinmermshaus kann auf vieles stolz seinmermshaus kann auf vieles stolz sein
Standard

  • Type-Hinting. PHP stellt sicher, dass ein korrektes Objekt übergeben wird. Bei einem Array kann beispielsweise willkürlich ein notwendiges Feld nicht gesetzt sein.
  • Dokumentierte Schnittstellen. Wo liest du bei einem Array nach, welche Felder du setzen kannst/musst? Mit Type-Hinting weißt du, eine Instanz welcher Klasse übergeben werden muss. Die notwendigen „Felder“ kannst du in der Klassendefinition nachlesen.
  • Gültiger Zustand. Eine Klasse kann üblicherweise sicherstellen, dass alle Instanzdaten korrekt sind. Während dich niemand abhält, $myuser['age'] = -17; zu schreiben, kann $myuser->setAge(-17); eine Exception werfen.
__________________
Blog | Buch | Kaloa
mermshaus ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
liking_own_content_cheating

Alle Zeitangaben in WEZ +2. Es ist jetzt 01:38 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum