Monday - April 11th, 2016


Verizon Code and Trophies

I was originally hired for a six month contract. That blossomed into a timeframe that was just shy of two years. It was a great experience and the additions that were made to my skillset and portfolio were significant, thanks to the opportunities and personalites I came in contact with during my time with Verizon Wireless.

Here's a brief "tour..."

In addition to what's below, feel free to peruse the Powerpoint presentation that's displayed to the right to view the GANT Chart and the Phantom JS scripting that created a pdf version of the web data the user was looking at.

I) OOP / MVC

The template that was in place, in terms of how PHP pages were to be constructed, was based on an MVC approach to Object Oriented Programming. Where OOP has Functions categorized under the heading of various Classes, this approach further grouped classes in the context of "Model, View and Controller."

Whereas an "object" is usually thought of as a digital placeholder that positions functionality within the landscape of the page, this infrastructure established the page itself as the "object." The result being a very clean and concise way of organizing and constructing applications. Click on the "show / hide" link below to read more and to see how the code was written.

...show / hide

Below is how a page is typically coded.

  1. require_once('homepageclass.php'); // this extends the htmlclass which is all your basic html info such doctype, header information etc. "homepageclass" will extend that and add any unique scripting for the sake of this particular page
  2. require_once('model_class.php');//this is where you keep all of your database functionality
  3. require_once('view_class.php');//this is where you keep all of your "GUI" functionality as far as how you display the data being retrieved by the classes in the model_class.php page
  4. $app_id=6;
  5. $app_roles = array('*');
  6. $new_page= new HomePage($app_id,$app_roles);
  7. $data= new NewsAdmin();
  8. $view = new viewNews();
  9. $headline_info=$data->headline_featured(); //function that retrieves all of the news articles in the database
  10. $headline_display=$view->featured_app($headline_info); // function that breaks up the array into intuitive and aesthetically sensible elements that can be displayed
  11. $body='</div>
  12. <div class="headlines">';
  13. $body.=$headline_display;//here's the "headlines" as they're being displayed thanks to line 13
  14. $body.='
  15. </div>
  16. $new_page->setBody($body);//this is a construct that's located on the htmlclass.php page that simply "assembles" all of the content that's been categorized under the "body" heading and is then displayed on line 23
  17. echo $new_page->display();
  18. ?>


It becomes easier to understand when you see the htmlclass.php page. Here's the way that looks:

  1. <?php
  2. //require_once 'DataTools/classes/SecurityCheck.class.php';
  3. class htmlpage
  4. {
  5. protected $headerTop; //the following values are "protected" in order to ensure that they remain exclusive to the htmlpage Class. This is healthy programming because it prevents situations where unintended usages of the Property name (i.e. $style) don't result in wires getting crossed and apps blowing up because of the way the page is subsequently processed
  6. protected $metatags;
  7. protected $style;
  8. protected $scripts;
  9. protected $headerBottom;
  10. protected $body;
  11. protected $footer;
  12. protected $URL;
  13. protected $web_address;
  14. protected $security;
  15. protected $app_id;
  16. protected $app_roles = array();
  17. public $root_directory;
  18. //public function __construct($app_id, $app_roles = array(), $title='South Area Network Page')
  19. public function __construct($title='South Area Network Page')
  20. {
  21. //$this->app_id = $app_id;
  22. //$this->app_roles = $app_roles;
  23. //here' where I'm declaring and / or defining my Property values
  24. $this->metaTags=''; //by leaving this blank, I'm giving myself the opportunity to define this in the context of some kind of interactivity in the context of a Function. As an aside, you don't declare a variable / property with a function and expect it to be shared by other Functions in the same Class apart from using the Construct Function.
  25. $this->style='';
  26. $this->scripts='';
  27. $this->body='';
  28. $this->headerTop = '
  29. <!DOCTYPE html>
  30. <head>
  31. <meta http-equiv="Pragma" content="no-cache" />
  32. <meta http-equiv="Expires" content="-1" />
  33. <title>'.$title.'</title>
  34. <link href="css/new_style.css" rel="stylesheet" type="text/css" />
  35. <link rel="shortcut icon" href="http://southareanetwork.nss.vzwnet.com/images/verizon_favicon.ico">
  36. <map name="tabs">
  37. <area shape="rect" coords="19,27,140,43" href="http://cascsawssa1v.nss.vzwnet.com:8080/c0couri/exdash/index.php">
  38. <area shape="rect" coords="153,27,262,43" href="network_tools.php">
  39. <area shape="rect" coords="281,27,393,43" href="recognition.php">
  40. <area shape="rect" coords="405,27,523,43" href="project_request.php">
  41. </map>
  42. <map name="login">
  43. <area shape="rect" coords="14,64,456,131" href="index.php">
  44. </map>
  45. '; //hard coding the value of my $headerTop Property
  46. $this->headerBottom= '
  47. '; //hard coding the value of my $headerBottom Property, but this can usurped by the other pages
  48. $this->footer='
  49. </div> <!-- close site_content -->
  50. <div class="footer"><br>© Verizon Wireless | South Area | All Rights Reserved | <a href="sign_in.php" style="color:#ffffff; text-decoration:none;">Sign In</a> | <a href="page.php?page_id=8.php" style="color:#ffffff; text-decoration:none;">Contact</a></div></body></html>
  51. ';//hard coding the value of my $footer Property
  52. //$this->security = new SecurityCheck($this,$this->app_id,$this->app_roles);
  53. $this->setURL();
  54. }
  55. public function getURL()
  56. {
  57. return $this->URL;
  58. } //apparently I'm going to be defining my URL Property value in the context of either this Function or the one directly beneath it. Either way, the Property value is the one being "returned" by one of these two functions.
  59. public function setURL($URL=null)
  60. {
  61. if(isset($URL))
  62. {
  63. $this->URL=$URL;
  64. }
  65. else
  66. {
  67. $this->URL='http://'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'];
  68. return;
  69. }
  70. }
  71. public function curPageName()
  72. {
  73. $this->web_address=substr($_SERVER["SCRIPT_NAME"],strrpos($_SERVER["SCRIPT_NAME"],"/")+1);
  74. return $this->web_address;
  75. }
  76. public function setMetaTags($metaTags)
  77. {
  78. $this->metatags .=$metaTags;
  79. return; //I can expect this Property value to be establishd as a result of a variable that's going to be passed into this Function
  80. }
  81. public function setStyle($style)
  82. {
  83. $this->style .=$style;
  84. return;
  85. } //same thing as $metaTags
  86. public function setScript($scripts)
  87. {
  88. $this->scripts .=$scripts;
  89. return;
  90. } //same thing as $metaTags
  91. public function setBody($body)
  92. {
  93. $this->body .=$body;
  94. return;
  95. } // same thing as $metaTags
  96. public function display()
  97. {
  98. echo $this->headerTop;
  99. echo $this->metatags;
  100. echo $this->style;
  101. echo $this->scripts;
  102. echo $this->headerBottom;
  103. echo $this->body;
  104. echo $this->footer;
  105. return;
  106. } //this Function is taking all of the Property values that have been declared and defined and displaying them by "echo-ing" them
  107. }
  108. ?>


II) 20,000,000 Rows...

The first project I was assigned was to take a database that consisted of Twitter data and build an app that allowed users to query the database based on date and latitude / longitude values.

What made this challenging was that even by indexing the data, because the query included a "BETWEEN" dynamic, the indexing approach did very little in terms of streamling the search process.

The first step was to break the original table down into 365 individual tables. Each table was a day's worth of Twitter traffic. This in and of itself required a script that would run overnite for several days and break the table down and write new tables with one day's worth the data.

Once that was in place, the actual app would identify the tables that corresponded to the user's search criteria. It would then grab the appropriate data and export it into a temporary table that could then be dumped into a CSV table the user could download.

Even with the data being broken down into 365 different tables, the process was still potentially lengthy to the point of being distracting for the user. To prevent the apparent lack of activity from being a problem, a Javascript was introduced that "moved" the user's process so they could see progress being made. Click on the "show more..." link below to see the code.

...show / hide

You've got 365 tables, each representing one day's worth of Twitter traffic. When the user submits their search criteria, the first thing is to determine how many days / tables will need to be queried in order to "mine" the appropriate amount of information. That number of tables becomes the number of "laps" the code will make as it gathers all of the data from each of the tables that corresponds to the latitude and longitude values the user entered and inserts that information into a new temporary that has as its name the current session id.

As each table is processed and dumped into the new temp table, the user is routed to a page whose sole purpose is to inform the user how many more "laps" or tables the process has to go through before the process if finished. Once the process completes its last "lap," the user is routed to a page where it can now export all of the information that's been compiled and inserted into the new temp table into a CSV file.

Here's the code for the page that is monitoring the number of "laps" that are being made:

  1. <?php
  2. $the_session_id=session_id();
  3. if(empty($the_session_id))
  4. {
  5. session_start();
  6. $the_session_id=session_id();
  7. }
  8. if(!isset($_GET['new_count']))
  9. {
  10. if(isset($_POST['start_date']))
  11. {
  12. header("location:no_results.php");
  13. exit();
  14. }
  15. if(!$_POST['end_date'])
  16. {
  17. header("location:no_results.php");
  18. exit();
  19. }
  20. if(!$_POST['latitude_1'])
  21. {
  22. header("location:no_results.php");
  23. exit();
  24. }
  25. if(!$_POST['latitude_2'])
  26. {
  27. header("location:no_results.php");
  28. exit();
  29. }
  30. if(!$_POST['longitude_1'])
  31. {
  32. header("location:no_results.php");
  33. exit();
  34. }
  35. if(!$_POST['longitude_2'])
  36. {
  37. header("location:no_results.php");
  38. exit();
  39. }
  40. }
  41. ini_set('max_execution_time', 300); //300 seconds = 5 minutes
  42. ini_set("memory_limit", "700M");
  43. include ("carter.inc");
  44. $cxn = mysqli_connect($host,$user,$password,$database)
  45. or die ("couldn't connect to server");
  46. /*$start_date = date('Y-m-d',strtotime($_POST['start_month'].' '.$_POST['start_day'].' '.$_POST['start_year']));
  47. $end_date = date('Y-m-d',strtotime($_POST['end_month'].' '.$_POST['end_day'].' '.$_POST['end_year']));*/
  48. if(!isset($_GET['new_count']))
  49. {
  50. $the_start_date=trim($_POST['start_date']);
  51. $the_end_date=trim($_POST['end_date']);
  52. $min_date = strtotime("$the_start_date"); // or your date as well
  53. $max_date = strtotime("$the_end_date");
  54. $datediff = $max_date - $min_date;
  55. $starting_count= floor($datediff/(60*60*24));
  56. $the_count=$starting_count+2;
  57. $lat_1=trim($_POST['latitude_1']);
  58. $lat_2=trim($_POST['latitude_2']);
  59. $lon_1=trim($_POST['longitude_1']);
  60. $lon_2=trim($_POST['longitude_2']);
  61. //set up temporary table based on session_id, but first make sure there isn't one left over from an abandoned session
  62. $dan="show tables like '$the_session_id'";
  63. $dan_result=mysqli_query($cxn, $dan);
  64. if(!$dan_result)
  65. {
  66. $rats=mysqli_errno($cxn).': '.mysqli_error($cxn);
  67. die($rats);
  68. }
  69. $dan_count=mysqli_num_rows($dan_result);
  70. if($dan_count>0)
  71. {
  72. $michelle="delete from $the_session_id";
  73. $michelle_query=mysqli_query($cxn, $michelle);
  74. if(!$michelle_query)
  75. {
  76. $bummer=mysqli_errno($cxn).': '.mysqli_error($cxn);
  77. die($bummer);
  78. }
  79. }
  80. else
  81. {
  82. $brice="CREATE TABLE `$the_session_id` (
  83. `id` int(11) NOT NULL AUTO_INCREMENT,
  84. `actor_id` varchar(150) DEFAULT NULL,
  85. `actor_display_name` varchar(150) DEFAULT NULL,
  86. `posted_time` varchar(150) DEFAULT NULL,
  87. `lat` varchar(150) DEFAULT NULL,
  88. `lon` varchar(150) DEFAULT NULL,
  89. `location_name` varchar(150) DEFAULT NULL,
  90. `posted_day` date DEFAULT NULL,
  91. `session_id` varchar(150) DEFAULT NULL,
  92. PRIMARY KEY (`id`)
  93. ) ENGINE=InnoDB AUTO_INCREMENT=529425 DEFAULT CHARSET=latin1";
  94. $brice_query=mysqli_query($cxn, $brice);
  95. if(!$brice_query)
  96. {
  97. echo "right here, champ";
  98. $rats=mysqli_errno($cxn).': '.mysqli_error($cxn);
  99. die($rats);
  100. }
  101. }
  102. //get the right table names
  103. $table_date = str_replace("-","","$the_start_date");
  104. $the_table_name="twtr_";
  105. $the_table_name.=$table_date;
  106. $current_date = "$the_start_date";
  107. $new_current_date=date('Y-m-d', strtotime($current_date. ' + 1 days'));
  108. $new_table_date = str_replace("-","","$new_current_date");
  109. $new_table_name="twtr_";
  110. $new_table_name.=$new_table_date;
  111. $the_twitter_table=$the_session_id;
  112. $nelson="insert into $the_twitter_table (actor_id, actor_display_name, posted_time, lat, lon, location_name, posted_day, session_id) SELECT actor_id, actor_display_name, posted_time, geo_coords_lat ,geo_coords_lon, location_name, posted_day, '$the_session_id' FROM $the_table_name WHERE (geo_coords_lat BETWEEN '$lat_1' and '$lat_2') and (geo_coords_lon BETWEEN '$lon_1' and '$lon_2')";
  113. $nelson_query=mysqli_query($cxn, $nelson);
  114. if(!$nelson_query)
  115. {
  116. $nuts=mysqli_errno($cxn).': '.mysqli_error($cxn);
  117. die($nuts);
  118. }
  119. $new_count=$the_count-1;
  120. header("Location:new_nelson_preliminary.php?lat_1=$lat_1&lat_2=$lat_2&lon_1=$lon_1&lon_2=$lon_2&new_count=$new_count&table_name=$new_table_name¤t_date=$the_start_date&session_id=$the_session_id");
  121. exit();
  122. }
  123. else
  124. {
  125. if($_GET['new_count']==0)
  126. {
  127. $the_session_id=$_GET['session_id'];
  128. header("Location:new_nelson_twitter_preliminary.php?session_id=$the_session_id");
  129. exit();
  130. }
  131. else
  132. {
  133. $the_table_name=$_GET['table_name'];
  134. $the_new_count=$_GET['new_count'];
  135. $lat_1=$_GET['lat_1'];
  136. $lat_2=$_GET['lat_2'];
  137. $lon_1=$_GET['lon_1'];
  138. $lon_2=$_GET['lon_2'];
  139. $the_session_id=$_GET['session_id'];
  140. $the_twitter_table=$the_session_id;
  141. $nelson="insert into $the_twitter_table (actor_id, actor_display_name, posted_time, lat, lon, posted_day, session_id) SELECT actor_id, actor_display_name, posted_time, geo_coords_lat ,geo_coords_lon, posted_day, '$the_session_id' FROM $the_table_name WHERE (geo_coords_lat BETWEEN '$lat_1' and '$lat_2') and (geo_coords_lon BETWEEN '$lon_1' and '$lon_2')";
  142. $nelson_query=mysqli_query($cxn, $nelson);
  143. if(!$nelson_query)
  144. {
  145. $nuts=mysqli_errno($cxn).': '.mysqli_error($cxn);
  146. die($nuts);
  147. }
  148. $new_count=$the_new_count-1;
  149. $current_date = $_GET['current_date'];
  150. $new_current_date=date('Y-m-d', strtotime($current_date. ' + 1 days'));
  151. $new_table_date = str_replace("-","","$new_current_date");
  152. $new_table_name="twtr_";
  153. $new_table_name.=$new_table_date;
  154. header("Location:new_nelson_preliminary.php?lat_1=$lat_1&lat_2=$lat_2&lon_1=$lon_1&lon_2=$lon_2&new_count=$new_count&table_name=$new_table_name¤t_date=$new_current_date&session_id=$the_session_id");
  155. exit();
  156. }
  157. }
  158. ?>




III) Bootstrap

Given the priority of creating mobile versions of whatever web content that you have, "Bootstrap" is a very handy skill to have in your toolbox.

It's not always intuitive, when it comes to creating a mirror image of your site. Even collapsible menus require a little "finagling" in order to get the desired effect.

Click here to view the Bootstrap version of the Verizon webpage.