SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    SitePoint Addict MikesBarto2002's Avatar
    Join Date
    May 2006
    Location
    New York City
    Posts
    317
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question Use private function from one file in a public function in another

    I have two files:

    File get-calendar.php
    PHP Code:
    namespace genesis\calendar;

    class 
    Calendar {

        var 
    $calendar;
        
        public function 
    Get_calendar($date,$ministries,$limit) {
            global 
    $mysqli;
            
    $query 'SELECT calendar.event_name, calendar.calendar_id, calendar.ministry_id, calendar.start_date, venue.venue_name, ministry.ministry_name FROM calendar LEFT JOIN venue ON calendar.venue_id = venue.venue_id LEFT JOIN ministry ON calendar.ministry_id = ministry.ministry_id WHERE DATE(start_date) ' $date ' ';
            if (
    $ministries !== 'all') {
                
    $query .= 'AND calendar.ministry_id = "' $ministries '" ';
            }
            
    $query .= 'ORDER BY calendar.start_date ASC';
            if (
    $limit !== 'all') {
                
    $query .= ' LIMIT ' $limit;
            }
            
    $result $mysqli->query($query);
            if (
    $result) {
                while (
    $row $result->fetch_array(MYSQLI_ASSOC)){
                    
    $this->calendar[] = $row;
                }
                
    $result->close();
            } else {
                
    $this->calendar NULL;
            }
            return 
    $this->calendar;
        }
        

    File set-calendar.php
    PHP Code:
    use genesis\calendar as C;
    require_once(
    $_SERVER['DOCUMENT_ROOT'] . "/genesis/data/class-get-calendar.php");

    class 
    Calendar {

        var 
    $date;
        var 
    $ministries;
        var 
    $limit;
        var 
    $calendar;
        var 
    $num_results;
        
        function 
    __construct($date,$ministries 'all',$limit) {
            
    // Validate dates
            
    if (isset($_GET['from']) || isset($_GET['to'])) {
                if (isset(
    $_GET['from'])) {
                    if (
    $_GET['from'] == 'From') {
                        
    $from NULL;
                    } else {
                        
    $from strtotime($_GET['from']);
                        if (
    checkdate(date('m'$from),date('d'$from),date('Y'$from))) { 
                            
    $from mysql_real_escape_string($_GET['from']);
                        } else {
                            
    $from NULL;
                        }
                    }
                }
                if (isset(
    $_GET['to'])) {
                    if (
    $_GET['to'] == 'To') {
                        
    $to NULL;
                    } else {
                        
    $to strtotime($_GET['to']);
                        if (
    checkdate(date('m'$to),date('d'$to),date('Y'$to))) { 
                            
    $to mysql_real_escape_string($_GET['to']);
                        } else {
                            
    $to NULL;
                        }
                    }
                }
                if (!
    is_null($from) && !is_null($to)) {
                    
    $this->date 'BETWEEN "' $from '" AND "' $to '"'
                } else if (!
    is_null($from) && is_null($to)) {
                    
    $this->date '>= "' $from '"';
                } else if (
    is_null($from) && is_null($to)) {
                    
    $this->date '>= "' date('Y-m-d') . '"';
                }
            } else {
                if (!
    is_numeric($date)) {
                    
    $this->date date('Y-m-d');
                } else {
                    if (
    checkdate(date('m'$date),date('d'$date),date('Y'$date))) { 
                        
    $this->date $date;
                    } else {
                        
    $this->date date('Y-m-d');
                    }
                }
                if (!
    is_null($this->date)) {
                    
    $this->date '>= "' $this->date '"';
                } else {
                    
    $this->date '>= "' date('Y-m-d') . '"';
                }
            }
            
    // Validate ministry ID
            
    if (isset($_GET['ministry']) && is_numeric($_GET['ministry'])) {
                
    $this->ministries mysql_real_escape_string($_GET['ministry']);
            } else if (
    is_int($ministries) || $ministries == 'all') {
                
    $this->ministries $ministries;
            } else {
                
    $this->ministries 'all';
            }
            
    // Validate limit
            
    if (is_int($limit)) {
                
    $this->limit $limit;
            } else {
                
    $this->limit 'all';
            }
        }
        
        public function 
    Set_calendar($location) {
            
    $calendar = new C\Calendar();
            
    $calendar $calendar->Get_calendar($this->date,$this->ministries,$this->limit);
            if (
    $calendar == NULL) {
                
    $this->calendar '';
            } else {
                if (
    $location == 'main') {        
                    if (!empty(
    $calendar)) {
                        
    $this->calendar '<table>
                            <thead>
                                <tr>
                                    <th>Event</th>
                                    <th>Date</th>
                                    <th>Time</th>
                                    <th>Venue</th>
                                    <th>Ministry</th>
                                </tr>
                            </thead>
                            <tbody class="vcalendar">'
    ;
                        foreach (
    $calendar as $key => $value) {
                            
    $this->calendar .= '<tr class="vevent">';
                            
    $this->calendar .= '<td><a class="url uid summary" href="/calendar/event.php?id=' $calendar[$key]['calendar_id'] . '&amp;ministry=' $calendar[$key]['ministry_id'] . '">' $calendar[$key]['event_name'] . '</a></td>';
                            
    $date date('M. j, Y',strtotime(substr($calendar[$key]['start_date'],0,10)));
                            
    $time date('g:ia',strtotime(substr($calendar[$key]['start_date'],11,8)));
                            
    $this->calendar .= '<td><span class="dtstart"><abbr class="value" title="' date('Y-m-d',strtotime(substr($calendar[$key]['start_date'],0,10))) . 'T' date('H:i:s',strtotime(substr($calendar[$key]['start_date'],11,8))) . '">' $date '</abbr></span></td>';
                            
    $this->calendar .= '<td>' $time '</td>';
                            
    $this->calendar .= '<td class="location">' $calendar[$key]['venue_name'] . '</td>';
                            
    $this->calendar .= '<td class="organiser">' $calendar[$key]['ministry_name'] . '</td>';
                            
    $this->calendar .= '</tr>';
                        }
                        
    $this->calendar .= '</tbody>
                        </table>'
    ;
                    } else {
                        
    $this->calendar '<h2>There are no events at this time</h2><p>Please check back often.</p>';
                    }
                } else if (
    $location == 'sidebar') {
                    
    $this->calendar '<div id="calendar">';
                    if (empty(
    $calendar)) {
                        
    $this->calendar .= '<p>There are no events at this time.</p>';
                    } else {
                        foreach (
    $calendar as $key => $value) {
                            
    $this->calendar .= '<div class="calendar-event">';
                            
    $number_date substr($calendar[$key]['start_date'],8,2);
                            if (
    $number_date 10) {
                                
    $number_date substr($number_date,1,1);
                            }
                            
    $date date('F j, Y',strtotime(substr($calendar[$key]['start_date'],0,10)));
                            
    $time date('g:i A',strtotime(substr($calendar[$key]['start_date'],11,8)));
                            
    $this->calendar .= '<div class="calendar-event-numberdate">' $number_date '</div>';
                            
    $this->calendar .= '<div class="calendar-event-title"><a href="/calendar/event.php?id=' $calendar[$key]['calendar_id'] . '&amp;ministry=' $calendar[$key]['ministry_id'] . '">' $calendar[$key]['event_name'] . '</a></div>';
                            
    $this->calendar .= '<div class="calendar-event-description">';
                            
    $this->calendar .= '<div class="calendar-event-description-date">' $date '</div>';
                            
    $this->calendar .= '<div class="calendar-event-description-time">' $time '</div>';
                            
    $this->calendar .= '<div class="calendar-event-description-location">' $calendar[$key]['venue_name'] . '</div>';
                            
    $this->calendar .= '</div>
                                </div>'
    ;
                        }
                        
    $this->calendar .= '<p class="small-links"><a href="/calendar/';
                        if (
    $this->ministries !== 'all') {
                            
    $this->calendar .= 'index.php?ministry=' $calendar[$key]['ministry_id'];
                        }
                        
    $this->calendar .= '">View More ';
                        if (
    $this->ministries !== 'all') {
                            
    $this->calendar .= '<br />' $calendar[$key]['ministry_name'] . ' ';
                        }
                        
    $this->calendar .= 'Events &gt;&gt;</a></p>';
                    }
                    
    $this->calendar .= '</div>';
                }
            }
            return 
    $this->calendar;
        }
        

    I want to make the Get_calendar function in get-calendar.php private, but when I do, it throws me an error. I know it has to do with inheritance, but I am not sure ho to fix the problem.

    I tried putting the require_once from set-calendar.php in the construct, but that didn't work. I am guessing I have to extend Set_calendar in set-calendar.php, but I'm not quite sure the best way to do this.

    Any advice would be much appreciated!
    James Web Development | New York, NY
    Design, Develop, Deliver

  2. #2
    I solve practical problems. bronze trophy
    Michael Morris's Avatar
    Join Date
    Jan 2008
    Location
    Knoxville TN
    Posts
    2,026
    Mentioned
    64 Post(s)
    Tagged
    0 Thread(s)
    Once declared, the scope of a function cannot change. This is true of all languages which implement classical inheritance. Second, constructors have one and only one purpose - put the object in a ready state for execution. NEVER write a constructor that does anything else - it makes your code un-testable.

  3. #3
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,266
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)
    As written, Get_calendar cannot be private, otherwise Set_calendar in your second class won't be able to access it.

    To get you the right solution, we'll have to address the bigger issue.... why two calendar classes? What's their relationship to each other supposed to be?

  4. #4
    SitePoint Addict MikesBarto2002's Avatar
    Join Date
    May 2006
    Location
    New York City
    Posts
    317
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Maybe I am doing this wrong, please inform me if you think I am.

    I am creating a CMS for a church. I would like to use the Calendar in the front end and the back end. I created the Calendar class in the first file, and placed it in one folder, and the Calendar class in the second file, and placed it in the other. I don't want to have to write the first file's Calendar class over and over, seeing that it's use could be used in more than one way (front end to display the calendar, back end to edit a calendar, etc).

    All of my database query files are in one folder, and all of my view files are in another. Then the front end references that view file to pull the different parts needed (calendar, mass schedule, events, etc).

    Am I going about this the wrong way?
    James Web Development | New York, NY
    Design, Develop, Deliver

  5. #5
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,266
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)
    Here's how I might do it. The code below is just a skeleton, but hopefully the structure is clear.

    First, based on your get-calendar, it looks like a calendar is conceptually a list of events, so let's make that first -- just a generic calendar class.

    PHP Code:
    class Calendar
    {
        private 
    $events;
        
        public function 
    __construct($events)
        {
            
    $this->events = array();
            
            if (isset(
    $events)) {
                
    $this->addEvents($events);
            }
        }
        
        public function 
    addEvent($event)
        {
            
    $this->events[] = $event;
        }
        
        public function 
    addEvents($events)
        {
            foreach (
    $events as $event) {
                
    $this->addEvent($event);
            }
        }
        
        public function 
    getEvents()
        {
            return 
    $this->events;
        }

    Then, for translating between Calendar objects and database storage, we could make a calendar database class.

    PHP Code:
    class CalendarDatabase
    {
        public function 
    findByDateRangeAndMinistry($dateFrom$dateTo$ministries$limit)
        {
            
    $events // sql select...
            // database escaping (i.e., mysql_real_escape_string) happens in here only
            
            
    return new Calendar($events);
        }
        
        public function 
    save($calendar)
        {
            
    // sql insert, update....
        
    }

    Next, your set-calendar looks like it handles the request, so we could make a calendar request class.

    PHP Code:
    class CalendarRequest
    {
        public function 
    show()
        {
            
    $database = new CalendarDatabase();
            
            
    $calendar $database->findByDateRangeAndMinistry($_GET['from'], $_GET['to'], $_GET['ministry']);
            
            return 
    $this->render('calendar/show.php', array('calendar' => $calendar));
        }
        
        private function 
    render($template$params)
        {
            
    extract($params);
            
            
    ob_start();
            include 
    $template;
            
    $content ob_get_clean();
            
            return 
    $content;
        }

    And finally, the template.

    PHP Code:
    // calendar/show.php
    <?php if ($calendar): ?>
        <table>
            <?php foreach ($calendar->getEvents() as $event): ?>
                <tr>
                    <td><?php echo htmlspecialchars($event['event_name']) ?></td>
                    <td><?php echo htmlspecialchars($event['start_date']) ?></td>
                    ...
                </tr>
            <?php endforeach ?>
        </table>
    <?php else: ?>
        There are no events at this time.
    <?php endif ?>
    We've broken the logic up into several files, and this allows each component to have a simple and focused responsibility. The Calendar class is responsible for a calendar's behavior, and it doesn't need to know or care about how it's stored or presented. The CalendarDatabase class is responsible for mapping calendar objects to database tables and fields. The template is responsible for presenting a calendar, usually as HTML, but also possibly as JSON or an email message. And finally the CalendarRequest class is the glue. None of the other classes know about each other. CalendarRequest is the mediator that handles the interaction between the other components.

    The term "MVC" is used a lot these days. In MVC nomenclature, the Calendar and CalendarDatabase classes would be the model, the CalendarRequest class would be the controller, and the template would be the view.

  6. #6
    SitePoint Addict MikesBarto2002's Avatar
    Join Date
    May 2006
    Location
    New York City
    Posts
    317
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Thumbs up

    Thanks for putting so much time into showing me how you would do this. I really like what you've shown me, but I am still a little confused about how the extract function works with the template.

    So I am guessing that the render function is what I call when I want to print the calendar events onto a page using:

    PHP Code:
    $calendar = new CalendarRequest;
    echo 
    $calendar->render(); 
    I understand that extract takes the key names from an array and places them in their own variable, but then when calling them, I am assuming in the example below you have the key names being "event_name" and "start_date"?

    Is extract something that I should use? I feel like this doesn't really allow you to visually see the array that you are calling, making the code cleaner, but a little harder to read if someone else was working on the project with me. To make it visually easier to read, if I decided not to use extract, I would just loop through the array?

    Thanks again for all of your help with this. I really like how you laid it out much better than I had it. You also cleared up MVC for me, which I have been trying to understand and hadn't quite grasped.
    James Web Development | New York, NY
    Design, Develop, Deliver

  7. #7
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,266
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)
    You would actually not call render yourself. In fact it's private, so you can't. You would call the show method.

    PHP Code:
    $calendarRequest = new CalendarRequest();
    $calendarHtml $calendarRequest->show(); 
    The show method uses the _GET params to ask the database for the appropriate calendar of events, then the show method itself calls render, passing in the calendar it just fetched.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •