2014-02-13 2 views
0

구독이 곧 만료 될 때 경고 전자 메일을 보내는 Concrete5 플러그인을 수정하려고합니다. 먼저 통보 된 사용자를 필터링 한 다음 오늘의 구독이 만료 날짜 (expirationDate)에서 지정된 일 수 (emailOnExpirationDays)만큼 떨어진 사용자를 선택하여 작동합니다.Concrete5 필터 SQL

제 문제는 사용자에게 한 번이 아니라 3 번 알려줄 수 있어야한다는 것입니다. 30 일전, 5 일전 및 1 일전에 통보하고 싶습니다. 내 첫 번째 장애물은 5 일 이내에 고지 된 사용자 (의도적으로 25 일 전에 알리지 않은 사용자) 만 필터링하는 것입니다. 어떻게 이것을 달성하기 위해 아래의 PHP와 SQL을 수정할 수 있습니까? 주석 처리 된 코드는 내가 시도한 것입니다. 필터 기능에 대한 정보는 here입니다.

컬렉션은 여기 인스턴스화 :

$expiringTxns = new LMemTxnList(); 
$expiringTxns->filterByProductWithExpirationEmailsThatShouldBeWarned(); 

......

public function filterByProductWithExpirationEmailsThatShouldBeWarned() { 
    $this->setupProductExpirationQueries();//displays all with account 

    //we haven't already sent out an expiration warning or, for that matter, a notice 
    $this->filter('notifiedDate', null); 
    $this->filter('warnedDate', null); //Caitlin commented out to allow more than one warning 
    //$this->filter('warnedDate', '!= BETWEEN DATE_SUB(NOW(), INTERVAL 5 DAY) AND NOW()'); 


    // the emailOnExpirationDays has been properly configured 
    $this->filter('emailOnExpirationDays', null, '!='); 
    $this->filter('emailOnExpirationDays', 0, '>'); 

    //the expirationDate - warning is between 5 days ago (don't want to send a bunch of emails) and now 
    // the warning code should be getting run after the notice code, so we shouldn't have to worry about 3 day warnings and sending warning and notice at the same time 
    $this->filter(null, 'DATE_SUB(expirationDate, INTERVAL emailOnExpirationDays DAY) BETWEEN DATE_SUB(NOW(), INTERVAL 5 DAY) AND NOW()'); 
    //$this->filter(null, 'DATE_SUB(expirationDate, INTERVAL 30 DAY) BETWEEN DATE_SUB(NOW(), INTERVAL 5 DAY) AND NOW()'); 

} 


protected function setupProductExpirationQueries() { 
    $this->addToQuery(' INNER JOIN LMemProducts ON txns.productID = LMemProducts.ID'); 

    // the expiration date exists (some products don't expire) 
    $this->filter('expirationDate', null, '!='); 

    // we're supposed to send emails 
    $this->filter('emailOnExpiration', true); 

    $this->filter('emailOnExpirationDays', null, '!='); 
    $this->filter('emailOnExpirationDays', 0, '!='); 
} 

}

답변

0

다음 SQL 해야 당신을 위해 일 :

(
    (DATE_SUB(expirationDate, 30 DAYS) BETWEEN DATE_SUB(NOW(), 3 DAYS) AND NOW()) 
    OR 
    (DATE_SUB(expirationDate, 5 DAYS) BETWEEN DATE_SUB(NOW(), 3 DAYS) AND NOW()) 
    OR 
    (DATE_SUB(expirationDate, 1 DAYS) BETWEEN DATE_SUB(NOW(), 3 DAYS) AND NOW()) 
) 
AND 
(DATE_ADD(warnedDate, 4 DAYS) <= NOW()) 

기본적으로 만료 날짜에서 경고 기간을 뺀 것이 3 일 전과 현재 사이에 있는지 확인하고 있습니다. 이렇게하면 작게 (3 일간) 작업이 진행되지 않습니다. 특히 만료 날짜가 3 월 15 일이면 2 월 15 일 (30 일이라고 가정)부터 2 월 18 일 사이에 true를 반환합니다. 그러나이 기간에 여러 번 보내지 않으려는 경우 (작업이 하루에 두 번 이상 실행될 수있는 잠재적 인 문제), warnedDate가 적어도 4 일 전에 확인되었는지 확인합니다. 이것은 30/5/1 기간에 잘 재생됩니다.

가 filterBy ... 했소() 함수에 그것을 넣어하려면 $this->filter('warnedDate', null); 줄을 제거 할 다음 하나를 DATE_SUB와 함께, 그리고 당신은 "직접"의 SQL을 추가 할 것 :

$this->filter(null, "(
    (DATE_SUB(expirationDate, 30 DAYS) BETWEEN DATE_SUB(NOW(), 3 DAYS) AND NOW()) 
    OR 
    (DATE_SUB(expirationDate, 5 DAYS) BETWEEN DATE_SUB(NOW(), 3 DAYS) AND NOW()) 
    OR 
    (DATE_SUB(expirationDate, 1 DAYS) BETWEEN DATE_SUB(NOW(), 3 DAYS) AND NOW()) 
) 
AND 
(DATE_ADD(warnedDate, 4 DAYS) <= NOW())"); 
+0

감사합니다. 이제 어떻게 테스트하는지 알아 내야합니다. 재미 있어야 롤 – CaitlinHavener