| Conditions | 53 |
| Paths | > 20000 |
| Total Lines | 478 |
| Code Lines | 237 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | <?php |
||
| 772 | public function export() |
||
| 773 | { |
||
| 774 | clearstatcache(); |
||
| 775 | session_write_close(); |
||
| 776 | |||
| 777 | # data to send |
||
| 778 | $data = []; |
||
| 779 | |||
| 780 | # environment settings |
||
| 781 | $post = $this->getPost(); # catch $_POST |
||
| 782 | $this->setTerminal(true); # set terminal |
||
| 783 | |||
| 784 | # TRY-CATCH-BLOCK |
||
| 785 | try { |
||
| 786 | |||
| 787 | # STANDARD VALIDATIONS [check method] |
||
| 788 | if (!$this->isPost()) |
||
| 789 | { |
||
| 790 | $http = new Http(); |
||
| 791 | $http->writeStatus($http::HTTP_METHOD_NOT_ALLOWED); |
||
| 792 | |||
| 793 | die('Error ' . $http::HTTP_METHOD_NOT_ALLOWED .' (' . $http->getStatusText($http::HTTP_METHOD_NOT_ALLOWED) . ')!!'); |
||
| 794 | } |
||
| 795 | |||
| 796 | # STANDARD VALIDATIONS [check needed arguments] |
||
| 797 | $needles = ['conn', 'sql', 'type', 'filename']; |
||
| 798 | |||
| 799 | array_walk($needles, function(&$item) use ($post) { |
||
| 800 | if (!array_key_exists($item, $post)) |
||
| 801 | { |
||
| 802 | $http = new Http(); |
||
| 803 | $http->writeStatus($http::HTTP_BAD_REQUEST); |
||
| 804 | |||
| 805 | die('Error ' . $http::HTTP_BAD_REQUEST .' (' . $http->getStatusText($http::HTTP_BAD_REQUEST) . ')!!'); |
||
| 806 | } |
||
| 807 | }); |
||
| 808 | |||
| 809 | $components = [ |
||
| 810 | "attributes" => [ |
||
| 811 | "conn" => [ |
||
| 812 | "required" => true, |
||
| 813 | "type" => "number" |
||
| 814 | ], |
||
| 815 | "sql" => [ |
||
| 816 | "required" => true, |
||
| 817 | "type" => "text" |
||
| 818 | ], |
||
| 819 | "type" => [ |
||
| 820 | "required" => true, |
||
| 821 | "type" => "text" |
||
| 822 | ], |
||
| 823 | "filename" => [ |
||
| 824 | "required" => true, |
||
| 825 | "type" => "text" |
||
| 826 | ] |
||
| 827 | ], |
||
| 828 | ]; |
||
| 829 | |||
| 830 | $options = [ |
||
| 831 | "conn" => [ |
||
| 832 | "label" => "Connection", |
||
| 833 | ], |
||
| 834 | "sql" => [ |
||
| 835 | "label" => "SQL", |
||
| 836 | "validators" => [ |
||
| 837 | "Alnum" => ["allowWhiteSpace" => false] |
||
| 838 | ] |
||
| 839 | ], |
||
| 840 | "type" => [ |
||
| 841 | "label" => "Type", |
||
| 842 | "validators" => [ |
||
| 843 | "InArray" => ["haystack" => ['excel', 'csv']] |
||
| 844 | ] |
||
| 845 | ], |
||
| 846 | "filename" => [ |
||
| 847 | "label" => "Filename" |
||
| 848 | ] |
||
| 849 | ]; |
||
| 850 | |||
| 851 | $form = new Form($components); |
||
| 852 | $form->fill($post); |
||
| 853 | |||
| 854 | $validator = new FormValidator($form, $options); |
||
| 855 | $validator->validate(); |
||
| 856 | |||
| 857 | $data["validator"] = $validator; |
||
| 858 | |||
| 859 | # form validation |
||
| 860 | if (!$validator->isValid()) |
||
| 861 | { |
||
| 862 | $data["messages"] = $validator->getMessages(); |
||
| 863 | throw new \Drone\Exception\Exception("Form validation errors", 300); |
||
| 864 | } |
||
| 865 | |||
| 866 | $id = $post["conn"]; |
||
| 867 | |||
| 868 | $connection = $this->getUserConnectionEntity()->select([ |
||
| 869 | "USER_CONN_ID" => $id |
||
| 870 | ]); |
||
| 871 | |||
| 872 | if (!count($connection)) |
||
| 873 | throw new \Exception("The Connection does not exists"); |
||
| 874 | |||
| 875 | $connection = array_shift($connection); |
||
| 876 | |||
| 877 | if ($connection->STATE == 'I') |
||
| 878 | throw new \Drone\Exception\Exception("This connection was deleted", 300); |
||
| 879 | |||
| 880 | $details = $this->getUserConnectionDetailsEntity()->select([ |
||
| 881 | "USER_CONN_ID" => $id |
||
| 882 | ]); |
||
| 883 | |||
| 884 | $idenfiers = $this->getIdentifiersEntity()->select([]); |
||
| 885 | |||
| 886 | $dbconfig = []; |
||
| 887 | |||
| 888 | foreach ($details as $field) |
||
| 889 | { |
||
| 890 | foreach ($idenfiers as $identifier) |
||
| 891 | { |
||
| 892 | if ($field->CONN_IDENTI_ID == $identifier->CONN_IDENTI_ID) |
||
| 893 | $dbconfig[$identifier->CONN_IDENTI_NAME] = $field->FIELD_VALUE; |
||
| 894 | } |
||
| 895 | } |
||
| 896 | |||
| 897 | /* identifies if sql is base64 encoded */ |
||
| 898 | if (array_key_exists('base64', $post)) |
||
| 899 | { |
||
| 900 | if ((bool) $post["base64"]) |
||
| 901 | $post["sql"] = base64_decode($post["sql"]); |
||
| 902 | } |
||
| 903 | |||
| 904 | $data["sql"] = base64_encode($post["sql"]); |
||
| 905 | |||
| 906 | $sql_text = $post["sql"]; |
||
| 907 | |||
| 908 | /* |
||
| 909 | * SQL parsing |
||
| 910 | */ |
||
| 911 | $sql_text = trim($sql_text); |
||
| 912 | |||
| 913 | if (empty($sql_text)) |
||
| 914 | throw new \Drone\Exception\Exception("Empty statement"); |
||
| 915 | |||
| 916 | $pos = strpos($sql_text, ';'); |
||
| 917 | |||
| 918 | if ($pos !== false) |
||
| 919 | { |
||
| 920 | $end_stament = strstr($sql_text, ';'); |
||
| 921 | |||
| 922 | if ($end_stament == ';') |
||
| 923 | $sql_text = strstr($sql_text, ';', true); |
||
| 924 | } |
||
| 925 | |||
| 926 | # clean comments and other characters |
||
| 927 | |||
| 928 | // (/**/) |
||
| 929 | $clean_code = preg_replace('/(\s)*\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\//', '', $sql_text); |
||
| 930 | |||
| 931 | // (--) |
||
| 932 | $clean_code = preg_replace('/(\s)*--.*\n/', "", $clean_code); |
||
| 933 | |||
| 934 | # clean other characters starting senteces |
||
| 935 | $clean_code = preg_replace('/^[\n\t\s]*/', "", $clean_code); |
||
| 936 | |||
| 937 | # indicates if SQL is a selection statement |
||
| 938 | $isSelectStm = $data["selectStm"] = (preg_match('/^SELECT/i', $clean_code)); |
||
| 939 | |||
| 940 | # indicates if SQL is a show statement |
||
| 941 | $isShowStm = $data["showStm"] = (preg_match('/^SHOW/i', $clean_code)); |
||
| 942 | |||
| 943 | # detect selection |
||
| 944 | if (!$isSelectStm && !$isShowStm) |
||
| 945 | throw new \Exception("You can't export a non-selection statement!"); |
||
| 946 | |||
| 947 | try { |
||
| 948 | |||
| 949 | $connError = false; |
||
| 950 | |||
| 951 | $entity = new EntityMd([]); |
||
| 952 | $entity->setConnectionIdentifier("CONN" . $id); |
||
| 953 | |||
| 954 | $driverAdapter = new \Drone\Db\Driver\DriverAdapter($dbconfig, false); |
||
| 955 | |||
| 956 | # start time to compute execution |
||
| 957 | $startTime = microtime(true); |
||
| 958 | |||
| 959 | $driverAdapter->getDb()->connect(); |
||
| 960 | |||
| 961 | $auth = $driverAdapter; |
||
| 962 | |||
| 963 | $data["results"] = $auth->getDb()->execute($sql_text); |
||
| 964 | } |
||
| 965 | # encapsulate real connection error! |
||
| 966 | catch (\Drone\Db\Driver\Exception\ConnectionException $e) |
||
| 967 | { |
||
| 968 | $connError = true; |
||
| 969 | |||
| 970 | $file = str_replace('\\', '', __CLASS__); |
||
| 971 | $storage = new \Drone\Exception\Storage("cache/$file.json"); |
||
| 972 | |||
| 973 | # stores the error code |
||
| 974 | if (($errorCode = $storage->store($e)) === false) |
||
| 975 | { |
||
| 976 | $errors = $storage->getErrors(); |
||
| 977 | |||
| 978 | # if error storing is not possible, handle it (internal app error) |
||
| 979 | $this->handleErrors($errors, __METHOD__); |
||
| 980 | } |
||
| 981 | |||
| 982 | $data["code"] = $errorCode; |
||
| 983 | $data["message"] = "Could not connect to database"; |
||
| 984 | |||
| 985 | # to identify development mode |
||
| 986 | $config = include 'config/application.config.php'; |
||
| 987 | $data["dev_mode"] = $config["environment"]["dev_mode"]; |
||
| 988 | |||
| 989 | # redirect view |
||
| 990 | $this->setMethod('error'); |
||
| 991 | } |
||
| 992 | catch (\Exception $e) |
||
| 993 | { |
||
| 994 | # SUCCESS-MESSAGE |
||
| 995 | $data["process"] = "error"; |
||
| 996 | $data["message"] = $e->getMessage(); |
||
| 997 | |||
| 998 | return $data; |
||
| 999 | } |
||
| 1000 | |||
| 1001 | # end time to compute execution |
||
| 1002 | $endTime = microtime(true); |
||
| 1003 | $elapsed_time = $endTime - $startTime; |
||
| 1004 | |||
| 1005 | $data["time"] = round($elapsed_time, 4); |
||
| 1006 | |||
| 1007 | if (!$connError) |
||
| 1008 | { |
||
| 1009 | $data["num_rows"] = $auth->getDb()->getNumRows(); |
||
| 1010 | $data["num_fields"] = $auth->getDb()->getNumFields(); |
||
| 1011 | $data["rows_affected"] = $auth->getDb()->getRowsAffected(); |
||
| 1012 | |||
| 1013 | $rows = $auth->getDb()->getArrayResult(); |
||
| 1014 | |||
| 1015 | # columns with errors in a select statement |
||
| 1016 | $column_errors = []; |
||
| 1017 | |||
| 1018 | switch ($post["type"]) |
||
| 1019 | { |
||
| 1020 | case 'excel': |
||
| 1021 | $ext = '.xls'; |
||
| 1022 | break; |
||
| 1023 | case 'csv': |
||
| 1024 | $ext = '.csv'; |
||
| 1025 | break; |
||
| 1026 | default: |
||
| 1027 | $ext = '.txt'; |
||
| 1028 | break; |
||
| 1029 | } |
||
| 1030 | |||
| 1031 | $filename = $post["filename"] . $ext; |
||
| 1032 | |||
| 1033 | $file_hd = @fopen("cache/" . $filename, "w+"); |
||
| 1034 | |||
| 1035 | if (!$file_hd) |
||
| 1036 | { |
||
| 1037 | $this->error(Errno::FILE_PERMISSION_DENIED, "cache/" . $filename); |
||
| 1038 | throw new \Exception("The file could not be created!"); |
||
| 1039 | } |
||
| 1040 | |||
| 1041 | $contents = ""; |
||
| 1042 | |||
| 1043 | $data["data"] = []; |
||
| 1044 | |||
| 1045 | switch ($post["type"]) |
||
| 1046 | { |
||
| 1047 | case 'excel': |
||
| 1048 | |||
| 1049 | $table = "<html xmlns:v='urn:schemas-microsoft-com:vml' \r\n\txmlns:o='urn:schemas-microsoft-com:office:office'\r\n"; |
||
| 1050 | $table .= "\txmlns:x='urn:schemas-microsoft-com:office:excel'\r\n"; |
||
| 1051 | $table .= "\txmlns='http://www.w3.org/TR/REC-html40'>\r\n"; |
||
| 1052 | |||
| 1053 | $table .= "<head>\r\n"; |
||
| 1054 | $table .= "\t<meta name='Excel Workbook Frameset'><meta http-equiv='Content-Type' content='text/html; charset='utf-8'>\r\n"; |
||
| 1055 | $table .= "</head>\r\n\r\n"; |
||
| 1056 | |||
| 1057 | $table .= "<body>\r\n<table border=1>\r\n"; |
||
| 1058 | |||
| 1059 | $column_names = []; |
||
| 1060 | |||
| 1061 | foreach ($rows[0] as $column_name => $row) |
||
| 1062 | { |
||
| 1063 | if (!is_numeric($column_name)) |
||
| 1064 | $column_names[] = $column_name; |
||
| 1065 | } |
||
| 1066 | |||
| 1067 | $table .= "\t<thead>\r\n\t\t<tr>\r\n"; |
||
| 1068 | |||
| 1069 | foreach ($column_names as $column_name) |
||
| 1070 | { |
||
| 1071 | $table .= "\t\t\t<th>$column_name</th>\r\n"; |
||
| 1072 | } |
||
| 1073 | |||
| 1074 | $table .= "\t\t</tr>\r\n\t</thead>\r\n\t<tbody>"; |
||
| 1075 | |||
| 1076 | # data parsing |
||
| 1077 | foreach ($rows as $key => $row) |
||
| 1078 | { |
||
| 1079 | $data["data"][$key] = []; |
||
| 1080 | |||
| 1081 | foreach ($row as $column => $value) |
||
| 1082 | { |
||
| 1083 | if ($isShowStm) |
||
| 1084 | $column++; |
||
| 1085 | |||
| 1086 | if (gettype($value) == 'object') |
||
| 1087 | { |
||
| 1088 | if (get_class($value) == 'OCI-Lob') |
||
| 1089 | { |
||
| 1090 | if (($val = @$value->load()) === false) |
||
| 1091 | { |
||
| 1092 | $val = null; # only for default, this value is not used |
||
| 1093 | $column_errors[] = $column; |
||
| 1094 | } |
||
| 1095 | |||
| 1096 | $data["data"][$key][$column] = $val; |
||
| 1097 | } |
||
| 1098 | else |
||
| 1099 | $data["data"][$key][$column] = $value; |
||
| 1100 | } |
||
| 1101 | else { |
||
| 1102 | $data["data"][$key][$column] = $value; |
||
| 1103 | } |
||
| 1104 | } |
||
| 1105 | |||
| 1106 | } |
||
| 1107 | |||
| 1108 | foreach ($data["data"] as $row) |
||
| 1109 | { |
||
| 1110 | $table .= "\t\t<tr>\r\n"; |
||
| 1111 | |||
| 1112 | foreach ($column_names as $column_name) |
||
| 1113 | { |
||
| 1114 | $table .= "\t\t\t<td>". $row[$column_name] ."</td>\r\n"; |
||
| 1115 | } |
||
| 1116 | |||
| 1117 | $table .= "\t\t</tr>\r\n"; |
||
| 1118 | } |
||
| 1119 | |||
| 1120 | $table .= "\t</tbody>\r\n</table>\r\n</body>\r\n</html>"; |
||
| 1121 | $contents = $table; |
||
| 1122 | |||
| 1123 | break; |
||
| 1124 | |||
| 1125 | case 'csv': |
||
| 1126 | |||
| 1127 | $text = ""; |
||
| 1128 | |||
| 1129 | $column_names = []; |
||
| 1130 | |||
| 1131 | foreach ($rows[0] as $column_name => $row) |
||
| 1132 | { |
||
| 1133 | if (!is_numeric($column_name)) |
||
| 1134 | $column_names[] = $column_name; |
||
| 1135 | } |
||
| 1136 | |||
| 1137 | foreach ($column_names as $column_name) |
||
| 1138 | { |
||
| 1139 | $text .= "$column_name;"; |
||
| 1140 | } |
||
| 1141 | |||
| 1142 | $text .= "\r\n"; |
||
| 1143 | |||
| 1144 | # data parsing |
||
| 1145 | foreach ($rows as $key => $row) |
||
| 1146 | { |
||
| 1147 | $data["data"][$key] = []; |
||
| 1148 | |||
| 1149 | foreach ($row as $column => $value) |
||
| 1150 | { |
||
| 1151 | if ($isShowStm) |
||
| 1152 | $column++; |
||
| 1153 | |||
| 1154 | if (gettype($value) == 'object') |
||
| 1155 | { |
||
| 1156 | if (get_class($value) == 'OCI-Lob') |
||
| 1157 | { |
||
| 1158 | if (($val = @$value->load()) === false) |
||
| 1159 | { |
||
| 1160 | $val = null; # only for default, this value is not used |
||
| 1161 | $column_errors[] = $column; |
||
| 1162 | } |
||
| 1163 | |||
| 1164 | $data["data"][$key][$column] = $val; |
||
| 1165 | } |
||
| 1166 | else |
||
| 1167 | $data["data"][$key][$column] = $value; |
||
| 1168 | } |
||
| 1169 | else { |
||
| 1170 | $data["data"][$key][$column] = $value; |
||
| 1171 | } |
||
| 1172 | } |
||
| 1173 | } |
||
| 1174 | |||
| 1175 | foreach ($data["data"] as $row) |
||
| 1176 | { |
||
| 1177 | foreach ($column_names as $column_name) |
||
| 1178 | { |
||
| 1179 | $text .= $row[$column_name] . ";"; |
||
| 1180 | } |
||
| 1181 | |||
| 1182 | $text .= "\r\n"; |
||
| 1183 | } |
||
| 1184 | |||
| 1185 | $contents = $text; |
||
| 1186 | |||
| 1187 | break; |
||
| 1188 | |||
| 1189 | default: |
||
| 1190 | # code... |
||
| 1191 | break; |
||
| 1192 | } |
||
| 1193 | |||
| 1194 | if (!@fwrite($file_hd, $contents)) |
||
| 1195 | { |
||
| 1196 | $this->error(Errno::FILE_PERMISSION_DENIED, "cache/" . $filename); |
||
| 1197 | throw new \Exception("The file could not be generated!"); |
||
| 1198 | } |
||
| 1199 | |||
| 1200 | @fclose($file_hd); |
||
| 1201 | |||
| 1202 | $data["column_errors"] = $column_errors; |
||
| 1203 | |||
| 1204 | $data["filename"] = $filename; |
||
| 1205 | |||
| 1206 | if (array_key_exists('id', $post)) |
||
| 1207 | $data["id"] = $post["id"]; |
||
| 1208 | |||
| 1209 | # SUCCESS-MESSAGE |
||
| 1210 | $data["process"] = "success"; |
||
| 1211 | } |
||
| 1212 | } |
||
| 1213 | catch (\Drone\Exception\Exception $e) |
||
| 1214 | { |
||
| 1215 | # ERROR-MESSAGE |
||
| 1216 | $data["process"] = "warning"; |
||
| 1217 | $data["message"] = $e->getMessage(); |
||
| 1218 | } |
||
| 1219 | catch (\Exception $e) |
||
| 1220 | { |
||
| 1221 | $file = str_replace('\\', '', __CLASS__); |
||
| 1222 | $storage = new \Drone\Exception\Storage("cache/$file.json"); |
||
| 1223 | |||
| 1224 | # stores the error code |
||
| 1225 | if (($errorCode = $storage->store($e)) === false) |
||
| 1226 | { |
||
| 1227 | $errors = $storage->getErrors(); |
||
| 1228 | |||
| 1229 | # if error storing is not possible, handle it (internal app error) |
||
| 1230 | $this->handleErrors($errors, __METHOD__); |
||
| 1231 | } |
||
| 1232 | |||
| 1233 | # errors retrived by the use of ErrorTrait |
||
| 1234 | if (count($this->getErrors())) |
||
| 1235 | $this->handleErrors($this->getErrors(), __METHOD__); |
||
| 1236 | |||
| 1237 | $data["code"] = $errorCode; |
||
| 1238 | $data["message"] = $e->getMessage(); |
||
| 1239 | |||
| 1240 | $config = include 'config/application.config.php'; |
||
| 1241 | $data["dev_mode"] = $config["environment"]["dev_mode"]; |
||
| 1242 | |||
| 1243 | # redirect view |
||
| 1244 | $this->setMethod('error'); |
||
| 1245 | |||
| 1246 | return $data; |
||
| 1247 | } |
||
| 1248 | |||
| 1249 | return $data; |
||
| 1250 | } |
||
| 1282 | } |