A ccHost Quick Reverse Engineer
When I sat down to write the auto 'feature this playlist' feature I knew I wanted to add a menu item to the playlist's command window but I totally forgot how that menu was generated. It took less than a minute to figure it out but I thought it might be useful since I know this kind of 'view source/reverse engineer' is how most developers approach a codebase like ccHost.
- I browsed to a playlist.
- Selected 'View Style Information' from Firefox's Web Developer Toolbar which highlights the area under the cursor and gives you the CSS class selector name. (Of course view source also works, this is just faster.)
- For the menu that turned out to be 'cc_playlist_owner'
- I searched under ccskins for all occurances of that selector.
- I found the template that built the menu at ccskins/shared/playlist_2_head.tpl
<ul class="cc_playlist_owner_menu light_bg dark_border"> %loop(#R/menu,mi)% <li> <a target="_parent" href="%(#mi/url)%" id="%(#mi/id)%" class="%(#mi/class)%">%text(#mi/text)% </a>
- From the code in this template I could deduce the following:
- the menu was just being displayed here. The menu was being built somewhere else.
- the menu itself is embedded in the 'R' record
- a few lines above is line %map(#R,records/0)% which means 'R' is result of the query ('records' is the array of a query result in a template)
- every query must have a dataview somewhere, at the top of the template is the meta declaration dataview = playlist_detail
- I found ccdataviews/playlist_detail.php
- Since the 'menu' is a PHP array and not a normal SQL column, I deduced there must a dataview filter that is building the menu.
- Filter events are returned in an array in a dataview and there was CC_EVENT_FILTER_CART_MENU (a playlist is actually a record in the cc_tbl_carts table)
- I searched cchost_lib/* for that event and found the declaration of a handler in cchost_lib/ccextras/cc-playlist.php
- That pointed to a method in cchost_lib/ccextras/cc-playlist-browse.inc called CCPlaylistBrowse::OnFilterCartMenu
At this point I knew what event I had to handle CC_EVENT_FILTER_CART_MENU and I had an example of what the system was doing with that event in CCPlaylistBrowse::OnFilterCartMenu.