├── README.md ├── comic.php ├── connections ├── character.php ├── creator.php ├── name-search.php └── single-comic.php ├── creator.php ├── index.php ├── main.js ├── php.ini └── style.css /README.md: -------------------------------------------------------------------------------- 1 | # Marvel-Character-Search-API 2 | This is a simple site one can use to search and display marvels comic character 3 | 4 | 5 | ## Technologies used 6 | * PHP 7 | * JavaScript 8 | * Bootstrap 9 | * JQuery 10 | -------------------------------------------------------------------------------- /comic.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | Marvel Character Search API 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | Home 21 |
22 |
23 | 24 |
25 |
26 | 27 | 28 | 29 | 32 | 35 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /connections/character.php: -------------------------------------------------------------------------------- 1 | 'comic', 16 | 'formatType' => 'comic', 17 | 'apikey' => $public_key, 18 | 'ts' => $ts, 19 | 'hash' => $hash, 20 | ); 21 | 22 | curl_setopt($curl, CURLOPT_URL, 23 | "https://gateway.marvel.com:443/v1/public/characters/" . $character_id . "/comics" . "?" . http_build_query($query) 24 | ); 25 | 26 | $result = json_decode(curl_exec($curl), true); 27 | 28 | curl_close($curl); 29 | 30 | echo json_encode($result); 31 | 32 | } else { 33 | echo "Character Id not defined"; 34 | } 35 | } else { 36 | echo "Error: wrong server."; 37 | } -------------------------------------------------------------------------------- /connections/creator.php: -------------------------------------------------------------------------------- 1 | $public_key, 18 | 'ts' => $ts, 19 | 'hash' => $hash, 20 | ); 21 | 22 | curl_setopt($curl, CURLOPT_URL, 23 | "https://gateway.marvel.com:443/v1/public/creators/" . $creator_id . "?" . http_build_query($query) 24 | ); 25 | 26 | $result = json_decode(curl_exec($curl), true); 27 | 28 | curl_close($curl); 29 | 30 | echo json_encode($result); 31 | 32 | } else { 33 | echo "Error comic-id invalid."; 34 | } 35 | } else { 36 | echo "Error: wrong server."; 37 | } -------------------------------------------------------------------------------- /connections/name-search.php: -------------------------------------------------------------------------------- 1 | $name_to_search, 16 | "orderBy" => "name", 17 | "limit" => "20", 18 | 'apikey' => $public_key, 19 | 'ts' => $ts, 20 | 'hash' => $hash, 21 | ); 22 | 23 | $marvel_url = 'https://gateway.marvel.com:443/v1/public/characters?' . http_build_query($query); 24 | 25 | curl_setopt($curl, CURLOPT_URL, $marvel_url); 26 | 27 | $result = json_decode(curl_exec($curl), true); 28 | 29 | curl_close($curl); 30 | 31 | echo json_encode($result); 32 | 33 | } else { 34 | echo "Error: no name given."; 35 | } 36 | } else { 37 | echo "Error: wrong server."; 38 | } -------------------------------------------------------------------------------- /connections/single-comic.php: -------------------------------------------------------------------------------- 1 | $public_key, 17 | 'ts' => $ts, 18 | 'hash' => $hash 19 | ); 20 | 21 | curl_setopt($curl, CURLOPT_URL, 22 | "https://gateway.marvel.com:443/v1/public/comics/" . $comic_id . "?" . http_build_query($query) 23 | ); 24 | 25 | $result = json_decode(curl_exec($curl), true); 26 | 27 | curl_close($curl); 28 | 29 | echo json_encode($result); 30 | 31 | } else { 32 | echo "Error invalid comic id"; 33 | } 34 | } else { 35 | echo "Error: wrong server."; 36 | } 37 | 38 | ?> -------------------------------------------------------------------------------- /creator.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | Marvel Comics API Search - Creator 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | Home 21 |
22 |
23 |
24 | 25 |
26 |
27 | 28 | 29 | 30 | 33 | 36 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | Marvel Character Search API 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 |

Marvel Character Search API

22 |
23 | 24 |
25 | 27 |
28 | 29 | 30 |
31 |
32 |
33 | 34 |
35 | 36 |
37 |
38 | 39 |
40 | 41 |
42 |
43 | 44 | 45 | 46 | 47 | 48 | 51 | 54 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | function character() { 2 | let urlQueryParameters = new URLSearchParams(window.location.search), 3 | queryParameterName = urlQueryParameters.get("name"), 4 | name = document.getElementById("name").value; 5 | 6 | 7 | 8 | if (queryParameterName !== null && queryParameterName !== "") { 9 | document.getElementById("name").value = queryParameterName; 10 | connection(); 11 | } else if (name !== null && name !== "") { 12 | document 13 | .getElementById("connectionForm") 14 | .addEventListener("submit", connection); 15 | } else { 16 | document.getElementById("characterSection").innerHTML = 17 | '

Enter character name in search bar

'; 18 | } 19 | } 20 | 21 | function connection() { 22 | document.getElementById("characterSpinnerSection").innerHTML = ""; 23 | document.getElementById("comicsSpinnerSection").innerHTML = ""; 24 | 25 | const xhr = new XMLHttpRequest(); 26 | const name = document.getElementById("name").value; 27 | const params = "name=" + name; 28 | 29 | xhr.open("GET", "./connections/name-search.php?" + params, true); 30 | xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 31 | xhr.onloadstart = function() { 32 | document.getElementById("characterSpinnerSection").innerHTML = 33 | 'Loading character...' + 34 | '
'; 36 | } 37 | xhr.onerror = function() { 38 | document.getElementById("characterSection").innerHTML = '

An error has occured, check connection.

'; 39 | } 40 | xhr.onload = function() { 41 | if (this.status == 200) { 42 | const results = JSON.parse(this.responseText); 43 | 44 | if (results["data"].count === 0) { 45 | document.getElementById("characterSection").innerHTML = 46 | '

No results for... ' + 47 | name + "" + ". Try again.

"; 48 | 49 | document.getElementById("characterSpinnerSection").innerHTML = ""; 50 | document.getElementById("comicsSpinnerSection").innerHTML = ""; 51 | 52 | } else if (results == undefined || results.length == 0) { 53 | document.getElementById("characterSection").innerHTML = 54 | '

' + 55 | "An error might have occured on our end, Sorry.
In this case, try again later.

"; 56 | 57 | document.getElementById("characterSpinnerSection").innerHTML = ""; 58 | document.getElementById("comicsSpinnerSection").innerHTML = ""; 59 | 60 | } else { 61 | const characterAttributes = results["data"].results[0], 62 | characterID = results["data"].results[0].id; 63 | let output = ""; 64 | 65 | output += 66 | '

' + 67 | "Character" + 68 | "

" + 69 | '
' + 70 | '
' + 71 | 'Picture of ' +
 73 |           characterAttributes.name +
 74 |           '' + 79 | "
" + 80 | '
' + 81 | '

' + 82 | characterAttributes.name + 83 | "

" + 84 | '

'; 85 | if (characterAttributes.description !== "") { 86 | output += characterAttributes.description; 87 | } 88 | output += 89 | "

" + 90 | '

' + 91 | "Comics: " + 92 | characterAttributes.comics.available + 93 | " | " + 94 | "Series: " + 95 | characterAttributes.series.available + 96 | " | " + 97 | "Stories: " + 98 | characterAttributes.stories.available + 99 | " | " + 100 | "Events: " + 101 | characterAttributes.events.available + 102 | "

" + 103 | '

' + 104 | results["attributionText"] + 105 | "

" + 106 | "
" + 107 | "
"; 108 | 109 | document.getElementById("characterSection").innerHTML = output; 110 | 111 | comics(characterID) 112 | } 113 | 114 | } else { 115 | document.getElementById("characterSection").innerHTML = '

Request not received

'; 116 | } 117 | } 118 | xhr.onloadend = function() { 119 | document.getElementById("characterSpinnerSection").innerHTML = ""; 120 | } 121 | xhr.send() 122 | } 123 | 124 | function comics(characterID) { 125 | const xhr = new XMLHttpRequest(); 126 | xhr.open("GET", './connections/character.php?character-id=' + characterID, true) 127 | xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 128 | xhr.onloadstart = function () { 129 | document.getElementById("comicsSpinnerSection").innerHTML = 130 | 'Loading comics below...' + 131 | '
'; 133 | } 134 | xhr.onerror = function () { 135 | document.getElementById("characterSection").innerHTML = 136 | '

An error has occured, check connection.

'; 137 | document.getElementById("comicSection").innerHTML = 138 | '

An error has occured, check connection.

'; 139 | } 140 | xhr.onload = function () { 141 | if (this.status == 200) { 142 | const results = JSON.parse(this.responseText), 143 | comics = results["data"].results, 144 | comicSection = document.getElementById("comicSection"); 145 | 146 | console.log(results) 147 | // console.log(comics) 148 | 149 | if (results["data"] == 0) { 150 | let output = ""; 151 | comicSection.innerHTML = output; 152 | comicSection.innerHTML = "

No comics Available

"; 153 | } else { 154 | // comics available 155 | let output = "", 156 | creators = ""; 157 | 158 | output += 159 | '

Comics

' + '
'; 160 | 161 | for (const i in comics) { 162 | if (comics.hasOwnProperty(i)) { 163 | const comic = comics[i]; 164 | 165 | output += 166 | '
' + 167 | '' +
174 |               comic.title +
175 |               '' + 176 | '
' + 177 | '
' + 178 | comic.title + 179 | "
"; 180 | 181 | if (comic.description != null) { 182 | output += 183 | '

' + 184 | comic.description + 185 | "

"; 186 | } 187 | 188 | output += 189 | '

Characters: '; 190 | 191 | for (const k in comic.characters.items) { 192 | if (comic.characters.items.hasOwnProperty(k)) { 193 | const character = comic.characters.items[k]; 194 | output += character.name.concat(", "); 195 | } 196 | } 197 | 198 | output += "

"; 199 | output += 200 | '

Creators: '; 201 | 202 | for (const j in comic.creators.items) { 203 | if (comic.creators.items.hasOwnProperty(j)) { 204 | const creator = comic.creators.items[j]; 205 | 206 | output += creator.name.concat(" (" + creator.role + "), "); 207 | } 208 | } 209 | 210 | output += "

"; 211 | output += 212 | "
" + 213 | '" + 218 | "
"; 219 | } 220 | } 221 | 222 | output += "
"; 223 | 224 | comicSection.innerHTML = output; 225 | 226 | } 227 | 228 | } else { 229 | document.getElementById("characterSection").innerHTML = 230 | '

Request not received

'; 231 | document.getElementById("comicSection").innerHTML = 232 | '

Request not received

'; 233 | } 234 | } 235 | xhr.onloadend = function() { 236 | document.getElementById("comicsSpinnerSection").innerHTML = 237 | 'Done.'; 238 | } 239 | xhr.send() 240 | } 241 | 242 | function singleComic() { 243 | const urlQueryParameters = new URLSearchParams(window.location.search), 244 | comicID = urlQueryParameters.get("comic-id"); 245 | singleComicContainerDiv = document.getElementById( 246 | "singleComicContainerDiv" 247 | ); 248 | 249 | const xhr = new XMLHttpRequest() 250 | 251 | xhr.open('GET', "./connections/single-comic.php?comic-id=" + comicID, true) 252 | xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 253 | xhr.onloadstart = function () { 254 | document.getElementById("comicsSpinnerSection").innerHTML = 255 | 'Loading comic info...' + 256 | '
'; 258 | } 259 | 260 | xhr.onerror = function () { 261 | singleComicContainerDiv.innerHTML = 262 | '

An error has occured, check connection.

'; 263 | } 264 | 265 | xhr.onload = function () { 266 | if (this.status == 200) { 267 | const results = JSON.parse(this.responseText), 268 | comicInfo = results["data"].results[0], 269 | comicImage = 270 | comicInfo.thumbnail["path"] + "." + comicInfo.thumbnail["extension"], 271 | comicDescription = comicInfo.description, 272 | comicCharacters = comicInfo.characters.items, 273 | comicCreators = comicInfo.creators.items; 274 | 275 | let output = ""; 276 | 277 | output += 278 | '

' + 279 | comicInfo.title + 280 | "

" + 281 | '
' + 282 | '
' + 283 | '
' + 284 | '...' + 287 | "
" + 288 | '
' + 289 | '
' + 290 | '
' + 291 | comicInfo.title + 292 | "
"; 293 | 294 | if (comicDescription !== null && comicDescription !== "") { 295 | output += '

' + comicDescription + "

"; 296 | } 297 | 298 | output += 299 | '

' + 300 | '' + 301 | " Characters: "; 302 | for (const i in comicCharacters) { 303 | if (comicCharacters.hasOwnProperty(i)) { 304 | const character = comicCharacters[i]; 305 | output += 306 | '' + 309 | character.name + 310 | ", "; 311 | } 312 | } 313 | 314 | output += 315 | "" + 316 | "

" + 317 | '

' + 318 | '' + 319 | "Creators: "; 320 | for (const i in comicCreators) { 321 | if (comicCreators.hasOwnProperty(i)) { 322 | const creator = comicCreators[i]; 323 | var url = new URL(creator.resourceURI), 324 | creatorID = url.pathname.substring( 325 | url.pathname.lastIndexOf("/") + 1 326 | ); 327 | output += 328 | '' + 331 | creator.name.concat(" (" + creator.role + "), ") + 332 | ", "; 333 | } 334 | } 335 | 336 | output += 337 | "" + 338 | "

" + 339 | "
" + 340 | "
" + 341 | "
" + 342 | '" + 345 | "
"; 346 | 347 | singleComicContainerDiv.innerHTML = output; 348 | 349 | 350 | } else { 351 | singleComicContainerDiv.innerHTML = 352 | '

Request not received

'; 353 | } 354 | } 355 | 356 | xhr.onloadend = function () { 357 | document.getElementById("comicsSpinnerSection").innerHTML = 358 | 'Done.'; 359 | } 360 | 361 | xhr.send() 362 | } 363 | 364 | function comicCreator() { 365 | const urlQueryParameters = new URLSearchParams(window.location.search), // http://localhost:8080/creator.php?creator-id=8635&name=jesushenandez 366 | creatorID = urlQueryParameters.get("creator-id"); 367 | 368 | const xhr = new XMLHttpRequest(); 369 | 370 | xhr.open("GET", "./connections/creator.php?creator-id=" + creatorID, true) 371 | xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 372 | xhr.onloadstart = function () { 373 | document.getElementById("comicCreatorSpinnerSection").innerHTML = 374 | 'Loading creator info...' + 375 | '
'; 377 | } 378 | 379 | xhr.onerror = function () { 380 | comicCreatorContainerDiv.innerHTML = 381 | '

An error has occured, check connection.

'; 382 | } 383 | 384 | xhr.onload = function () { 385 | if (this.status == 200) { 386 | const results = JSON.parse(this.responseText), 387 | creatorInfo = results["data"].results[0], 388 | creatorFullName = creatorInfo.fullName, 389 | creatorImage = 390 | creatorInfo.thumbnail["path"] + 391 | "." + 392 | creatorInfo.thumbnail["extension"], 393 | comicCreatorContainerDiv = document.getElementById( 394 | "comicCreatorContainerDiv" 395 | ), 396 | creatorComics = creatorInfo.comics.items; 397 | let output = ""; 398 | 399 | output += 400 | '

Creator

' + 401 | '
' + 402 | '
' + 403 | '
' + 404 | '' + creatorFullName + '' + 407 | "
" + // end col-md-4 408 | '
' + 409 | '
' + 410 | '
' + 411 | creatorFullName + 412 | "
"; 413 | 414 | output += 415 | '

' + 416 | "Comics: " + 417 | creatorInfo.comics["available"] + 418 | " | " + 419 | "Series: " + 420 | creatorInfo.series["available"] + 421 | " | " + 422 | "Stories: " + 423 | creatorInfo.stories["available"] + 424 | " | " + 425 | "Events: " + 426 | creatorInfo.events["available"] + 427 | "

"; 428 | 429 | output += 430 | "
" + // Card Body 431 | "
" + // col-md-8 432 | "
" + // row 433 | '" + 436 | "
"; // card 437 | 438 | output += 439 | '

Comics

' + 440 | '
'; 441 | 442 | comicCreatorContainerDiv.innerHTML = output; 443 | 444 | for (const i in creatorComics) { 445 | if (creatorComics.hasOwnProperty(i)) { 446 | const comic = creatorComics[i]; 447 | creatorSingleComic(comic.resourceURI); 448 | } 449 | } 450 | 451 | } else { 452 | comicCreatorContainerDiv.innerHTML = 453 | '

An error has occured, check connection or bad request.

'; 454 | } 455 | } 456 | 457 | xhr.onloadend = function () { 458 | document.getElementById("comicCreatorSpinnerSection").innerHTML = ""; 459 | } 460 | 461 | xhr.send() 462 | 463 | } 464 | 465 | function creatorSingleComic(comicResourceURI) { 466 | const url = new URL(comicResourceURI), 467 | comicID = url.pathname.substring(url.pathname.lastIndexOf("/") + 1), // https://lskdjflkjsd.com/kdjfls/laskdfj/847384738 468 | comicColumns = document.getElementById("comicColumns"); 469 | 470 | const xhr = new XMLHttpRequest(); 471 | xhr.open("GET", "./connections/single-comic.php?comic-id=" + comicID) 472 | xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 473 | xhr.onloadstart = function () { 474 | document.getElementById("comicCreatorSpinnerSection1").innerHTML = 475 | 'Loading comics...' + 476 | '
'; 478 | } 479 | xhr.onerror = function () { 480 | comicColumns.innerHTML == '

An error has occured.

'; 481 | } 482 | xhr.onload = function () { 483 | if (this.status == 200) { 484 | const results = JSON.parse(this.responseText), 485 | comicInfo = results["data"].results[0], 486 | comicImage = 487 | comicInfo.thumbnail["path"] + "." + comicInfo.thumbnail["extension"], 488 | comicTitle = comicInfo.title; 489 | 490 | let output = ""; 491 | 492 | output = 493 | '
' + 494 | '
' + 495 | '' + 498 | '' +
501 |         comicTitle +
502 |         '' + 503 | "" + 504 | '
' + 505 | '
' + 506 | comicTitle + 507 | "
"; 508 | 509 | if (comicInfo.description !== "" || comicInfo.description != null) { 510 | output += 511 | '

' + 512 | comicInfo.description + 513 | "

"; 514 | } 515 | output += 516 | 'Check it out!' + 519 | "
" + 520 | "
" + 521 | "
"; 522 | 523 | comicColumns.innerHTML += output; 524 | } else { 525 | comicColumns.innerHTML == '

An error has occured.

'; 526 | } 527 | } 528 | xhr.onloadend = function () { 529 | document.getElementById("comicCreatorSpinnerSection1").innerHTML = 530 | 'Done.'; 531 | } 532 | xhr.send() 533 | } -------------------------------------------------------------------------------- /php.ini: -------------------------------------------------------------------------------- 1 | error_reporting = E_ALL 2 | display_errors = On -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Roboto+Condensed:300,400,700|Roboto:300,400,700&display=swap'); 2 | 3 | body { 4 | font-family: 'Roboto Condensed', sans-serif; 5 | background-color: #22262A; 6 | } 7 | a:link, 8 | a:visited { 9 | color: #ED462F; 10 | text-decoration: none; 11 | display: inline-block; 12 | transition: all 0.2s; 13 | } 14 | 15 | a:hover, 16 | a:active { 17 | color: white; 18 | background-color: #ED462F; 19 | box-shadow: 0 1rem 2rem rgba(black, .4); 20 | transform: rotate(5deg) scale(1.2); 21 | padding: 2px; 22 | } 23 | 24 | 25 | .jumbotron { 26 | background-color: #151515; 27 | } 28 | .header-main-title { 29 | color: #fff; 30 | } 31 | .character-search-box, .search-character-button { 32 | border-radius: 0; 33 | } 34 | .search-character-button { 35 | background-color: #ED462F; 36 | } 37 | #characterMainTitle, #comicMainTitle { 38 | color: #FFFFFF; 39 | } 40 | .card { 41 | border:none; 42 | border-radius: 2px; 43 | } 44 | --------------------------------------------------------------------------------