/* global I18n */
/* global OpenLayers */
/* global $ */
/* global W */
/* global unsafeWindow */
/* global Components */
// ==UserScript==
// @name Place Harmonizer Beta
// @namespace https://greasyforks.org/en/users/19426-bmtg
// @version 1.0.26
// @description Harmonizes, formats, and locks a selected place
// @author WMEPH development group
// @include https://www.waze.com/editor/*
// @include https://www.waze.com/*/editor/*
// @include https://editor-beta.waze.com/editor/*
// @include https://editor-beta.waze.com/*/editor/*
// @exclude https://www.waze.com/user/editor/*
// @grant GM_xmlhttpRequest
// @require https://greasyforks.org/scripts/16071-wme-keyboard-shortcuts/code/WME%20Keyboard%20Shortcuts.js
// ==/UserScript==
(function () {
var WMEPHversion = "1.0.26";
var WMEPHversionMeta = WMEPHversion.match(/(\d+\.\d+)/i)[1];
var majorNewFeature = false;
var isDevVersion = true;
var USA_PNH_DATA, USA_PNH_NAMES = [], USA_CH_DATA, USA_CH_NAMES = [];
var CAN_PNH_DATA, CAN_PNH_NAMES = [], CAN_CH_DATA, CAN_CH_NAMES = [];
var WMEPHdevList, WMEPHbetaList;
var devVersStr; var devVersStrSpace; var devVersStrDash;
if (isDevVersion) { devVersStr = "Beta"; devVersStrSpace = " " + devVersStr; devVersStrDash = "-" + devVersStr; }
else { devVersStr = ""; devVersStrSpace = ""; devVersStrDash = ""; }
var WMEServicesArray = ["VALLET_SERVICE","DRIVETHROUGH","WI_FI","RESTROOMS","CREDIT_CARDS","RESERVATIONS","OUTSIDE_SEATING","AIR_CONDITIONING","PARKING_FOR_CUSTOMERS","DELIVERIES","TAKE_AWAY","WHEELCHAIR_ACCESSIBLE"];
function placeHarmonizer_bootstrap() {
var bGreasemonkeyServiceDefined = false;
try {
if ("object" === typeof Components.interfaces.gmIGreasemonkeyService) {
bGreasemonkeyServiceDefined = true;
}
}
catch (err) { //Ignore.
}
if ( "undefined" === typeof unsafeWindow || ! bGreasemonkeyServiceDefined) {
unsafeWindow = ( function () {
var dummyElem = document.createElement('p');
dummyElem.setAttribute ('onclick', 'return window;');
return dummyElem.onclick ();
} ) ();
}
/* begin running the code! */
if (("undefined" !== typeof W.loginManager)) {
setTimeout(function() {
// Pull USA PNH Data
GM_xmlhttpRequest({
method: "GET",
url: "https://docs.google.com/spreadsheets/d/1-f-JTWY5UnBx-rFTa4qhyGMYdHBZWNirUTOgn222zMY/export?format=tsv&id=1-f-JTWY5UnBx-rFTa4qhyGMYdHBZWNirUTOgn222zMY&gid=1061880663",
onload: function (response) {
//phlogdev(response.responseText);
USA_PNH_DATA = response.responseText.split('\n');
}
});
// Pull USA Category Data
GM_xmlhttpRequest({
method: "GET",
url: "https://docs.google.com/spreadsheets/d/1-f-JTWY5UnBx-rFTa4qhyGMYdHBZWNirUTOgn222zMY/export?format=tsv&id=1-f-JTWY5UnBx-rFTa4qhyGMYdHBZWNirUTOgn222zMY&gid=1898835833",
onload: function (response) {
//phlogdev(response.responseText );
USA_CH_DATA = response.responseText.split('\n');
}
});
// Pull CAN PNH Data
GM_xmlhttpRequest({
method: "GET",
url: "http://docs.google.com/spreadsheets/d/1TIxQZVLUbAJ8iH6LPTkJsvqFb_DstrHpKsJbv1W1FZs/export?format=tsv&id=1TIxQZVLUbAJ8iH6LPTkJsvqFb_DstrHpKsJbv1W1FZs&gid=947416380",
onload: function (response) {
//phlogdev(response.responseText );
CAN_PNH_DATA = response.responseText.split('\n');
}
});
// Pull UserList Data
GM_xmlhttpRequest({
method: "GET",
url: "https://docs.google.com/spreadsheets/d/1L82mM8Xg-MvKqK3WOfsMhFEGmVM46lA8BVcx8qwgmA8/export?format=tsv&id=1L82mM8Xg-MvKqK3WOfsMhFEGmVM46lA8BVcx8qwgmA8&gid=2120603213",
onload: function (response) {
var WMEPHuserList = response.responseText;
WMEPHuserList = WMEPHuserList.split("|");
var betaix = WMEPHuserList.indexOf('BETAUSERS');
WMEPHdevList = [];
WMEPHbetaList = [];
for (var ulix=1; ulix<betaix; ulix++) {
WMEPHdevList.push(WMEPHuserList[ulix].toLowerCase());
}
for (ulix=betaix+1; ulix<WMEPHuserList.length; ulix++) {
WMEPHbetaList.push(WMEPHuserList[ulix].toLowerCase());
}
}
});
}, 0);
dataReady(); // Run the code
} else {
phlog("Bootstrap failed. Trying again...");
setTimeout(function () { placeHarmonizer_bootstrap(); }, 700);
}
function dataReady() {
// If the data has returned, then start, otherwise wait a bit longer
if ("undefined" !== typeof CAN_PNH_DATA && "undefined" !== typeof USA_PNH_DATA && "undefined" !== typeof USA_CH_DATA && "undefined" !== typeof WMEPHdevList && "undefined" !== typeof WMEPHbetaList) {
setTimeout(function(){ // Build the name search lists
USA_PNH_NAMES = makeNameCheckList(USA_PNH_DATA);
USA_CH_NAMES = makeCatCheckList(USA_CH_DATA);
CAN_PNH_NAMES = makeNameCheckList(CAN_PNH_DATA);
}, 100);
setTimeout(runPH, 700); // start the main code
} else {
phlog("Waiting for PNH Data...");
setTimeout(function () { dataReady(); }, 200);
}
}
}
function runPH() {
var WMEPHWhatsNewList = ['1.0.26: Services icons work to turn on and off services.', '1.0.26: Fixed Babies R Us add-on', '1.0.25: **NEW FEATURE** - For places with no address info, it pulls localization from nearby segments. Can also add this to the place address fields if you enable the check in the prefs panel', '1.0.25: Storefinder Button indicates if it is a storefinder', '1.0.24: New messaging for script updates', '1.0.23: Improved localization for some storefinders']; // New in this version
var WMEPHWhatsNewMetaList = ['Live integration with PNH data', 'Over 700 chains harmonized', 'Works in the USA and Canada', 'Interactive banner buttons']; // New in this version
var newSep = '\n - ';
var listSep = '<li>';
var WMEPHWhatsNew = WMEPHWhatsNewList.join(newSep);
var WMEPHWhatsNewMeta = WMEPHWhatsNewMetaList.join(newSep);
var WMEPHWhatsNewHList = WMEPHWhatsNewList.join(listSep);
var WMEPHWhatsNewMetaHList = WMEPHWhatsNewMetaList.join(listSep);
WMEPHWhatsNew = 'WMEPH v. ' + WMEPHversion + '\nUpdates:' + newSep + WMEPHWhatsNew;
WMEPHWhatsNewMeta = 'WMEPH v. ' + WMEPHversionMeta + '\nMajor features:' + newSep + WMEPHWhatsNewMeta;
if ( localStorage.getItem('featuresExamined') === null ) {
localStorage.setItem('featuresExamined', '0');
}
var thisUser = W.loginManager.user;
if (thisUser === null) {
phlog("Could not determine user.");
return;
}
// If the editor installs a newer MAJOR version, pop up an alert with the new elements
if ( localStorage.getItem('WMEPHversionMeta') === null ) {
alert(WMEPHWhatsNewMeta);
localStorage.setItem('WMEPHversionMeta', WMEPHversionMeta);
localStorage.setItem('WMEPHversion', WMEPHversion);
localStorage.setItem(GLinkWarning, '0');
localStorage.setItem(SFURLWarning, '0');
localStorage.setItem('featuresExamined', '1');
} else if (localStorage.getItem('WMEPHversionMeta') !== WMEPHversionMeta) {
alert(WMEPHWhatsNewMeta);
localStorage.setItem('WMEPHversionMeta', WMEPHversionMeta);
localStorage.setItem('WMEPHversion', WMEPHversion);
localStorage.setItem(GLinkWarning, '0');
localStorage.setItem(SFURLWarning, '0');
localStorage.setItem('featuresExamined', '1');
} else if (localStorage.getItem('WMEPHversion') !== WMEPHversion) { // If minor version....
if (majorNewFeature) { // with major feature update, then alert
alert(WMEPHWhatsNew);
localStorage.setItem('featuresExamined', '1');
} else { // if not major feature update, then keep on the button
localStorage.setItem('featuresExamined', '0');
}
localStorage.setItem('WMEPHversion', WMEPHversion);
}
// initialize the KB shortcut and settings tab
setTimeout(setupKBShort, 100); // set up KB Shortcut
//setTimeout(initialiseKSU, 3000); // set up KB Shortcut
setTimeout(add_PlaceHarmonizationSettingsTab, 150); // set up settings tab
// function to prime the shortcuts
function setupKBShort() {
if (thisUser.userName.toLowerCase() === 't0cableguy') {
shortcut.add("Alt+p", function() { harmonizePlace(); });
} else if (isDevVersion) {
shortcut.add("Shift+Alt+s", function() { harmonizePlace(); });
} else {
shortcut.add("Shift+Alt+a", function() { harmonizePlace(); });
}
}
function initialiseKSU() {
/*
when adding shortcuts each shortcut will need a uniuque name
the command to add links is WMERegisterKeyboardShortcut(ScriptName, ShortcutsHeader, NewShortcut, ShortcutDescription, FunctionToCall, ShortcutKeysObj) {
ScriptName: This is the name of your script used to track all of your shortcuts on load and save.
ScriptName: replace 'WMEAwesome' with your scripts name such as 'SomeOtherScript'
ShortcutsHeader: this is the header that will show up in the keyboard editor
NewShortcut: This is the name of the shortcut and needs to be uniuque from all of the other shortcuts, from other scripts, and WME
ShortcutDescription: This wil show up as the text next to your shortcut
FunctionToCall: this is the name of your function that will be called when the keyboard shortcut is presses
ShortcutKeysObj: the is the object representing the keys watched set this to '-1' to let the users specify their own shortcuts.
ShortcutKeysObj: The alt, shift, and ctrl keys are A=alt, S=shift, C=ctrl. for short cut to use "alt shift ctrl and l" the object would be 'ASC+l'
*/
//add 3 short cuts
WMEKSRegisterKeyboardShortcut('WMEPH', 'WMEPH Script', 'WMEPH_Temp_SC1', 'Trial Shortcut', harmonizePlace, '-1'); //shortcut1
//WMEKSRegisterKeyboardShortcut('WMEAwesome', 'WME Awesome Script', 'AwesomeShortcut2', 'Awesome Descrption 2', WMEKSKyboardShortcutToCall, '-1'); //shortcut1
//WMEKSRegisterKeyboardShortcut('WMEAwesome', 'WME Awesome Script', 'AwesomeShortcut3', 'Awesome Descrption 3', WMEKSKyboardShortcutToCall, 'ASC+l'); //shortcut1
//WMERegisterKeyboardShortcut('WMEAwesome','AwesomeShortcut2','Awesome Descrption 2',doesnotexist,'-1'); //fuction does not exist
//load the saved shortcuts
//ScriptName: replace 'WMEAwesome' with your scripts name such as 'SomeOtherScript'
WMEKSLoadKeyboardShortcuts('WMEPH');
//before unloading WME save the shortcuts
//ScriptName: replace 'WMEAwesome' with your scripts name such as 'SomeOtherScript'
window.addEventListener("beforeunload", function() {
WMEKSSaveKeyboardShortcuts('WMEPH');
}, false);
}
var WMEPHurl = 'https://www.waze.com/forum/posting.php?mode=reply&f=819&t=164962'; // WMEPH Forum thread URL
var USAPNHMasURL = 'https://docs.google.com/spreadsheets/d/1-f-JTWY5UnBx-rFTa4qhyGMYdHBZWNirUTOgn222zMY/edit#gid=0'; // Master USA PNH link
var placesWikiURL = 'https://wiki.waze.com/wiki/Places';
var betaUser, devUser;
if (WMEPHbetaList.length === 0 || "undefined" === typeof WMEPHbetaList) {
alert('Beta user list access issue. Please post in the GHO or PM/DM bmtg about this message. Script should still work.');
betaUser = true;
devUser = false;
} else {
devUser = (WMEPHdevList.indexOf(thisUser.userName.toLowerCase()) > -1);
betaUser = (WMEPHbetaList.indexOf(thisUser.userName.toLowerCase()) > -1);
}
if (devUser) {
betaUser = true; // dev users are beta users
if (thisUser.userName !== 'bmtg') {
debugger;
}
}
var usrRank = thisUser.normalizedLevel; // get editor's level
var GLinkWarning = 'GLinkWarning'; // Warning message for first time using Google search to not to use the Google info itself.
if (!localStorage.getItem(GLinkWarning)) { // store settings so the warning is only given once
localStorage.setItem(GLinkWarning, '0');
}
var SFURLWarning = 'SFURLWarning'; // Warning message for first time using localized storefinder URL.
if (!localStorage.getItem(SFURLWarning)) { // store settings so the warning is only given once
localStorage.setItem(SFURLWarning, '0');
}
if (!localStorage.getItem("WMEPH-AlertNoHours" + devVersStr)) { // set default to ON if no previous setting
localStorage.setItem("WMEPH-AlertNoHours" + devVersStr, '1');
}
// lock levels are offset by one
var lockLevel1 = 0;
var lockLevel2 = 1;
var lockLevel3 = 2;
var lockLevel4 = 3;
var lockLevel5 = 4;
// Only lock up to the user's level
if (lockLevel2 > (usrRank - 1)) {lockLevel2 = (usrRank - 1);}
if (lockLevel3 > (usrRank - 1)) {lockLevel3 = (usrRank - 1);}
if (lockLevel4 > (usrRank - 1)) {lockLevel4 = (usrRank - 1);}
if (lockLevel5 > (usrRank - 1)) {lockLevel5 = (usrRank - 1);}
var defaultLockLevel = lockLevel2;
var PMUserList = { // user names and IDs
SER: {approvalActive: true, modID: '16941753', modName: 't0cableguy'},
WMEPH: {approvalActive: true, modID: '17027620', modName: 'bmtg'},
};
//var forumMsgInputs = { subject: 'Re: WMEPH', message: 'Message:', addbbcode20: '100', preview: 'Preview', attach_sig: 'on', notify: 'on' }; // Default forum post
//var forumPMInputs = { subject: 'WMEPH message', message: 'Message:', preview: 'Preview', attach_sig: 'on' }; // Default PM post
var severity; // error tracking to determine banner color (messages)
var severityButt; // error tracking to determine banner color (action buttons)
var bannButt, bannButt2, bannServ; // Banner Buttons objects
var sidebarMessageOld; // *** Eventually delete once new method is complete
var sidebarMessage; // Holds the banner messages
var bannMess = { // banner message array in order of display
bankType1: { active: false, severity: 3, message: 'Clarify the type of bank: the name has ATM but the primary category is Offices' },
gasBrandMM: { active: false, severity: 3, message: 'Gas name and brand do not appear to match. Verify which is correct.' },
gasUnbranded: { active: false, severity: 3, message: '"Unbranded" should not be used for the station brand. Change to the correct brand or use the blank entry at the top of the brand list.' },
areaNotPoint: { active: false, severity: 3, message: 'This category should be an area place. Either change it, or manually lock it.' },
areaStadium: { active: false, severity: 3, message: 'This category should be an area. Either change it, manually lock it, or consider using "Sports Court" category and a place point for small/local fields.' },
areaPostOfficeSER: { active: false, severity: 3, message: 'Only use the "Post Office" category for USPS post offices. If this is a USPS location, please change to an area place and run the script again. All other mail service places use the "Shopping and Services" Category.' },
areaHospital: { active: false, severity: 3, message: 'This category should usually be an area. Either change it, or use the "Office" category for non-emergency medical offices.' },
unmappedSER: { active: false, severity: 3, message: 'This category is usually not mapped in the SE region. If it\'s a valid place, please manually lock it.' },
pointCarDealerSER: { active: false, severity: 3, message: 'This category should be a point place, not an area.' },
nameMissing: { active: false, severity: 3, message: 'Name is missing.' },
hnMissing: { active: false, severity: 3, message: 'House number missing.' },
hnNonStandard: { active: false, severity: 3, message: 'House number is non-standard. Correct and rerun script, or manually lock the place.' },
streetMissing: { active: false, severity: 3, message: 'Street missing.' },
cityMissing: { active: false, severity: 3, message: 'City missing.' },
checkDescription: { active: false, severity: 2, message: 'Description field already contained info; PNH description was added in front of existing. Check for consistency or duplicate info.' },
resiTypeName: { active: false, severity: 2, message: 'The place name suggests a residential place. Please verify.' },
phoneInvalid: { active: false, severity: 2, message: 'Phone invalid.' },
mismatch247: { active: false, severity: 2, message: 'Hours of operation listed as open 24hrs but not for all 7 days.' },
subFuel: { active: false, severity: 1, message: 'Make sure this place is for the gas station itself and not the main store building. Otherwise undo and check the categories.' },
longURL: { active: false, severity: 1, message: 'Existing long URL was kept. Please verify.' },
catHotel: { active: false, severity: 1, message: 'Please check hotel details, as names can often be unique (e.g. Holiday Inn - Tampa North).' },
catPostOffice: { active: false, severity: 1, message: 'Verify the primary name according to your regional standards. If this is not a USPS post office, change the category, as "Post Office" is only used for USPS locations.' },
phoneMissing: { active: false, severity: 1, message: 'Phone missing.' },
urlMissing: { active: false, severity: 1, message: 'URL missing.' },
gasNoBrand: { active: false, severity: 1, message: 'Verify that gas station has no brand.' },
localURL: { active: false, severity: 0, message: 'Some locations for this business have localized urls, while others use the primary corporate site. Check if a local url applies to this location.' },
babiesRUs: { active: false, severity: 0, message: 'If there is a Toys R Us at this location, please make it the primary name and Babies R Us the alt name and rerun the script.' },
noHours: { active: false, severity: 0, message: 'Hours of operation missing.' },
generalStadium: { active: false, severity: 0, message: 'If this is a small/local ballfield or arena, consider using the "Sports Court" category and making it a point place.' },
placeFormatted: { active: false, severity: 0, message: 'Place formatted.' },
placeMatched: { active: false, severity: 0, message: 'Place matched from PNH data.' },
placeLocked: { active: false, severity: 0, message: 'Place locked.' }
};
var catTransWaze2Lang = I18n.translations['en'].venues.categories; // pulls the category translations
var item;
var newName;
var newAliases = [];
var newAliasesTemp = [];
var optionalAlias;
var newCategories = [];
var newURL;
var newPhone;
var newServices = [];
// CSS setups
var cssCode = [".PHbutton {background: #ffffff;color: #000;padding: 0px 6px 0px 6px;text-decoration: none;}",
".PHbutton:hover {background: #e8e5e8;text-decoration: none;}"];
for (var cssix=0; cssix<cssCode.length; cssix++) {
insertCss(cssCode[cssix]);
}
function insertCss( code ) {
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = code;
document.head.appendChild( style );
} // END insertCss funtion
// used for phone reformatting
if (!String.plFormat) {
String.plFormat = function(format) {
var args = Array.prototype.slice.call(arguments, 1);
return format.replace(/{(\d+)}/g, function(name, number) {
return typeof args[number] !== "undefined" ? args[number] : null;
});
};
}
// Banner production
function WMEPH_DispWarn(e) {
"use strict";
e = "<li>" + e;
var n = $('<div id="WMEPHlog">').append(e);
$("#WMEPH_logger_warn").append(n);
} // END WMEPH_DispWarn function
// Change place.name to title case
var ignoreWords = ["an", "and", "as", "at", "by", "for", "from", "hhgregg", "in", "into", "of", "on", "or", "the", "to", "with"];
var capWords = ["3M", "AMC", "AOL", "AT&T", "ATM", "BBC", "BLT", "BMV", "BMW", "BP", "CBS", "CCS", "CGI", "CISCO", "CNN", "CVS", "DHL", "DKNY",
"DMV", "DSW", "ER", "ESPN", "FCUK", "GNC", "H&M", "HP", "HSBC", "IBM", "IHOP", "IKEA", "IRS", "JBL", "JCPenney", "KFC", "LLC", "MBNA", "MCA", "MCI",
"NBC", "PNC", "TCBY", "TNT", "UPS", "USA", "USPS", "VW", "ZZZ"
];
function toTitleCase(str) {
if (!str) {
return str;
}
var allCaps = (str === str.toUpperCase());
// Cap first letter of each word
// str = str.replace(/\b([^\W_\d][^\s-\/]*) */g, function(txt) {
str = str.replace(/([A-Za-z\u00C0-\u017F][^\s-\/]*) */g, function(txt) {
return ((txt === txt.toUpperCase()) && !allCaps) ? txt : txt.charAt(0).toUpperCase() + txt.substr(1);
});
// Cap O'Reilley's, L'Amour, D'Artagnan as long as 5+ letters
str = str.replace(/[oOlLdD]'[A-Za-z']{3,}/g, function(txt) {
return ((txt === txt.toUpperCase()) && !allCaps) ? txt : txt.charAt(0).toUpperCase() + txt.charAt(1) + txt.charAt(2).toUpperCase() + txt.substr(3);
});
// Cap McFarley's, as long as 5+ letters long
str = str.replace(/[mM][cC][A-Za-z']{3,}/g, function(txt) {
return ((txt === txt.toUpperCase()) && !allCaps) ? txt : txt.charAt(0).toUpperCase() + txt.charAt(1).toLowerCase() + txt.charAt(2).toUpperCase() + txt.substr(3);
});
// anything with an "&" sign, cap the character after &
str = str.replace(/&.+/g, function(txt) {
return ((txt === txt.toUpperCase()) && !allCaps) ? txt : txt.charAt(0) + txt.charAt(1).toUpperCase() + txt.substr(2);
});
// lowercase any from the ignoreWords list
str = str.replace(/[^ ]+/g, function(txt) {
var txtLC = txt.toLowerCase();
return (ignoreWords.indexOf(txtLC) > -1) ? txtLC : txt;
});
// uppercase any from the capWords List
str = str.replace(/[^ ]+/g, function(txt) {
var txtLC = txt.toUpperCase();
return (capWords.indexOf(txtLC) > -1) ? txtLC : txt;
});
// Cap first letter of entire name
str = str.charAt(0).toUpperCase() + str.substr(1);
return str;
}
// Change place.name to title case
function toTitleCaseStrong(str) {
if (!str) {
return str;
}
var allCaps = (str === str.toUpperCase());
// Cap first letter of each word
// str = str.replace(/\b([^\W_\d][^\s-\/]*) */g, function(txt) {
str = str.replace(/([A-Za-z\u00C0-\u017F][^\s-\/]*) */g, function(txt) {
return ((txt === txt.toUpperCase()) && !allCaps) ? txt : txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
});
// Cap O'Reilley's, L'Amour, D'Artagnan as long as 5+ letters
str = str.replace(/[oOlLdD]'[A-Za-z']{3,}/g, function(txt) {
return ((txt === txt.toUpperCase()) && !allCaps) ? txt : txt.charAt(0).toUpperCase() + txt.charAt(1) + txt.charAt(2).toUpperCase() + txt.substr(3).toLowerCase();
});
// Cap McFarley's, as long as 5+ letters long
str = str.replace(/[mM][cC][A-Za-z']{3,}/g, function(txt) {
return ((txt === txt.toUpperCase()) && !allCaps) ? txt : txt.charAt(0).toUpperCase() + txt.charAt(1).toLowerCase() + txt.charAt(2).toUpperCase() + txt.substr(3).toLowerCase();
});
// anything sith an "&" sign, cap the word after &
str = str.replace(/&\w+/g, function(txt) {
return ((txt === txt.toUpperCase()) && !allCaps) ? txt : txt.charAt(0) + txt.charAt(1).toUpperCase() + txt.substr(2);
});
// lowercase any from the ignoreWords list
str = str.replace(/[^ ]+/g, function(txt) {
var txtLC = txt.toLowerCase();
return (ignoreWords.indexOf(txtLC) > -1) ? txtLC : txt;
});
// uppercase any from the capWords List
str = str.replace(/[^ ]+/g, function(txt) {
var txtLC = txt.toUpperCase();
return (capWords.indexOf(txtLC) > -1) ? txtLC : txt;
});
// Cap first letter of entire name
str = str.charAt(0).toUpperCase() + str.substr(1);
return str;
}
// Form banner Message
function formBannMess(bannKey) {
bannMess[bannKey].active = true;
severity = Math.max(bannMess[bannKey].severity, severity);
}
// Form banner Button Message
function formBannButt(bannKey) {
bannButt[bannKey].active = true;
severityButt = Math.max(bannButt[bannKey].severity, severityButt);
}
// normalize phone
function normalizePhone(s, outputFormat) {
if (!s) {
formBannMess('phoneMissing');
return s;
}
var s1 = s.replace(/\D/g, ''); // remove non-number characters
var m = s1.match(/^1?([2-9]\d{2})([2-9]\d{2})(\d{4})$/); // Ignore leading 1, and also don't allow area code or exchange to start with 0 or 1 (***USA/CAN specific)
if (!m) {
formBannMess('phoneInvalid');
return s;
} else {
return String.plFormat(outputFormat, m[1], m[2], m[3]);
}
}
// Normalize url
//function normalizeURL(placeName,s,addr) {
function normalizeURL(s) {
if (!s) { // Notify that url is missing and provide web search to find website and gather data (provided for all editors)
formBannMess('urlMissing');
formBannButt('webSearch');
return s;
}
s = s.replace(/ \(.*/g, ''); // remove anything with parentheses after it
s = s.replace(/ /g, ''); // remove any spaces
var m = s.match(/^https?:\/\/(.*)$/i); // remove http(s)://
if (m) { s = m[1]; }
s = s.replace(/[^\/]+/i, function(txt) { // lowercase the domain
return (txt === txt.toLowerCase()) ? txt : txt.toLowerCase();
});
/* OLD CODE to strip www. Keep in case of reinstatement
if ($("#WMEPH-StripWWW" + devVersStr).prop('checked')) { // if option is checked, remove 'www.' from the url
m = s.match(/^www\.(.*)$/i);
if (m) { s = m[1]; }
}
*/
m = s.match(/^(.*)\/pages\/welcome.aspx$/i); // remove unneeded terms
if (m) { s = m[1]; }
m = s.match(/^(.*)\/pages\/default.aspx$/i); // remove unneeded terms
if (m) { s = m[1]; }
m = s.match(/^(.*)\/index.html$/i); // remove unneeded terms
if (m) { s = m[1]; }
m = s.match(/^(.*)\/index.htm$/i); // remove unneeded terms
if (m) { s = m[1]; }
m = s.match(/^(.*)\/index.php$/i); // remove unneeded terms
if (m) { s = m[1]; }
m = s.match(/^(.*)\/$/i); // remove final slash
if (m) { s = m[1]; }
return s;
} // END normalizeURL function
// Only run the harmonization if a venue is selected
function harmonizePlace() {
// Script is only for R2+ editors
if (usrRank < 2) {
alert("Script is currently available for editors of Rank 2 and up.");
return;
}
// Only run if a single place is selected
if (W.selectionManager.selectedItems.length === 1) {
var item = W.selectionManager.selectedItems[0].model;
if (item.type === "venue") {
blurAll(); // focus away from current cursor position
harmonizePlaceGo();
}
}
}
// Main script
function harmonizePlaceGo() {
// Not sure what this does, but it's in all the other scripts that update Waze objects
if (isDevVersion && !betaUser) {
alert("Please sign up to beta-test this script version.\nSend a PM or Slack-DM to bmtg, or post in the WMEPH forum thread. Thanks.");
return;
}
var UpdateObject;
if (typeof(require) !== "undefined") {
UpdateObject = require("Waze/Action/UpdateObject");
} else {
UpdateObject = W.Action.UpdateObject;
}
var placePL = WMEPH_initialiseFL(); // set up external post div and pull place PL
placePL = placePL.replace(/&layers=[\d]+/g, ''); // remove Permalink Layers
var region;
var state2L;
var gFormState = "";
var newPlaceURL;
var approveRegionURL;
var PNHOrderNum = "";
var PNHNameTemp = "";
var PNHNameTempWeb = "";
sidebarMessageOld = [];
sidebarMessage = [];
// var topSBMess; // Unused, delete
severity = 0;
severityButt = 0;
var customStoreFinder = false; // switch indicating place-specific custom store finder url
var customStoreFinderLocal = false; // switch indicating place-specific custom store finder url with localization option (GPS/addr)
var customStoreFinderURL = ""; // switch indicating place-specific custom store finder url
var customStoreFinderLocalURL = ""; // switch indicating place-specific custom store finder url with localization option (GPS/addr)
for (var bannKey in bannMess) {
bannMess[bannKey].active = false;
}
bannButt = { // set up banner action buttons. Structure:
// active: false until activated in the script
// bannText: The text before the button option
// id: button id
// value: button text
// title: tooltip text
// cLog: message for console
// action: The action that happens if the button is pressed
addAlias: { // append optional Alias to the name
active: false,
bannText: "Is there a " + optionalAlias + " at this location?",
severity: 0,
id: "addAlias",
value: "Yes",
title: 'Add ' + optionalAlias,
cLog: "Added optional alt-name",
action: function() {
newAliases = insertAtIX(newAliases,optionalAlias,0);
if (specCases.indexOf('altName2Desc') > -1) {
if ( item.attributes.description.toUpperCase().indexOf(optionalAlias.toUpperCase()) === -1 ) {
newDescripion = optionalAlias + '\n' + newDescripion;
W.model.actionManager.add(new UpdateObject(item, { description: newDescripion }));
}
}
W.model.actionManager.add(new UpdateObject(item, { aliases: newAliases }));
//phlogdev(bannButt.addAlias.cLog);
bannButt.addAlias.active = false; // reset the display flag
}
}, // END addAlias definition
addCat2: { // append optional secondary category to the place
active: false,
bannText: "Is there a " + newCategories[0] + " at this location?",
severity: 0,
id: "addCat2",
value: "Yes",
title: 'Add ' + newCategories[0],
cLog: "Added optional secondary category",
action: function() {
newCategories.push.apply(newCategories,altCategories);
W.model.actionManager.add(new UpdateObject(item, { categories: newCategories }));
//phlogdev(bannButt.addCat2.cLog);
bannButt.addCat2.active = false; // reset the display flag
}
}, // END addCat2 definition
addPharm: { // append Pharmacy to the place
active: false,
bannText: "Is there a Pharmacy at this location?",
severity: 1,
id: "addPharm",
value: "Yes",
title: 'Add Pharmacy category',
cLog: "Added Pharmacy",
action: function() {
newCategories = insertAtIX(newCategories, 'PHARMACY', 1);
W.model.actionManager.add(new UpdateObject(item, {
categories: newCategories
}));
//phlogdev(bannButt.addPharm.cLog);
bannButt.addPharm.active = false; // reset the display flag
}
}, // END addPharm definition
appendAMPM: { // append AMPM to the name
active: false,
bannText: "Is there an ampm at this location?",
severity: 1,
id: "appendAMPM",
value: "Yes",
title: 'Add ampm to the place',
cLog: "Added ampm",
action: function() {
newCategories = insertAtIX(newCategories, 'CONVENIENCE_STORE', 1);
newName = 'ARCO ampm';
newURL = 'ampm.com';
W.model.actionManager.add(new UpdateObject(item, {
name: newName,
url: newURL,
categories: newCategories
}));
//phlogdev(bannButt.appendAMPM.cLog);
bannButt.appendAMPM.active = false; // reset the display flag
bannButt.addConvStore.active = false; // also reset the addConvStore display flag
}
}, // END appendAMPM definition
gasMismatch: { // if the gas brand and name don't match
active: false,
bannText: "Gas name and brand don't match. Move brand to name?",
severity: 3,
id: "gasMismatch",
value: "Yes",
title: 'Change the primary name to the brand and make the current name the alt-name.',
cLog: "Updated station name from brand",
action: function() {
newAliases = insertAtIX(newAliases, newName, 0);
W.model.actionManager.add(new UpdateObject(item, {
name: brand,
aliases: newAliases
}));
phlogdev(bannButt.gasMismatch.cLog);
bannButt.gasMismatch.active = false; // reset the display flag
newName = item.attributes.brand;
}
}, // END gasMismatch definition
STC: { // Force strong title case option
active: false, // Activated if Strong Title Case != Normal Title Case (e.g. HomeSpace Company)
bannText: "Force Title Case: ",
severity: 0,
id: "toTitleCaseStrong",
value: "Yes",
title: "Force Title Case to InterNal CaPs",
cLog: "Applied Strong Title Case",
action: function() {
newName = toTitleCaseStrong(item.attributes.name); // Get the Strong Title Case name
if (newName !== item.attributes.name) { // if they are not equal
W.model.actionManager.add(new UpdateObject(item, { // update the place name
name: newName
}));
phlogdev(bannButt.STC.cLog);
}
for (var ixali = 0; ixali < item.attributes.aliases.length; ixali++) {
newAliases[ixali] = toTitleCaseStrong(item.attributes.aliases[ixali].slice(0)); // Get the Strong Title Case name
}
phlogdev('newAliases: ' + newAliases);
phlogdev('item.attributes.aliases: ' + item.attributes.aliases);
phlogdev('check: ' + newAliases !== item.attributes.aliases);
//phlogdev(toTitleCaseStrong(item.attributes.aliases[ixali]));
if (newAliases !== item.attributes.aliases) { // if they are not equal
W.model.actionManager.add(new UpdateObject(item, { // update the place name
aliases: newAliases
}));
phlogdev(bannButt.STC.cLog);
}
bannButt.STC.active = false; // reset the display flag
}
}, // END Strong Title Case definition
addATM: {
active: false,
bannText: "ATM at location? ",
severity: 0,
id: "addATM",
value: "Yes",
title: "Add the ATM category to this place",
cLog: "Added ATM category",
action: function() {
newCategories = insertAtIX(newCategories,"ATM",1); // Insert ATM category in the second position
W.model.actionManager.add(new UpdateObject(item, { // update the place name
categories: newCategories
}));
bannButt.addATM.active = false; // reset the display flag
}
}, // END addATM definition
standaloneATM: {
active: false,
bannText: "Is this a standalone ATM? ",
severity: 2,
id: "standaloneATM",
value: "Yes",
title: "Is this a standalone ATM with no bank branch?",
cLog: "Changed to standalone ATM",
action: function() {
newCategories = ["ATM"]; // Change to ATM only
if (newName.indexOf("ATM") === -1) {
newName = newName + ' ATM';
}
W.model.actionManager.add(new UpdateObject(item, { categories: newCategories }));
bannButt.bankCorporate.active = false; // reset the bank Branch display flag
bannButt.bankBranch.active = false; // reset the bank Branch display flag
bannButt.standaloneATM.active = false; // reset the standalone ATM display flag
}
}, // END standaloneATM definition
bankBranch: {
active: false,
bannText: "Is this a bank branch office? ",
severity: 1,
id: "bankBranch",
value: "Yes",
title: "Is this a bank branch office?",
cLog: "Changed to bank branch",
action: function() {
newCategories = ["BANK_FINANCIAL","ATM"]; // Change to bank and atm cats
newName = newName.replace(/[\- (]*ATM[\- )]*/g, ' ').replace(/^ /g,'').replace(/ $/g,''); // strip ATM from name if present
W.model.actionManager.add(new UpdateObject(item, { categories: newCategories }));
W.model.actionManager.add(new UpdateObject(item, { name: newName }));
bannButt.bankCorporate.active = false; // reset the bank Branch display flag
bannButt.bankBranch.active = false; // reset the bank Branch display flag
bannButt.standaloneATM.active = false; // reset the standalone ATM display flag
}
}, // END bankBranch definition
bankCorporate: {
active: false,
bannText: "Is this the bank's corporate offices?",
severity: 1,
id: "bankCorporate",
value: "Yes",
title: "Is this the bank's corporate offices?",
cLog: "Changed to bank branch",
action: function() {
newCategories = ["OFFICES"]; // Change to offices category
newName = newName.replace(/[\- (]*ATM[\- )]*/g, ' ').replace(/^ /g,'').replace(/ $/g,''); // strip ATM from name if present
W.model.actionManager.add(new UpdateObject(item, { categories: newCategories }));
W.model.actionManager.add(new UpdateObject(item, { name: newName }));
bannButt.bankCorporate.active = false; // reset the bank Branch display flag
bannButt.bankBranch.active = false; // reset the bank Branch display flag
bannButt.standaloneATM.active = false; // reset the standalone ATM display flag
}
}, // END bankCorporate definition
addConvStore: {
active: false,
bannText: "Add convenience store category? ",
severity: 1,
id: "addConvStore",
value: "Yes",
title: "Add the Convenience Store category to this place",
cLog: "Added Convenience Store category",
action: function() {
newCategories = insertAtIX(newCategories,"CONVENIENCE_STORE",1); // Insert C.S. category in the second position
W.model.actionManager.add(new UpdateObject(item, { // update
categories: newCategories
}));
bannButt.addConvStore.active = false; // reset the display flag
}
}, // END addConvStore definition
isitUSPS: {
active: false,
bannText: "Is this a USPS location? ",
severity: 0,
id: "isitUSPS",
value: "Yes",
title: "Is this a USPS location?",
cLog: "Fixed USPS",
action: function() {
newServices = ["AIR_CONDITIONING", "CREDIT_CARDS", "PARKING_FOR_CUSTOMERS", "WHEELCHAIR_ACCESSIBLE"];
W.model.actionManager.add(new UpdateObject(item, { url: "usps.com" }));
if (region === 'SER') {
W.model.actionManager.add(new UpdateObject(item, { aliases: ["United States Postal Service"] }));
}
bannButt.isitUSPS.active = false;
}
}, // END isitUSPS definition
PlaceWebsite: {
active: false,
bannText: "",
severity: 0,
id: "PlaceWebsite",
value: "Open place website",
title: "Direct link to place website",
cLog: "Open web search",
action: function() {
var openPlaceWebsiteURL = 'http:\/\/' + newURL;
if (customStoreFinder) {
openPlaceWebsiteURL = customStoreFinderURL;
} else if (customStoreFinderLocal) {
openPlaceWebsiteURL = customStoreFinderLocalURL;
}
if (localStorage.getItem(SFURLWarning) === '0' && customStoreFinderLocal) {
if (confirm('***Localized store finder sites often show multiple nearby results. Please make sure you pick the right location.\nClick OK to agree and continue.') ) { // if the category doesn't translate, then pop an alert that will make a forum post to the thread
localStorage.setItem(SFURLWarning, '1');
window.open(openPlaceWebsiteURL);
}
} else {
window.open(openPlaceWebsiteURL);
}
}
}, // END PlaceWebsite definition
webSearch: {
active: false,
bannText: "",
severity: 0,
id: "webSearch",
value: "Web Search",
title: "Search the web for this place. Do not copy info from 3rd party sources!",
cLog: "Open web search",
action: function() {
if (localStorage.getItem(GLinkWarning) === '1') {
window.open(buildGLink(newName,addr,item.attributes.houseNumber));
} else {
if (confirm('***Please DO NOT copy info from Google or third party sources.*** This link is to help you find the business webpage.\nClick OK to agree and continue.') ) { // if the category doesn't translate, then pop an alert that will make a forum post to the thread
localStorage.setItem(GLinkWarning, '1');
window.open(buildGLink(newName,addr,item.attributes.houseNumber));
}
}
}
}, // END webSearch definition
NewPlaceSubmit: {
active: false,
bannText: "No PNH match. If place is a chain: ",
severity: 0,
id: "NewPlaceSubmit",
value: "Submit new data",
title: "Submit info for a new chain through the linked form",
cLog: "Open submit new place form",
action: function() {
window.open(newPlaceURL);
}
}, // END NewPlaceSubmit definition
ApprovalSubmit: {
active: false,
bannText: "PNH data exists but is not approved for your region: ",
severity: 0,
id: "ApprovalSubmit",
value: "Request approval",
title: "Request region/country approval of this place",
cLog: "Open request approval form",
action: function() {
if (PMUserList.hasOwnProperty(region)) {
if (PMUserList[region].approvalActive) {
var forumPMInputs = {
subject: 'PNH approval for "' + PNHNameTemp + '"',
message: 'Please approve "' + PNHNameTemp + '" for the ' + region + ' region. Thanks\n \nPNH order number: ' + PNHOrderNum + '\n \nExample Permalink: ' + placePL + '\n \nPNH Link: ' + USAPNHMasURL,
preview: 'Preview', attach_sig: 'on'
};
forumPMInputs['address_list[u]['+PMUserList[region].modID+']'] = 'to'; // SER region, sends a PM to t0cableguy = 16941753
WMEPH_openPostDataInNewTab('https://www.waze.com/forum/ucp.php?i=pm&mode=compose', forumPMInputs);
} else {
window.open(approveRegionURL);
}
} else {
window.open(approveRegionURL);
}
}
} // END ApprovalSubmit definition
};
bannButt2 = {
placesWiki: {
active: true,
bannText: "",
severity: 0,
id: "placesWiki",
value: "Places wiki",
title: "Open the places wiki page",
cLog: "Opened places wiki",
action: function() {
window.open(placesWikiURL);
}
}, // END placesWiki definition
PlaceErrorForumPost: {
active: true,
bannText: "",
severity: 0,
id: "PlaceErrorForumPost",
value: "Report script error",
title: "Report an error on the forum",
cLog: "Post initiated",
action: function() {
var forumMsgInputs = {
subject: 'Re: WMEPH Bug report',
message: 'Permalink: ' + placePL + '\nPlace name: ' + item.attributes.name + '\nCountry: ' + addr.country.name + '\nDescribe the error:\n ',
addbbcode20: '100', preview: 'Preview', attach_sig: 'on', notify: 'on'
};
WMEPH_openPostDataInNewTab(WMEPHurl + '#preview', forumMsgInputs);
}
}, // END PlaceErrorForumPost definition
whatsNew: {
active: false,
bannText: "",
severity: 0,
id: "whatsNew",
value: "Recent script updates",
title: "Open a list of recent script updates",
cLog: "Opened script update alert",
action: function() {
alert(WMEPHWhatsNew);
localStorage.setItem('featuresExamined', '1');
}
} // END whatsNew definition
}; // END bannButt2 definitions
if (localStorage.getItem('featuresExamined') === '0') {
bannButt2.whatsNew.active = true;
}
var servID;
bannServ = { // set up banner action buttons. Structure:
// active: false until activated in the script
// bannText: The text before the button option
// id: button id
// value: button text
// title: tooltip text
// cLog: message for console
// action: The action that happens if the button is pressed
addValet: { // append optional Alias to the name
active: false,
checked: false,
removed: false,
id: "addValet",
icon: "serv-valet",
value: "Valet",
title: 'Valet',
cLog: "Toggled Valet Service",
action: function() {
servID = WMEServicesArray[0];
if ( ($("#service-checkbox-"+servID).prop('checked') && bannServ.addValet.checked) ||
(!$("#service-checkbox-"+servID).prop('checked') && !bannServ.addValet.checked) ) {
$("#service-checkbox-"+servID).trigger('click');
}
updateServicesChecks(bannServ);
phlogdev(bannServ.addValet.cLog);
}
}, // END addValet definition
addDriveThru: { // append optional Alias to the name
active: false,
checked: false,
id: "addDriveThru",
icon: "serv-drivethru",
value: "DriveThru",
title: 'Drive-Thru',
cLog: "Toggled Drive-Thru service",
action: function() {
servID = WMEServicesArray[1];
if ( ($("#service-checkbox-"+servID).prop('checked') && bannServ.addDriveThru.checked) ||
(!$("#service-checkbox-"+servID).prop('checked') && !bannServ.addDriveThru.checked) ) {
$("#service-checkbox-"+servID).trigger('click');
}
updateServicesChecks(bannServ);
phlogdev(bannServ.addDriveThru.cLog);
}
}, // END addDriveThru definition
addWiFi: { // append optional Alias to the name
active: false,
checked: false,
id: "addWiFi",
icon: "serv-wifi",
value: "WiFi",
title: 'WiFi',
cLog: "Toggled WiFi service",
action: function() {
servID = WMEServicesArray[2];
if ( ($("#service-checkbox-"+servID).prop('checked') && bannServ.addWiFi.checked) ||
(!$("#service-checkbox-"+servID).prop('checked') && !bannServ.addWiFi.checked) ) {
$("#service-checkbox-"+servID).trigger('click');
}
updateServicesChecks(bannServ);
phlogdev(bannServ.addWiFi.cLog);
}
}, // END addWiFi definition
addRestrooms: { // append optional Alias to the name
active: false,
checked: false,
id: "addRestrooms",
icon: "serv-restrooms",
value: "Restroom",
title: 'Restrooms',
cLog: "Toggled Restroom service",
action: function() {
servID = WMEServicesArray[3];
if ( ($("#service-checkbox-"+servID).prop('checked') && bannServ.addRestrooms.checked) ||
(!$("#service-checkbox-"+servID).prop('checked') && !bannServ.addRestrooms.checked) ) {
$("#service-checkbox-"+servID).trigger('click');
}
updateServicesChecks(bannServ);
phlogdev(bannServ.addRestrooms.cLog);
}
}, // END addRestrooms definition
addCreditCards: { // append optional Alias to the name
active: false,
checked: false,
id: "addCreditCards",
icon: "serv-credit",
value: "CC",
title: 'Credit Cards',
cLog: "Toggled Credit Card service",
action: function() {
servID = WMEServicesArray[4];
if ( ($("#service-checkbox-"+servID).prop('checked') && bannServ.addCreditCards.checked) ||
(!$("#service-checkbox-"+servID).prop('checked') && !bannServ.addCreditCards.checked) ) {
$("#service-checkbox-"+servID).trigger('click');
}
updateServicesChecks(bannServ);
phlogdev(bannServ.addCreditCards.cLog);
}
}, // END addCreditCards definition
addReservations: { // append optional Alias to the name
active: false,
checked: false,
id: "addReservations",
icon: "serv-reservations",
value: "Reserve",
title: 'Reservations',
cLog: "Toggled Reservations service",
action: function() {
servID = WMEServicesArray[5];
if ( ($("#service-checkbox-"+servID).prop('checked') && bannServ.addReservations.checked) ||
(!$("#service-checkbox-"+servID).prop('checked') && !bannServ.addReservations.checked) ) {
$("#service-checkbox-"+servID).trigger('click');
}
updateServicesChecks(bannServ);
phlogdev(bannServ.addReservations.cLog);
}
}, // END addReservations definition
addOutside: { // append optional Alias to the name
active: false,
checked: false,
id: "addOutside",
icon: "serv-outdoor",
value: "OusideSeat",
title: 'Outside Seating',
cLog: "Toggled Outside Seating service",
action: function() {
servID = WMEServicesArray[6];
if ( ($("#service-checkbox-"+servID).prop('checked') && bannServ.addOutside.checked) ||
(!$("#service-checkbox-"+servID).prop('checked') && !bannServ.addOutside.checked) ) {
$("#service-checkbox-"+servID).trigger('click');
}
updateServicesChecks(bannServ);
phlogdev(bannServ.addOutside.cLog);
}
}, // END addOutside definition
addAC: { // append optional Alias to the name
active: false,
checked: false,
id: "addAC",
icon: "serv-ac",
value: "AC",
title: 'AC',
cLog: "Toggled Air Conditioning service",
action: function() {
servID = WMEServicesArray[7];
if ( ($("#service-checkbox-"+servID).prop('checked') && bannServ.addAC.checked) ||
(!$("#service-checkbox-"+servID).prop('checked') && !bannServ.addAC.checked) ) {
$("#service-checkbox-"+servID).trigger('click');
}
updateServicesChecks(bannServ);
phlogdev(bannServ.addAC.cLog);
}
}, // END addAC definition
addParking: { // append optional Alias to the name
active: false,
checked: false,
id: "addParking",
icon: "serv-parking",
value: "Parking",
title: 'Parking',
cLog: "Toggled Parking for Customers service",
action: function() {
servID = WMEServicesArray[8];
if ( ($("#service-checkbox-"+servID).prop('checked') && bannServ.addParking.checked) ||
(!$("#service-checkbox-"+servID).prop('checked') && !bannServ.addParking.checked) ) {
$("#service-checkbox-"+servID).trigger('click');
}
updateServicesChecks(bannServ);
phlogdev(bannServ.addParking.cLog);
}
}, // END addParking definition
addDeliveries: { // append optional Alias to the name
active: false,
checked: false,
id: "addDeliveries",
icon: "serv-deliveries",
value: "Delivery",
title: 'Deliveries',
cLog: "Toggled Delivery service",
action: function() {
servID = WMEServicesArray[9];
if ( ($("#service-checkbox-"+servID).prop('checked') && bannServ.addDeliveries.checked) ||
(!$("#service-checkbox-"+servID).prop('checked') && !bannServ.addDeliveries.checked) ) {
$("#service-checkbox-"+servID).trigger('click');
}
updateServicesChecks(bannServ);
phlogdev(bannServ.addDeliveries.cLog);
}
}, // END addDeliveries definition
addTakeAway: { // append optional Alias to the name
active: false,
checked: false,
id: "addTakeAway",
icon: "serv-takeaway",
value: "TakeOut",
title: 'Take Out',
cLog: "Toggled Take Out service",
action: function() {
servID = WMEServicesArray[10];
if ( ($("#service-checkbox-"+servID).prop('checked') && bannServ.addTakeAway.checked) ||
(!$("#service-checkbox-"+servID).prop('checked') && !bannServ.addTakeAway.checked) ) {
$("#service-checkbox-"+servID).trigger('click');
}
updateServicesChecks(bannServ);
phlogdev(bannServ.addTakeAway.cLog);
}
}, // END addTakeAway definition
addWheelchair: { // add service
active: false,
checked: false,
bannText: "",
icon: "serv-wheelchair",
id: "addWheelchair",
value: "WhCh",
title: 'Wheelchair Accessible',
cLog: "Toggled Wheelchair Accessible service",
action: function() {
servID = WMEServicesArray[11];
if ( ($("#service-checkbox-"+servID).prop('checked') && bannServ.addWheelchair.checked) ||
(!$("#service-checkbox-"+servID).prop('checked') && !bannServ.addWheelchair.checked) ) {
$("#service-checkbox-"+servID).trigger('click');
}
updateServicesChecks(bannServ);
phlogdev(bannServ.addWheelchair.cLog);
}
}// END addWheelchair definition
};
//Setting switch for the Places Wiki button
if ( $("#WMEPH-HidePlacesWiki" + devVersStr).prop('checked') ) {
bannButt2.placesWiki.active = false;
}
// provide Google search link to places
if (devUser || betaUser || usrRank > 2) { // enable the link for all places, for R4+ and betas
formBannButt('webSearch');
}
// Only can select one place at a time in WME, so the loop is superfluous (eg, ix=0 will work), but perhaps we leave it in case we add some sort of looping process like URs.
for (var ix = 0; ix < W.selectionManager.selectedItems.length; ix++) {
item = W.selectionManager.selectedItems[ix].model;
// get GPS lat/long coords from place
var itemGPS = OpenLayers.Layer.SphericalMercator.inverseMercator(item.attributes.geometry.bounds.right,item.attributes.geometry.bounds.top);
phlogdev("Place GPS coords: "+itemGPS);
var lockOK = true; // if nothing goes wrong, then place will be locked
var categories = item.attributes.categories;
newCategories = categories.slice(0);
newName = item.attributes.name;
newName = toTitleCase(newName);
// var nameShort = newName.replace(/[^A-Za-z]/g, ''); // strip non-letters for PNH name searching
// var nameNumShort = newName.replace(/[^A-Za-z0-9]/g, ''); // strip non-letters/non-numbers for PNH name searching
newAliases = item.attributes.aliases.slice(0);
var brand = item.attributes.brand;
var newDescripion = item.attributes.description;
newURL = item.attributes.url;
var newURLSubmit = "";
if (newURL !== null) {
newURLSubmit = newURL;
}
newPhone = item.attributes.phone;
var newServices = [];
for (var nsix=0; nsix<item.attributes.services.length; nsix++) {
newServices[nsix]= item.attributes.services[nsix];
}
//phlogdev(newServices);
var newServices2 = [];
newServices2.push(item.attributes.services);
//phlogdev(newServices2);
var addr = item.getAddress();
var PNHNameRegMatch;
function WMEPH_inferAddress() {
'use strict';
var city,
country,
distanceToSegment,
inferredAddress = {
country: null ,
city: null ,
state: null ,
street: null
},
i,
// Ignore pedestrian boardwalk, stairways, runways, and railroads
ignoreRoadTypes = [10, 16, 18, 19],
n,
orderedSegments = [],
segments = W.model.segments.getObjectArray(),
selectedItem,
state,
street,
wmeSelectedItems = W.selectionManager.selectedItems;
//phlogdev("No address data, gathering ", 2);
// Make sure a place is selected.
if (wmeSelectedItems.length > 0 && wmeSelectedItems[0].model.type === 'venue') {
selectedItem = W.selectionManager.selectedItems[0];
} else {
return;
}
// Go through segment array and calculate distances to segments.
for (i = 0,
n = segments.length; i < n; i++) {
// Make sure the segment is not an ignored roadType.
if (ignoreRoadTypes.indexOf(segments[i].attributes.roadType) === -1) {
if (selectedItem.model.isPoint()) {
distanceToSegment = selectedItem.geometry.distanceTo(segments[i].geometry);
} else {
distanceToSegment = W.geometryEditing.editors.venue.navigationPoint.lonlat
.toPoint().distanceTo(segments[i].geometry);
}
// Add segment object and its distanceTo to an array.
orderedSegments.push({
segment: segments[i],
distance: distanceToSegment
});
}
}
// Sort the array with segments and distance.
orderedSegments = _.sortBy(orderedSegments, 'distance');
// Go through sorted segment array until a country, state, and city have been found.
for (i = 0,
n = orderedSegments.length; i < n; i++) {
street = W.model.streets.get(orderedSegments[i].segment.attributes.primaryStreetID);
city = W.model.cities.get(street.cityID);
state = W.model.states.get(city.stateID);
country = W.model.countries.get(city.countryID);
if (inferredAddress.street === null && street.name !== '') {
inferredAddress.street = street;
}
if (inferredAddress.city === null && city.name !== '') {
inferredAddress.city = city;
}
if (inferredAddress.state === null && state.name !== '') {
inferredAddress.state = state;
}
if (inferredAddress.country === null && country.name !== '') {
inferredAddress.country = country;
}
// Stop looking for info if city, state, and country have been found.
if (inferredAddress.street && inferredAddress.city && inferredAddress.state &&
inferredAddress.country) {
break;
}
}
return inferredAddress;
}
/**
* Updates the address for a place.
* @param feature {WME Venue Object} The place to update.
* @param address {Object} An object containing the country, state, city, and street
* objects.
*/
function updateAddress(feature, address) {
'use strict';
var newAttributes,
UpdateFeatureAddress = require('Waze/Action/UpdateFeatureAddress');
feature = feature || item;
if (feature && address && address.state && address.country) {
newAttributes = {
countryID: address.country.id,
stateID: address.state.id,
cityName: address.city.name,
emptyCity: address.city.name ? null : true,
streetName: address.street.name,
emptyStreet: address.street.name ? null : true
};
W.model.actionManager.add(new UpdateFeatureAddress(feature, newAttributes));
}
}
// Some user submitted places have no data in the country, state and address fields. Need to have that to make the localization work.
if (!addr.state || !addr.country) {
var inferredAddress = WMEPH_inferAddress();
if (inferredAddress.state && inferredAddress.country) {
addr = inferredAddress;
if ( $("#WMEPH-AddAddresses" + devVersStr).prop('checked') ) {
updateAddress(item, addr);
}
} else {
alert("Place has no address data. Please set at least a city and rerun the script.");
return; // don't run the script
}
}
// Country restrictions
var countryCode;
if (addr.country.name === "United States") {
countryCode = "USA";
} else if (addr.country.name === "Canada") {
countryCode = "CAN";
} else {
alert("At present this script is not supported in this country.");
return;
}
if (countryCode === "USA") {
// Setup USA State and Regional vars
switch (addr.state.name) {
case "Arkansas": state2L = "AR"; region = "SCR"; gFormState = "&entry.124157720=AR"; break;
case "Louisiana": state2L = "LA"; region = "SCR"; gFormState = "&entry.124157720=LA"; defaultLockLevel = lockLevel4; break; // lock level from wiki/forum
case "Mississippi": state2L = "MS"; region = "SCR"; gFormState = "&entry.124157720=MS"; break;
case "Oklahoma": state2L = "OK"; region = "SCR"; gFormState = "&entry.124157720=OK"; break;
case "Texas": state2L = "TX"; region = "TX"; gFormState = "&entry.1252443068=TX"; defaultLockLevel = lockLevel1; break; // lock level from wiki
case "Alaska": state2L = "AK"; region = "NWR"; gFormState = "&entry.124157720=AK"; break;
case "Idaho": state2L = "ID"; region = "NWR"; gFormState = "&entry.124157720=ID"; break;
case "Montana": state2L = "MT"; region = "NWR"; gFormState = "&entry.124157720=MT"; break;
case "Oregon": state2L = "OR"; region = "NWR"; gFormState = "&entry.124157720=OR"; break;
case "Washington": state2L = "WA"; region = "NWR"; gFormState = "&entry.124157720=WA"; defaultLockLevel = lockLevel3; break; // lock level from wiki
case "Wyoming": state2L = "WY"; region = "NWR"; gFormState = "&entry.124157720=WY"; break;
case "Hawaii": state2L = "HI"; region = "HI"; gFormState = "&entry.124157720=HI"; defaultLockLevel = lockLevel3; break; // lock level from wiki
case "Arizona": state2L = "AZ"; region = "SWR"; gFormState = "&entry.124157720=AZ"; defaultLockLevel = lockLevel2; break; // lock level from wiki
case "California": state2L = "CA"; region = "SWR"; gFormState = "&entry.124157720=CA"; defaultLockLevel = lockLevel3; break; // lock level from wiki
case "Colorado": state2L = "CO"; region = "SWR"; gFormState = "&entry.124157720=CO"; defaultLockLevel = lockLevel4; break; // lock level from wiki/forum
case "Nevada": state2L = "NV"; region = "SWR"; gFormState = "&entry.124157720=NV"; defaultLockLevel = lockLevel2; break; // lock level from wiki
case "New Mexico": state2L = "NM"; region = "SWR"; gFormState = "&entry.124157720=NM"; defaultLockLevel = lockLevel2; break; // lock level from wiki
case "Utah": state2L = "UT"; region = "SWR"; gFormState = "&entry.124157720=UT"; defaultLockLevel = lockLevel2; break; // lock level from wiki
case "Iowa": state2L = "IA"; region = "PLN"; gFormState = "&entry.124157720=IA"; break;
case "Kansas": state2L = "KS"; region = "PLN"; gFormState = "&entry.124157720=KS"; break;
case "Minnesota": state2L = "MN"; region = "PLN"; gFormState = "&entry.124157720=MN"; defaultLockLevel = lockLevel2; break; // lock level from wiki
case "Missouri": state2L = "MO"; region = "PLN"; gFormState = "&entry.124157720=MO"; defaultLockLevel = lockLevel2; break; // lock level from wiki
case "Nebraska": state2L = "NE"; region = "PLN"; gFormState = "&entry.124157720=NE"; break;
case "North Dakota": state2L = "ND"; region = "PLN"; gFormState = "&entry.124157720=ND"; break;
case "South Dakota": state2L = "SD"; region = "PLN"; gFormState = "&entry.124157720=SD"; break;
case "Illinois": state2L = "IL"; region = "GLR"; gFormState = "&entry.124157720=IL"; break;
case "Indiana": state2L = "IN"; region = "GLR"; gFormState = "&entry.124157720=IN"; break;
case "Michigan": state2L = "MI"; region = "GLR"; gFormState = "&entry.124157720=MI"; defaultLockLevel = lockLevel3; break; // lock level from wiki
case "Ohio": state2L = "OH"; region = "GLR"; gFormState = "&entry.124157720=OH"; break;
case "Wisconsin": state2L = "WI"; region = "GLR"; gFormState = "&entry.124157720=WI"; defaultLockLevel = lockLevel3; break; // lock level from wiki
case "Kentucky": state2L = "KY"; region = "SAT"; gFormState = "&entry.1025078817=KY+-+Kentucky"; defaultLockLevel = lockLevel3; break; // lock level from wiki
case "North Carolina": state2L = "NC"; region = "SAT"; gFormState = "&entry.1025078817=NC+-+North+Carolina"; defaultLockLevel = lockLevel3; break; // lock level from wiki
case "South Carolina": state2L = "SC"; region = "SAT"; gFormState = "&entry.1025078817=SC+-+South+Carolina"; defaultLockLevel = lockLevel3; break; // lock level from wiki
case "Tennessee": state2L = "TN"; region = "SAT"; gFormState = "&entry.1025078817=TN+-+Tennessee"; defaultLockLevel = lockLevel3; break; // lock level from wiki
case "Alabama": state2L = "AL"; region = "SER"; gFormState = "&entry.2010899807=AL+-+Alabama"; defaultLockLevel = lockLevel3; break; // lock level from wiki
case "Florida": state2L = "FL"; region = "SER"; gFormState = "&entry.2010899807=FL+-+Florida"; defaultLockLevel = lockLevel3; break; // lock level from wiki
case "Georgia": state2L = "GA"; region = "SER"; gFormState = "&entry.2010899807=GA+-+Georgia"; defaultLockLevel = lockLevel3; break; // lock level from wiki
case "Connecticut": state2L = "CT"; region = "NEW"; gFormState = "&entry.124157720=CT"; break;
case "Maine": state2L = "ME"; region = "NEW"; gFormState = "&entry.124157720=ME"; defaultLockLevel = lockLevel2; break; // lock level from wiki
case "Massachusetts": state2L = "MA"; region = "NEW"; gFormState = "&entry.124157720=MA"; defaultLockLevel = lockLevel2; break; // lock level from wiki
case "New Hampshire": state2L = "NH"; region = "NEW"; gFormState = "&entry.124157720=NH"; defaultLockLevel = lockLevel2; break; // lock level from wiki
case "Rhode Island": state2L = "RI"; region = "NEW"; gFormState = "&entry.124157720=RI"; defaultLockLevel = lockLevel2; break;
case "Vermont": state2L = "VT"; region = "NEW"; gFormState = "&entry.124157720=VT"; defaultLockLevel = lockLevel2; break; // lock level from wiki
case "Delaware": state2L = "DE"; region = "NOR"; gFormState = "&entry.124157720=DE"; break;
case "New Jersey": state2L = "NJ"; region = "NOR"; gFormState = "&entry.124157720=NJ"; break;
case "New York": state2L = "NY"; region = "NOR"; gFormState = "&entry.124157720=NY"; break;
case "Pennsylvania": state2L = "PA"; region = "NOR"; gFormState = "&entry.124157720=PA"; break;
case "District of Columbia": state2L = "DC"; region = "MAR"; gFormState = "&entry.124157720=DC"; defaultLockLevel = lockLevel2; break; // lock level from wiki
case "Maryland": state2L = "MD"; region = "MAR"; gFormState = "&entry.124157720=MD"; defaultLockLevel = lockLevel2; break; // lock level from wiki
case "Virginia": state2L = "VA"; region = "MAR"; gFormState = "&entry.124157720=VA"; defaultLockLevel = lockLevel2; break; // lock level from wiki
case "West Virginia": state2L = "WV"; region = "MAR"; gFormState = "&entry.124157720=WV"; defaultLockLevel = lockLevel2; break; // lock level from wiki
default: state2L = "Unknown"; region = "Unknown";
}
phlog("Place is in region " + region);
} // END USA regional/state assigning
if (countryCode === "CAN") {
// Setup Canadian provinces
defaultLockLevel = lockLevel3;
switch (addr.state.name) {
case "Ontario": state2L = "ON"; region = "CAN"; break;
case "British Columbia": state2L = "BC"; region = "CAN"; break;
case "Alberta": state2L = "AB"; region = "CAN"; break;
case "Saskatchewan": state2L = "SK"; region = "CAN"; break;
case "Manitoba": state2L = "MB"; region = "CAN"; break;
case "Ontario": state2L = "ON"; region = "CAN"; break;
case "Quebec": state2L = "QC"; region = "CAN"; break;
case "Newfoundland And Labrador": state2L = "NL"; region = "CAN"; break;
case "New Brunswick": state2L = "NB"; region = "CAN"; break;
case "Prince Edward Island": state2L = "PE"; region = "CAN"; break;
case "Nova Scotia": state2L = "NS"; region = "CAN"; break;
case "Nunavut": state2L = "NU"; region = "CAN"; break;
case "Northwest Territories": state2L = "NT"; region = "CAN"; break;
case "Yukon": state2L = "YT"; region = "CAN"; break;
default: state2L = "Unknown"; region = "Unknown";
}
phlog("Place is in province: " + state2L);
} // END Canada assignments
// If region or state is unknown, report the error
if (state2L === "Unknown" || region === "Unknown") {
if (confirm('WMEPH: Localization Error\nClick OK to report this error') ) { // if the location is not found, then pop an alert that will make a forum post to the thread
var forumMsgInputs = {
subject: 'Re: WMEPH Bug report',
message: 'Error report: State name "' + addr.state.name + '" is not found.',
addbbcode20: '100', preview: 'Preview', attach_sig: 'on', notify: 'on'
};
WMEPH_openPostDataInNewTab(WMEPHurl + '#preview', forumMsgInputs);
}
return;
}
// Clear attributes from residential places
if (item.attributes.residential) {
newName = item.attributes.houseNumber + " " + addr.street.name;
if (item.attributes.name !== newName) { // Set the residential place name to the address (to clear any personal info)
phlogdev("Residential Name reset");
W.model.actionManager.add(new UpdateObject(item, {name: newName}));
}
newCategories = ["RESIDENCE_HOME"];
newDescripion = null;
if (item.attributes.description !== null && item.attributes.description !== "") { // remove any description
phlogdev("Residential description cleared");
W.model.actionManager.add(new UpdateObject(item, {description: newDescripion}));
}
newPhone = null;
if (item.attributes.phone !== null && item.attributes.phone !== "") { // remove any phone info
phlogdev("Residential Phone cleared");
W.model.actionManager.add(new UpdateObject(item, {phone: newPhone}));
}
newURL = null;
if (item.attributes.url !== null && item.attributes.url !== "") { // remove any url
phlogdev("Residential URL cleared");
W.model.actionManager.add(new UpdateObject(item, {url: newURL}));
}
if (item.attributes.services.length > 0) {
phlogdev("Residential services cleared");
W.model.actionManager.add(new UpdateObject(item, {services: [] }));
}
} else if (item.attributes.name !== "" && item.attributes.name !== " " && item.attributes.name !== null) { // for non-residential places
// Place Harmonization
var PNHMatchData = harmoList(newName,state2L,region,countryCode,newCategories); // check against the PNH list
PNHNameRegMatch = false;
if (PNHMatchData[0] !== "NoMatch" && PNHMatchData[0] !== "ApprovalNeeded" ) { // *** Replace place data with PNH data
PNHNameRegMatch = true;
var PNH_DATA_headers;
if (countryCode === "USA") {
PNH_DATA_headers = USA_PNH_DATA[0].split("|");
} else if (countryCode === "CAN") {
PNH_DATA_headers = CAN_PNH_DATA[0].split("|");
}
var ph_name_ix = PNH_DATA_headers.indexOf("ph_name");
var ph_aliases_ix = PNH_DATA_headers.indexOf("ph_aliases");
var ph_category1_ix = PNH_DATA_headers.indexOf("ph_category1");
var ph_category2_ix = PNH_DATA_headers.indexOf("ph_category2");
var ph_description_ix = PNH_DATA_headers.indexOf("ph_description");
var ph_url_ix = PNH_DATA_headers.indexOf("ph_url");
var ph_order_ix = PNH_DATA_headers.indexOf("ph_order");
// var ph_notes_ix = PNH_DATA_headers.indexOf("ph_notes");
var ph_speccase_ix = PNH_DATA_headers.indexOf("ph_speccase");
var ph_sfurl_ix = PNH_DATA_headers.indexOf("ph_sfurl");
var ph_sfurllocal_ix = PNH_DATA_headers.indexOf("ph_sfurllocal");
// var ph_forcecat_ix = PNH_DATA_headers.indexOf("ph_forcecat");
var ph_displaynote_ix = PNH_DATA_headers.indexOf("ph_displaynote");
// Check special cases
var specCases = PNHMatchData[ph_speccase_ix];
if (specCases !== "0" && specCases !== "") {
specCases = specCases.replace(/,[^A-Za-z0-9}]+/g, ",,"); // tighten up commas if more than one specCase flag.
specCases = specCases.split(",,"); // split by comma
}
var scFlag;
var localURLcheck = '';
for (var scix = 0; scix < specCases.length; scix++) {
// find any button/message flags in the special case (format: butt_xyzXyz)
if ( specCases[scix].match(/^buttOn_/g) !== null ) {
scFlag = specCases[scix].match(/^buttOn_(.+)/i)[1];
bannButt[scFlag].active = true;
} else if ( specCases[scix].match(/^buttOff_/g) !== null ) {
scFlag = specCases[scix].match(/^buttOff_(.+)/i)[1];
bannButt[scFlag].active = false;
} else if ( specCases[scix].match(/^messOn_/g) !== null ) {
scFlag = specCases[scix].match(/^messOn_(.+)/i)[1];
bannMess[scFlag].active = true;
} else if ( specCases[scix].match(/^messOff_/g) !== null ) {
scFlag = specCases[scix].match(/^messOff_(.+)/i)[1];
bannMess[scFlag].active = false;
}
// parseout localURL data if exists
if ( specCases[scix].match(/^localURL_/g) !== null ) {
localURLcheck = specCases[scix].match(/^localURL_(.+)/i)[1];
}
if ( specCases[scix].match(/^optionAltName<>(.+)/g) !== null ) {
optionalAlias = specCases[scix].match(/^optionAltName<>(.+)/i)[1];
if (newAliases.indexOf(optionalAlias) === -1) {
bannButt.addAlias.active = true;
}
}
}
// Display any notes for the specific place
if (PNHMatchData[ph_displaynote_ix] !== '0' && PNHMatchData[ph_displaynote_ix] !== '' ) {
if ( containsAny(specCases,['pharmhours']) ) {
if ( item.attributes.description.toUpperCase().indexOf('PHARMACY') === -1 || item.attributes.description.toUpperCase().indexOf('HOURS') === -1 ) {
sidebarMessage.push(PNHMatchData[ph_displaynote_ix]);
severity = Math.max(severity,1);
}
} else {
sidebarMessage.push(PNHMatchData[ph_displaynote_ix]);
}
}
// populate the variables from PNH data
newName = PNHMatchData[ph_name_ix];
newAliasesTemp = PNHMatchData[ph_aliases_ix].match(/([^\(]*)/i)[0];
newDescripion = PNHMatchData[ph_description_ix];
PNHOrderNum = PNHMatchData[ph_order_ix];
// url parsing
var localURLcheckRE;
if ( localURLcheck !== '') {
if (newURL !== null || newURL !== '') {
localURLcheckRE = new RegExp(localURLcheck, "i");
if ( newURL.match(localURLcheckRE) !== null ) {
newURL = normalizeURL(newURL);
} else {
newURL = PNHMatchData[ph_url_ix];
formBannMess('localURL');
}
} else {
newURL = PNHMatchData[ph_url_ix];
formBannMess('localURL');
}
} else {
newURL = PNHMatchData[ph_url_ix];
}
// Storefinder code:
if (PNHMatchData[ph_sfurllocal_ix] !== "" && PNHMatchData[ph_sfurllocal_ix] !== "0") {
phlogdev('sfurllocal: ' + PNHMatchData[ph_sfurllocal_ix]);
bannButt.PlaceWebsite.value = "Chain Store Finder";
var tempLocalURL = PNHMatchData[ph_sfurllocal_ix].split("<>");
var searchStreet = "", searchCity = "", searchState = "";
if ("string" === typeof addr.street.name) {
//searchCity = addr.city.name + ",%20";
searchStreet = addr.street.name;
}
var searchStreetPlus = searchStreet.replace(/ /g, "+");
searchStreet = searchStreet.replace(/ /g, "%20");
if ("string" === typeof addr.city.name) {
//searchCity = addr.city.name + ",%20";
searchCity = addr.city.name;
}
var searchCityPlus = searchCity.replace(/ /g, "+");
searchCity = searchCity.replace(/ /g, "%20");
if ("string" === typeof addr.state.name) {
//searchState = addr.state.name + ",%20";
searchState = addr.state.name;
}
var searchStatePlus = searchState.replace(/ /g, "+");
searchState = searchState.replace(/ /g, "%20");
for (var tlix = 1; tlix<tempLocalURL.length; tlix++) {
if (tempLocalURL[tlix] === 'ph_streetName') {
customStoreFinderLocalURL = customStoreFinderLocalURL + searchStreet;
} else if (tempLocalURL[tlix] === 'ph_streetNamePlus') {
customStoreFinderLocalURL = customStoreFinderLocalURL + searchStreetPlus;
} else if (tempLocalURL[tlix] === 'ph_cityName') {
customStoreFinderLocalURL = customStoreFinderLocalURL + searchCity;
} else if (tempLocalURL[tlix] === 'ph_cityNamePlus') {
customStoreFinderLocalURL = customStoreFinderLocalURL + searchCityPlus;
} else if (tempLocalURL[tlix] === 'ph_stateName') {
customStoreFinderLocalURL = customStoreFinderLocalURL + searchState;
} else if (tempLocalURL[tlix] === 'ph_stateNamePlus') {
customStoreFinderLocalURL = customStoreFinderLocalURL + searchStatePlus;
} else if (tempLocalURL[tlix] === 'ph_state2L') {
customStoreFinderLocalURL = customStoreFinderLocalURL + state2L;
} else if (tempLocalURL[tlix] === 'ph_latitudeEW') {
//customStoreFinderLocalURL = customStoreFinderLocalURL + itemGPS[0];
} else if (tempLocalURL[tlix] === 'ph_longitudeNS') {
//customStoreFinderLocalURL = customStoreFinderLocalURL + itemGPS[1];
} else if (tempLocalURL[tlix] === 'ph_latitudePM') {
customStoreFinderLocalURL = customStoreFinderLocalURL + itemGPS.lat;
} else if (tempLocalURL[tlix] === 'ph_longitudePM') {
customStoreFinderLocalURL = customStoreFinderLocalURL + itemGPS.lon;
} else {
customStoreFinderLocalURL = customStoreFinderLocalURL + tempLocalURL[tlix];
}
}
customStoreFinderLocal = true;
} else if (PNHMatchData[ph_sfurl_ix] !== "" && PNHMatchData[ph_sfurl_ix] !== "0") {
phlogdev('sfurl: ' + PNHMatchData[ph_sfurl_ix]);
bannButt.PlaceWebsite.value = "Chain Store Finder";
customStoreFinderURL = PNHMatchData[ph_sfurl_ix];
customStoreFinder = true;
}
// Category parsing
var priPlaceCat = catTranslate(PNHMatchData[ph_category1_ix]); // translate primary category to WME code
var altCategories = PNHMatchData[ph_category2_ix];
if (altCategories !== "0" && altCategories !== "") {
altCategories = altCategories.replace(/,[^A-Za-z0-9]*/g, ","); // tighten up commas if more than one secondary category.
altCategories = altCategories.split(","); // split by comma
for (var catix = 0; catix<altCategories.length; catix++) { // translate altCats into WME cat codes
var newAltTemp = catTranslate(altCategories[catix]);
if (newAltTemp === "ERROR") { // if no translation, quit the loop
phlog('Category ' + altCategories[catix] + 'cannot be translated.');
return;
} else {
altCategories[catix] = newAltTemp; // replace with translated element
}
}
}
if ( ["GAS_STATION"].indexOf(priPlaceCat) > -1 ) { // for primary categories in the vector, don't replace existing sub-categories
if ( altCategories !== "0" && altCategories !== "" ) { // if alts exist
insertAtIX(newCategories, altCategories, 1); // then insert the alts into the existing category array
}
} else { // completely replace categories with PNH categories
newCategories = [priPlaceCat];
if (altCategories !== "0" && altCategories !== "") {
newCategories.push.apply(newCategories,altCategories);
}
}
// *** need to add a section above to allow other permissible categories to remain? (optional)
if (newAliasesTemp !== "0" && newAliasesTemp !== "") { // make aliases array
newAliasesTemp = newAliasesTemp.replace(/,[^A-za-z0-9]*/g, ","); // tighten up commas if more than one alias.
newAliasesTemp = newAliasesTemp.split(","); // split by comma
}
if (bannButt.addAlias.active) {
bannButt.addAlias.bannText = "Is there a " + optionalAlias + " at this location?";
bannButt.addAlias.title = 'Add ' + optionalAlias;
}
if (specCases.indexOf('buttOn_addCat2') > -1) {
bannButt.addAlias.bannText = "Is there a " + catTransWaze2Lang[altCategories[0]] + " at this location?";
bannButt.addAlias.title = 'Add ' + catTransWaze2Lang[altCategories[0]];
}
if ( specCases.indexOf('bank') > -1 ) { // PNH banks
// #### Needs work
// Generic Bank treatment
/*
var newNameExt = ' '+newName+' ';
newNameExt = newNameExt.replace(/[^A-Za-z0-9]/g, ' ');
var ixBank = item.attributes.categories.indexOf("BANK_FINANCIAL");
var ixATM = item.attributes.categories.indexOf("ATM");
var ixOffices = item.attributes.categories.indexOf("OFFICES");
// if the name contains ATM in it
if ( newNameExt.toUpperCase().indexOf('ATM ') > -1 ) {
if ( ixOffices === 0 ) {
formBannMess('bankType1');
formBannButt('standaloneATM');
formBannButt('bankBranch');
formBannButt('bankCorporate');
} else if ( ixBank === -1 && ixATM === -1 ) {
formBannButt('standaloneATM');
formBannButt('bankBranch');
} else if ( ixBank === 0 ) {
formBannButt('standaloneATM');
formBannButt('bankBranch');
} else if ( ixATM === 0 && ixBank > 0) {
formBannButt('bankBranch');
}
// Net result: If the place has ATM cat only and ATM in the name, then it will be green
} else { // if no ATM in name:
if ( ixOffices === 0 ) {
formBannButt('bankBranch');
} else if ( ixBank === -1 && ixATM === -1 ) {
formBannButt('standaloneATM');
formBannButt('bankBranch');
} else if ( ixBank > -1 && ixATM === -1 ) {
formBannButt('addATM');
} else if ( ixATM === 0 ) {
formBannButt('standaloneATM');
formBannButt('bankBranch');
} else if ( ixBank > 0 && ixATM > 0 ) {
formBannButt('standaloneATM');
formBannButt('bankBranch');
}
// Net result: If the place has Bank category first, then it will be green
}
*/
} else if ( specCases.indexOf('hotel') > 1 ) { // for certain flags, proceed with update
} else { // for certain flags, proceed with update
if (newName !== item.attributes.name) {
phlogdev("Name updated");
W.model.actionManager.add(new UpdateObject(item, { name: newName }));
}
if (!containsAll(newAliases,newAliasesTemp) && newAliasesTemp !== "0" && newAliasesTemp !== "" && specCases.indexOf('optionName2') === -1 ) {
newAliases = insertAtIX(newAliases,newAliasesTemp,0);
phlogdev("Alt Names updated");
W.model.actionManager.add(new UpdateObject(item, { aliases: newAliases }));
}
if (!matchSets(item.attributes.categories,newCategories) && specCases.indexOf('optionCat2') === -1 ) {
phlogdev("Categories updated" + " with " + newCategories);
W.model.actionManager.add(new UpdateObject(item, { categories: newCategories }));
}
if (newDescripion !== null && newDescripion !== "0") {
if ( item.attributes.description.toUpperCase().indexOf(newDescripion.toUpperCase()) === -1 ) {
if ( item.attributes.description !== "" || item.attributes.description !== null ) {
formBannMess('checkDescription');
}
phlogdev("Description updated");
newDescripion = newDescripion + '\n' + item.attributes.description;
W.model.actionManager.add(new UpdateObject(item, { description: newDescripion }));
}
}
}
if ( PNHMatchData[ph_speccase_ix] === 'subFuel' ) {
formBannMess('subFuel');
}
// *** Add storefinder URL codes
} else { // if no match found
if (PNHMatchData[0] === "ApprovalNeeded") {
PNHNameTemp = PNHMatchData[1];
PNHNameTempWeb = PNHNameTemp.replace(/&/g, "%26");
PNHNameTempWeb = PNHNameTempWeb.replace(/\//g, "%2F");
PNHOrderNum = PNHMatchData[2];
}
if (newName !== item.attributes.name) {
phlogdev("Name updated");
W.model.actionManager.add(new UpdateObject(item, { name: newName }));
}
if (newName !== toTitleCaseStrong(newName)) {
formBannButt('STC');
}
// #### Needs work
// Generic Bank treatment
var ixBank = item.attributes.categories.indexOf("BANK_FINANCIAL");
var ixATM = item.attributes.categories.indexOf("ATM");
var ixOffices = item.attributes.categories.indexOf("OFFICES");
var newNameExt = ' '+newName+' ';
newNameExt = newNameExt.replace(/[^A-Za-z0-9]/g, ' ');
// if the name contains ATM in it
if ( newNameExt.toUpperCase().indexOf('ATM ') > -1 ) {
if ( ixOffices === 0 ) {
formBannMess('bankType1');
formBannButt('standaloneATM');
formBannButt('bankBranch');
formBannButt('bankCorporate');
} else if ( ixBank === -1 && ixATM === -1 ) {
formBannButt('standaloneATM');
formBannButt('bankBranch');
} else if ( ixBank === 0 ) {
formBannButt('standaloneATM');
formBannButt('bankBranch');
} else if ( ixATM === 0 && ixBank > 0) {
formBannButt('bankBranch');
}
// Net result: If the place has ATM cat only and ATM in the name, then it will be green
} else if (ixBank > -1 || ixATM > -1) { // if no ATM in name:
if ( ixOffices === 0 ) {
formBannButt('bankBranch');
} else if ( ixBank > -1 && ixATM === -1 ) {
formBannButt('addATM');
} else if ( ixATM === 0 ) {
formBannButt('standaloneATM');
formBannButt('bankBranch');
} else if ( ixBank > 0 && ixATM > 0 ) {
formBannButt('standaloneATM');
formBannButt('bankBranch');
}
// Net result: If the place has Bank category first, then it will be green
}
} // END match/no-match updates
// Gas station treatment applies to all
if (newCategories[0] === 'GAS_STATION') {
// Brand checking
if ( !item.attributes.brand || item.attributes.brand === null || item.attributes.brand === "" ) {
formBannMess('gasNoBrand');
} else if (item.attributes.brand === 'Unbranded' ) {
formBannMess('gasUnbranded');
lockOK = false;
} else {
var brandNameRegEx = new RegExp('\\b'+item.attributes.brand.toUpperCase()+'\\b', "i");
if ( newName.match(brandNameRegEx) === null ) {
formBannButt('gasMismatch');
lockOK = false;
}
}
// Add convenience store category to station
if (newCategories.indexOf("CONVENIENCE_STORE") === -1 && !bannMess.subFuel.active) {
if ( $("#WMEPH-ConvenienceStoreToGasStations" + devVersStr).prop('checked') ) { // Automatic if user has the setting checked
newCategories = insertAtIX(newCategories, "CONVENIENCE_STORE", 1); // insert the C.S. category
W.model.actionManager.add(new UpdateObject(item, { // update
categories: newCategories
}));
} else { // If not checked, then it will be a banner button
formBannButt('addConvStore');
}
}
}
// Make submission links
var regionFormURL = '';
var newPlaceAddon = '';
var approvalAddon = '';
var approvalMessage = 'Submitted via WMEPH. PNH order number ' + PNHOrderNum;
switch (region) {
case "NWR": regionFormURL = 'https://docs.google.com/forms/d/1hv5hXBlGr1pTMmo4n3frUx1DovUODbZodfDBwwTc7HE/viewform';
newPlaceAddon = '?entry.925969794='+newName+'&entry.1970139752='+newURLSubmit+'&entry.1749047694='+thisUser.userName+gFormState;
approvalAddon = '?entry.925969794='+PNHNameTempWeb+'&entry.50214576='+approvalMessage+'&entry.1749047694='+thisUser.userName+gFormState;
break;
case "SWR": regionFormURL = 'https://docs.google.com/forms/d/1Qf2N4fSkNzhVuXJwPBJMQBmW0suNuy8W9itCo1qgJL4/viewform';
newPlaceAddon = '?entry.1497446659='+newName+'&entry.1970139752='+newURLSubmit+'&entry.1749047694='+thisUser.userName+gFormState;
approvalAddon = '?entry.1497446659='+PNHNameTempWeb+'&entry.50214576='+approvalMessage+'&entry.1749047694='+thisUser.userName+gFormState;
break;
case "HI": regionFormURL = 'https://docs.google.com/forms/d/1Qf2N4fSkNzhVuXJwPBJMQBmW0suNuy8W9itCo1qgJL4/viewform';
newPlaceAddon = '?entry.925969794='+newName+'&entry.1970139752='+newURLSubmit+'&entry.1749047694='+thisUser.userName+gFormState;
approvalAddon = '?entry.925969794='+PNHNameTempWeb+'&entry.50214576='+approvalMessage+'&entry.1749047694='+thisUser.userName+gFormState;
break;
case "PLN": regionFormURL = 'https://docs.google.com/forms/d/1ycXtAppoR5eEydFBwnghhu1hkHq26uabjUu8yAlIQuI/viewform';
newPlaceAddon = '?entry.925969794='+newName+'&entry.1970139752='+newURLSubmit+'&entry.1749047694='+thisUser.userName+gFormState;
approvalAddon = '?entry.925969794='+PNHNameTempWeb+'&entry.50214576='+approvalMessage+'&entry.1749047694='+thisUser.userName+gFormState;
break;
case "SCR": regionFormURL = 'https://docs.google.com/forms/d/1KZzLdlX0HLxED5Bv0wFB-rWccxUp2Mclih5QJIQFKSQ/viewform';
newPlaceAddon = '?entry.925969794='+newName+'&entry.1970139752='+newURLSubmit+'&entry.1749047694='+thisUser.userName+gFormState;
approvalAddon = '?entry.925969794='+PNHNameTempWeb+'&entry.50214576='+approvalMessage+'&entry.1749047694='+thisUser.userName+gFormState;
break;
case "TX": regionFormURL = 'https://docs.google.com/forms/d/1x7VM7ofPOKVnWOaX7d70OWXpnVKf6Mkadn4dgYxx4ic/viewform';
newPlaceAddon = '?entry.925969794='+newName+'&entry.1970139752='+newURLSubmit+'&entry.1749047694='+thisUser.userName+gFormState;
approvalAddon = '?entry.925969794='+PNHNameTempWeb+'&entry.50214576='+approvalMessage+'&entry.1749047694='+thisUser.userName+gFormState;
break;
case "GLR": regionFormURL = 'https://docs.google.com/forms/d/19btj-Qt2-_TCRlcS49fl6AeUT95Wnmu7Um53qzjj9BA/viewform';
newPlaceAddon = '?entry.925969794='+newName+'&entry.1970139752='+newURLSubmit+'&entry.1749047694='+thisUser.userName+gFormState;
approvalAddon = '?entry.925969794='+PNHNameTempWeb+'&entry.50214576='+approvalMessage+'&entry.1749047694='+thisUser.userName+gFormState;
break;
case "SAT": regionFormURL = 'https://docs.google.com/forms/d/1bxgK_20Jix2ahbmUvY1qcY0-RmzUBT6KbE5kjDEObF8/viewform';
newPlaceAddon = '?entry.2063110249='+newName+'&entry.2018912633='+newURLSubmit+'&entry.1924826395='+thisUser.userName+gFormState;
approvalAddon = '?entry.2063110249='+PNHNameTempWeb+'&entry.123778794='+approvalMessage+'&entry.1924826395='+thisUser.userName+gFormState;
break;
case "SER": regionFormURL = 'https://docs.google.com/forms/d/1jYBcxT3jycrkttK5BxhvPXR240KUHnoFMtkZAXzPg34/viewform';
newPlaceAddon = '?entry.822075961='+newName+'&entry.1422079728='+newURLSubmit+'&entry.1891389966='+thisUser.userName+gFormState;
approvalAddon = '?entry.822075961='+PNHNameTempWeb+'&entry.607048307='+approvalMessage+'&entry.1891389966='+thisUser.userName+gFormState;
break;
case "TER": regionFormURL = 'https://docs.google.com/forms/d/1v7JhffTfr62aPSOp8qZHA_5ARkBPldWWJwDeDzEioR0/viewform';
newPlaceAddon = '?entry.925969794='+newName+'&entry.1970139752='+newURLSubmit+'&entry.1749047694='+thisUser.userName+gFormState;
approvalAddon = '?entry.925969794='+PNHNameTempWeb+'&entry.50214576='+approvalMessage+'&entry.1749047694='+thisUser.userName+gFormState;
break;
case "NEW": regionFormURL = 'https://docs.google.com/forms/d/1UgFAMdSQuJAySHR0D86frvphp81l7qhEdJXZpyBZU6c/viewform';
newPlaceAddon = '?entry.925969794='+newName+'&entry.1970139752='+newURLSubmit+'&entry.1749047694='+thisUser.userName+gFormState;
approvalAddon = '?entry.925969794='+PNHNameTempWeb+'&entry.50214576='+approvalMessage+'&entry.1749047694='+thisUser.userName+gFormState;
break;
case "NOR": regionFormURL = 'https://docs.google.com/forms/d/1iYq2rd9HRd-RBsKqmbHDIEBGuyWBSyrIHC6QLESfm4c/viewform';
newPlaceAddon = '?entry.925969794='+newName+'&entry.1970139752='+newURLSubmit+'&entry.1749047694='+thisUser.userName+gFormState;
approvalAddon = '?entry.925969794='+PNHNameTempWeb+'&entry.50214576='+approvalMessage+'&entry.1749047694='+thisUser.userName+gFormState;
break;
case "MAR": regionFormURL = 'https://docs.google.com/forms/d/1PhL1iaugbRMc3W-yGdqESoooeOz-TJIbjdLBRScJYOk/viewform';
newPlaceAddon = '?entry.925969794='+newName+'&entry.1970139752='+newURLSubmit+'&entry.1749047694='+thisUser.userName+gFormState;
approvalAddon = '?entry.925969794='+PNHNameTempWeb+'&entry.50214576='+approvalMessage+'&entry.1749047694='+thisUser.userName+gFormState;
break;
case "CAN": regionFormURL = 'https://docs.google.com/forms/d/13JwXsrWPNmCdfGR5OVr5jnGZw-uNGohwgjim-JYbSws/viewform';
newPlaceAddon = '?entry_839085807='+newName+'&entry_1067461077='+newURLSubmit;
approvalAddon = '?entry_839085807='+PNHNameTempWeb+'&entry_1125435193='+approvalMessage;
break;
default: regionFormURL = "";
}
newPlaceURL = regionFormURL + newPlaceAddon;
approveRegionURL = regionFormURL + approvalAddon;
// *** filter weak/parent categories from stronger categories (remove food and drink if restaurant, etc.)
// Category/Name-based Services, added to any existing services:
var CH_DATA, CH_NAMES;
if (countryCode === "USA") {
CH_DATA = USA_CH_DATA;
CH_NAMES = USA_CH_NAMES;
} else if (countryCode === "CAN") {
CH_DATA = USA_CH_DATA; // #### Eventually can be split to new sheet if needed
CH_NAMES = USA_CH_NAMES;
}
var CH_DATA_headers = CH_DATA[0].split("|");
var CH_DATA_keys = CH_DATA[1].split("|");
var CH_DATA_list = CH_DATA[2].split("|");
var servHeaders = [], servKeys = [], servList = [], servHeaderCheck;
for (var jjj=0; jjj<CH_DATA_headers.length; jjj++) {
servHeaderCheck = CH_DATA_headers[jjj].match(/^ps/i); // if it's a service header
if (servHeaderCheck) {
servHeaders.push(jjj);
servKeys.push(CH_DATA_keys[jjj]);
servList.push(CH_DATA_list[jjj]);
}
}
var CH_DATA_Temp;
for (var iii=0; iii<CH_NAMES.length; iii++) {
if (newCategories.indexOf(CH_NAMES[iii]) > -1 ) {
CH_DATA_Temp = CH_DATA[iii].split("|");
for (var psix=0; psix<servHeaders.length; psix++) {
if (CH_DATA_Temp[servHeaders[psix]] === '1') {
bannServ[servKeys[psix]].active = true;
if ($("#WMEPH-EnableServices" + devVersStr).prop('checked')) {
// Automatically enable new services
newServices = insertAtIX(newServices,servList[psix],12);
}
} else if (CH_DATA_Temp[servHeaders[psix]] === '2') {
bannServ[servKeys[psix]].active = true;
}
}
}
}
for (var slix=0; slix<servList.length; slix++) {
if (newServices.indexOf(servList[slix]) > -1) {
bannServ[servKeys[slix]].active = true;
bannServ[servKeys[slix]].checked = true;
}
}
// Place Area check
if (item.isPoint() && containsAny(newCategories,["GAS_STATION","PARKING_LOT","AIRPORT","BRIDGE","CEMETERY","EMBASSY_CONSULATE","FIRE_DEPARTMENT",
"POLICE_STATION","PRISON_CORRECTIONAL_FACILITY","SCHOOL","SHOPPING_CENTER","RACING_TRACK","THEME_PARK","GOLF_COURSE","PARK"]) ) {
formBannMess('areaNotPoint');
lockOK = false;
}
if (item.isPoint() && newCategories.indexOf("STADIUM_ARENA") > -1) {
formBannMess('areaStadium');
lockOK = false;
}
if (region === "SER" && item.isPoint() && newCategories.indexOf("POST_OFFICE") > -1) {
formBannMess('areaPostOfficeSER');
lockOK = false;
}
if (item.isPoint() && newCategories.indexOf("HOSPITAL_MEDICAL_CARE") > -1) {
formBannMess('areaHospital');
lockOK = false;
}
if (region === "SER" && containsAny(newCategories,["JUNCTION_INTERCHANGE","SEA_LAKE_POOL","RIVER_STREAM","FOREST_GROVE","CANAL","SWAMP_MARSH","ISLAND","BEACH","TRANSPORTATION"]) ) {
formBannMess('unmappedSER');
lockOK = false;
}
if (region === "SER" && item.is2D() && (newCategories.indexOf("CAR_DEALERSHIP") > -1)) {
formBannMess('pointCarDealerSER');
lockOK = false;
}
// Address check
if (!item.attributes.name && !item.attributes.residential) {
formBannMess('nameMissing');
lockOK = false;
}
} // END if (not residential)
// House number check
if (!item.attributes.houseNumber) {
formBannMess('hnMissing');
lockOK = false;
} else {
var hnOK = false;
var hnTemp = item.attributes.houseNumber.replace(/[^\d]/g, ''); // Digits only
var hnTempDash = item.attributes.houseNumber.replace(/[^\d-]/g, ''); // Digits and dashes only
if (hnTemp === item.attributes.houseNumber && hnTemp < 1000000) { // general check that HN is 6 digits or less, & that it is only [0-9]
hnOK = true;
}
if (state2L === "HI") { // Allowance for XX-XXXX HN format for Hawaii
if (hnTempDash.match(/^\d{1,2}-\d{1,4}$/g) !== null) {
if (hnTempDash === hnTempDash.match(/^\d{1,2}-\d{1,4}$/g)[0]) {
hnOK = true;
}
}
}
if (!hnOK) {
formBannMess('hnNonStandard');
lockOK = false;
}
}
if (!addr.street || addr.street.isEmpty) {
formBannMess('streetMissing');
lockOK = false;
}
if (!addr.city || addr.city.isEmpty) {
formBannMess('cityMissing');
lockOK = false;
}
if (!item.attributes.residential) {
// Check for missing hours field
if ( $("#WMEPH-AlertNoHours" + devVersStr).prop('checked') ) {
// ### Needs correct hours field check below
if (item.attributes.openingHours.length === 0) { // if no hours...
if (!containsAny(newCategories,["PARKING_LOT","STADIUM_ARENA","CONVENTIONS_EVENT_CENTER","CEMETERY","FIRE_DEPARTMENT",
"POLICE_STATION","MILITARY","FACTORY_INDUSTRIAL","ATM","TRANSPORTATION","AIRPORT","FERRY_PIER","SEAPORT_MARINA_HARBOR","SUBWAY_STATION","TRAIN_STATION",
"BRIDGE","TUNNEL","TAXI_STATION","JUNCTION_INTERCHANGE","ISLAND","SEA_LAKE_POOL","RIVER_STREAM","FOREST_GROVE","FARM","CANAL","SWAMP_MARSH","DAM"]) ) {
formBannMess('noHours');
}
} else if (item.attributes.openingHours.length === 1) { // if one set of hours exist...
if (item.attributes.openingHours[0].days.length < 7 && item.attributes.openingHours[0].fromHour==='00:00' &&
(item.attributes.openingHours[0].toHour==='00:00' || item.attributes.openingHours[0].toHour==='23:59' ) ) {
formBannMess('mismatch247');
}
}
}
// URL formatting
newURL = normalizeURL(newURL);
if (newURL !== item.attributes.url && newURL !== "" && newURL !== "0") {
// if option is checked and place was harmonized, keep long URL for Harmonized place if domains match4444444
if ($("#WMEPH-PreserveLongURLs" + devVersStr).prop('checked') && PNHNameRegMatch && item.attributes.url !== null) {
var tempNormURL = normalizeURL(item.attributes.url); // Normalize existing url
tempNormURL = tempNormURL.replace(/\/.*/g, ''); // strip everything after the domain
var mTemp = tempNormURL.match(/^www\.(.*)$/i); // strip www. if there (this is just for checking, doesn't strip www from the WME field)
if (mTemp) { tempNormURL = mTemp[1]; }
var tempNewURL = newURL.replace(/\/.*/g, ''); // strip newURL down to domain
mTemp = tempNewURL.match(/^www\.(.*)$/i); // strip www. if there (this is just for checking, doesn't strip www from the WME field)
if (mTemp) { tempNewURL = mTemp[1]; }
if ( tempNormURL.indexOf(tempNewURL) > -1 ) { // domain match check
newURL = normalizeURL(item.attributes.url); // Keep existing, normalized URL
formBannMess('longURL');
}
}
phlogdev("URL updated");
W.model.actionManager.add(new UpdateObject(item, { url: newURL }));
}
// Phone formatting
var outputFormat = "({0}) {1}-{2}";
if ( containsAny(["SAT","CA","CO"],[region,state2L]) && (/^\d{3}-\d{3}-\d{4}$/.test(item.attributes.phone))) {
outputFormat = "{0}-{1}-{2}";
} else if (region === "SER" && !(/^\(\d{3}\) \d{3}-\d{4}$/.test(item.attributes.phone))) {
outputFormat = "{0}-{1}-{2}";
} else if (region === "GLR") {
outputFormat = "{0}-{1}-{2}";
} else if (countryCode === "CAN") {
outputFormat = "+1-{0}-{1}-{2}";
}
newPhone = normalizePhone(item.attributes.phone, outputFormat);
if (newPhone !== item.attributes.phone) {
phlogdev("Phone updated");
W.model.actionManager.add(new UpdateObject(item, {phone: newPhone}));
}
} // END if (not residential)
// Post Office cat check
if (newCategories.indexOf("POST_OFFICE") > -1) {
formBannButt('isitUSPS');
}
// Add services to existing, only if they are different than what's there
if (!item.attributes.residential && !matchSets(item.attributes.services,newServices) && $("#WMEPH-EnableServices" + devVersStr).prop('checked')) {
phlogdev("Services updated");
W.model.actionManager.add(new UpdateObject(item, { services: newServices }));
}
// Place locking
if (lockOK) {
var levelToLock = lockLevel3;
if (region === "SER") {
if (newCategories.indexOf("COLLEGE_UNIVERSITY") > -1 && newCategories.indexOf("PARKING_LOT") > -1) {
levelToLock = lockLevel4;
} else if ( item.isPoint() && newCategories.indexOf("COLLEGE_UNIVERSITY") > -1 && newCategories.indexOf("HOSPITAL_MEDICAL_CARE") === -1 ) {
levelToLock = lockLevel4;
} else if ( containsAny(newCategories,["HOSPITAL_MEDICAL_CARE","COLLEGE_UNIVERSITY","STADIUM_ARENA","SCHOOL","AIRPORT"]) ) {
levelToLock = lockLevel5;
}
}
if (region === "SAT") {
var SATlevel5Categories = ["HOSPITAL_MEDICAL_CARE", "AIRPORT"];
if ( containsAny(newCategories,SATlevel5Categories) ) {
levelToLock = lockLevel5;
}
}
if (region === "MAR") {
var MARlevel4Categories = [ "HOSPITAL_MEDICAL_CARE", "AIRPORT", "FIRE_DEPARTMENT", "POLICE_STATION" ];
if ( containsAny(newCategories,MARlevel4Categories) ) {
levelToLock = lockLevel4;
}
}
if (item.attributes.lockRank < levelToLock) {
phlogdev("Venue locked!");
W.model.actionManager.add(new UpdateObject(item, {
lockRank: levelToLock
}));
}
bannMess.placeLocked.active = true;
}
// User alerts for potentially confusing places
var hotelCat = 0;
var walmartFlag = 0;
if (Math.max(severity, severityButt) < 3) {
var nameShortSpace = newName.replace(/[^A-Za-z ]/g, '');
if ( ["HOME","MY HOME","HOUSE","MY HOUSE","CASA","MI CASA"].indexOf( nameShortSpace.toUpperCase() ) > -1 ) {
formBannMess('resiTypeName');
}
if (newName === "UPS") {
sidebarMessageOld.push("If this is a 'UPS Store' location, please change the name to The UPS Store and run the script again.");
severity = Math.max(1, severity);
}
if (newName === "FedEx") {
sidebarMessageOld.push("If this is a FedEx Office location, please change the name to FedEx Office and run the script again.");
severity = Math.max(1, severity);
}
if (newName === "IBM Southeast EFCU") {
sidebarMessageOld.push("Please add the suffix ' - LOCATION' to the primary name as found on IBMSEFCU's website");
severity = Math.max(2, severity);
}
if (walmartFlag === 1) {
sidebarMessageOld.push("If this Walmart sells groceries, please add the Supermarket category to the place.");
severity = Math.max(1, severity);
}
if (newCategories.indexOf("POST_OFFICE") > -1) {
customStoreFinderURL = "https://tools.usps.com/go/POLocatorAction.action";
customStoreFinder = true;
formBannMess('catPostOffice');
}
if (item.is2D() && newCategories.indexOf("STADIUM_ARENA") > -1) {
formBannMess('generalStadium');
}
if (hotelCat === 1 || newCategories.indexOf("HOTEL") > -1) {
formBannMess('catHotel');
}
}
// #### Needs work
if (newURL !== null && newURL !== "") {
bannButt.PlaceWebsite.active = true;
}
// push together messages from active bannMess objects
for (bannKey in bannMess) {
if (bannMess[bannKey].active) {
sidebarMessage.push(bannMess[bannKey].message);
}
}
// Make Messaging banners
assembleBanner(item);
} // (End Place 'loop')
} // END harmonizePlaceGo function
// Set up banner messages
function assembleBanner(item) {
var sidebarMessageEXT = sidebarMessage.slice(0); // pull out message array to add on to if necessary
var tempKey, strButt1, NHix;
severityButt = 0;
for (NHix = 0; NHix < Object.keys(bannButt).length; NHix++ ) {
tempKey = Object.keys(bannButt)[NHix];
var strButt2 = '';
if (bannButt[tempKey].active) {
strButt1 = bannButt[tempKey].bannText + '<input class="PHbutton" id="' + bannButt[tempKey].id + '" title="' + bannButt[tempKey].title + '" type="button" value="' + bannButt[tempKey].value + '">';
sidebarMessageEXT.push(strButt1 + strButt2);
severityButt = Math.max(bannButt[tempKey].severity, severityButt);
}
}
if (!$("#WMEPH-HideServices" + devVersStr).prop('checked')) {
// setup Add Service Buttons for suggested services
var sidebarServButts = '';
var servButtHeight = '28';
for ( NHix = 0; NHix < Object.keys(bannServ).length; NHix++ ) {
tempKey = Object.keys(bannServ)[NHix];
if (bannServ[tempKey].active) {
if (bannServ[tempKey].checked) {
strButt1 = ' <input class="PHbutton" id="' + bannServ[tempKey].id + '" title="' + bannServ[tempKey].title + '" type="image" style="height:' + servButtHeight +
'px;background:none;border-color: none;border-style: none;" src="https://openmerchantaccount.com/img2/' + bannServ[tempKey].icon + '.png">';
} else {
strButt1 = ' <input class="PHbutton" id="' + bannServ[tempKey].id + '" title="' + bannServ[tempKey].title + '" type="image" style="height:' + servButtHeight +
'px;background:none;border-color: none;border-style: none;" src="https://openmerchantaccount.com/img2/' + bannServ[tempKey].icon + '-grey.png">';
}
sidebarServButts = sidebarServButts + strButt1;
}
}
if (sidebarServButts.length>0) {
//sidebarMessageEXT.push('Add services:<br>' + sidebarServButts + '<br><hr align="center" width="90%">');
sidebarMessageEXT.push('Add services:<br>' + sidebarServButts);
}
}
for (NHix = 0; NHix < Object.keys(bannButt2).length; NHix++ ) {
tempKey = Object.keys(bannButt2)[NHix];
if (bannButt2[tempKey].active) {
strButt1 = bannButt2[tempKey].bannText + '<input class="PHbutton" id="' + bannButt2[tempKey].id + '" title="' + bannButt2[tempKey].title + '" type="button" value="' + bannButt2[tempKey].value + '">';
sidebarMessageEXT.push(strButt1);
severityButt = Math.max(bannButt2[tempKey].severity, severityButt);
}
}
// Add banner indicating that it's the beta version
if (isDevVersion) {
sidebarMessageEXT.push('WMEPH Beta');
}
displayBanners(sidebarMessageEXT.join("<li>"), Math.max(severity, severityButt) );
setupButtons(item);
if (!$("#WMEPH-HideServices" + devVersStr).prop('checked')) {
setupServiceButtons(item);
}
setupButtons2(item);
} // END assemble Banner function
// Button event handlers
function setupButtons(item) {
var ixButt = 0;
var btn = [];
for (var NHix = 0; NHix < Object.keys(bannButt).length; NHix++ ) {
var tempKey = Object.keys(bannButt)[NHix];
if (bannButt[tempKey].active) {
btn[ixButt] = document.getElementById(bannButt[tempKey].id);
btn[ixButt].onclick = (function(buttonId, item){
return function() {
//bannButt[buttonId].action(item);
bannButt[buttonId].action();
assembleBanner(item);
};
})(tempKey, item)
ixButt++;
}
}
} // END setupButtons function
function setupServiceButtons(item) {
var ixButt = 0;
var btn = [];
for (var NHix = 0; NHix < Object.keys(bannServ).length; NHix++ ) {
var tempKey = Object.keys(bannServ)[NHix];
if (bannServ[tempKey].active) {
btn[ixButt] = document.getElementById(bannServ[tempKey].id);
btn[ixButt].onclick = (function(buttonId, item){
return function() {
bannServ[buttonId].action();
assembleBanner(item);
};
})(tempKey, item)
ixButt++;
}
}
} // END setupServiceButtons function
function setupButtons2(item) {
var ixButt = 0;
var btn = [];
for (var NHix = 0; NHix < Object.keys(bannButt2).length; NHix++ ) {
var tempKey = Object.keys(bannButt2)[NHix];
if (bannButt2[tempKey].active) {
btn[ixButt] = document.getElementById(bannButt2[tempKey].id);
btn[ixButt].onclick = (function(buttonId, item){
return function() {
//bannButt[buttonId].action(item);
bannButt2[buttonId].action();
assembleBanner(item);
};
})(tempKey, item)
ixButt++;
}
}
} // END setupButtons function
// Display banners with <LI> string and severity
function displayBanners(sbm,sev) {
$('#WMEPH_logger_warn').empty();
if (sev === 0) {
$('<div id="WMEPH_logger_warn">').css("width", "290").css("background-color", "rgb(36, 172, 36)").css("color", "white").css("font-size", "15px").css("font-weight", "bold").css("margin-left", "auto").css("margin-right", "auto").prependTo(".contents");
}
if (sev === 1) {
$('<div id="WMEPH_logger_warn">').css("width", "290").css("background-color", "rgb(40, 40, 230)").css("color", "white").css("font-size", "15px").css("font-weight", "bold").css("margin-left", "auto").css("margin-right", "auto").prependTo(".contents");
}
if (sev === 2) {
$('<div id="WMEPH_logger_warn">').css("width", "290").css("background-color", "rgb(217, 173, 42)").css("color", "white").css("font-size", "15px").css("font-weight", "bold").css("margin-left", "auto").css("margin-right", "auto").prependTo(".contents");
}
if (sev === 3) {
$('<div id="WMEPH_logger_warn">').css("width", "290").css("background-color", "rgb(211, 48, 48)").css("color", "white").css("font-size", "15px").css("font-weight", "bold").css("margin-left", "auto").css("margin-right", "auto").prependTo(".contents");
}
WMEPH_DispWarn(sbm);
} // END displayBanners funtion
// Build a Google search url based on place name and address
function buildGLink(searchName,addr,HN) {
var searchHN = "", searchStreet = "", searchCity = "";
searchName = searchName.replace(/&/g, "%26");
searchName = searchName.replace(/[ \/]/g, "%20");
if ("string" === typeof HN) {
searchHN = HN + "%20";
}
if ("string" === typeof addr.street.name) {
searchStreet = addr.street.name + ",%20";
}
searchStreet = searchStreet.replace(/ /g, "%20");
if ("string" === typeof addr.city.name) {
searchCity = addr.city.name + ",%20";
}
searchCity = searchCity.replace(/ /g, "%20");
return "http://www.google.com/search?q=" + searchName + ",%20" + searchHN + searchStreet + searchCity + addr.state.name;
} // END buildGLink function
// WME Category translation from Natural language to object language
function catTranslate(natCategories) {
if (natCategories.toUpperCase().replace(/ AND /g, "").replace(/[^A-Z]/g, "").indexOf('PETSTORE') > -1) {
return "PET_STORE_VETERINARIAN_SERVICES";
}
for(var keyCat in catTransWaze2Lang){
if ( natCategories.toUpperCase().replace(/ AND /g, "").replace(/[^A-Z]/g, "") === catTransWaze2Lang[keyCat].toUpperCase().replace(/ AND /g, "").replace(/[^A-Z]/g, "")) {
return keyCat;
}
}
if (confirm('WMEPH: Category Error!\nClick OK to report this error') ) { // if the category doesn't translate, then pop an alert that will make a forum post to the thread
var forumMsgInputs = {
subject: 'Re: WMEPH Bug report',
message: 'Error report: category "' + natCategories + '" is not translatable.',
addbbcode20: '100', preview: 'Preview', attach_sig: 'on', notify: 'on'
};
WMEPH_openPostDataInNewTab(WMEPHurl + '#preview', forumMsgInputs);
}
return "ERROR";
} // END catTranslate function
// compares two arrays to see if equal, regardless of order
function matchSets(array1, array2) {
if (array1.length !== array2.length) {return false;} // compare lengths
for (var i = 0; i < array1.length; i++) {
if (array2.indexOf(array1[i]) === -1) {
return false;
}
}
return true;
}
// function that checks if all elements of target are in array:source
function containsAll(source,target) {
if (typeof(target) === "string") { target = [target]; } // if a single string, convert to an array
for (var ixx = 0; ixx < target.length; ixx++) {
if ( source.indexOf(target[ixx]) === -1 ) {
return false;
}
}
return true;
}
// function that checks if any element of target are in source
function containsAny(source,target) {
if (typeof(source) === "string") { source = [source]; } // if a single string, convert to an array
if (typeof(target) === "string") { target = [target]; } // if a single string, convert to an array
var result = source.filter(function(tt){ return target.indexOf(tt) > -1; });
return (result.length > 0);
}
// Function that inserts a string or a string array into another string array at index ix and removes any duplicates
function insertAtIX(array1, array2, ix) { // array1 is original string, array2 is the inserted string, at index ix
var arrayNew = array1.slice(0); // slice the input array so it doesn't change
if (typeof(array2) === "string") { array2 = [array2]; } // if a single string, convert to an array
if (typeof(array2) === "object") { // only apply to inserted arrays
var arrayTemp = arrayNew.splice(ix); // split and hold the first part
arrayNew.push.apply(arrayNew, array2); // add the insert
arrayNew.push.apply(arrayNew, arrayTemp); // add the tail end of original
}
return uniq(arrayNew); // remove any duplicates (so the function can be used to move the position of a string)
}
// settings tab
function add_PlaceHarmonizationSettingsTab() {
//Create Settings Tab
var phTabHtml = '<li><a href="#sidepanel-ph' + devVersStr + '" data-toggle="tab" id="PlaceHarmonization' + devVersStr + '">WMEPH' + devVersStrSpace + '</a></li>';
$("#user-tabs ul.nav-tabs:first").append(phTabHtml);
//Create Settings Tab Content
var phContentHtml = '<div class="tab-pane" id="sidepanel-ph' + devVersStr + '"><div id="PlaceHarmonizer' + devVersStr + '"><p>WMEPH' + devVersStrSpace + ' v. ' + WMEPHversion + '</p><hr align="center" width="90%"><p>Settings:</p></div></div>';
$("#user-info div.tab-content:first").append(phContentHtml);
//Create Settings Checkboxes and Load Data
//example condition: if ( $("#WMEPH-PreserveLongURLs" + devVersStr).prop('checked') ) { }
createSettingsCheckbox("WMEPH-HidePlacesWiki" + devVersStr,"Hide 'Places Wiki' button in results banner");
createSettingsCheckbox("WMEPH-AlertNoHours" + devVersStr,"Alert for missing or unlikely hours of operation");
if (devUser || betaUser || usrRank > 2) {
createSettingsCheckbox("WMEPH-ConvenienceStoreToGasStations" + devVersStr,'Automatically add "Convenience Store" category to gas stations');
}
if (devUser) {
// Old option for removing www. Keep in case it is needed.
// createSettingsCheckbox("WMEPH-StripWWW" + devVersStr,"Strip 'www.' from all URLs");
}
if (devUser || betaUser || usrRank > 2) {
createSettingsCheckbox("WMEPH-PreserveLongURLs" + devVersStr,"Preserve existing long URLs for harmonized places");
}
if (devUser || betaUser || usrRank > 1) {
createSettingsCheckbox("WMEPH-HideServices" + devVersStr,"Hide Add Services banner buttons");
}
if (devUser || betaUser || usrRank > 3) {
createSettingsCheckbox("WMEPH-EnableServices" + devVersStr,"Enable automatic addition of common services");
}
if (devUser || betaUser || usrRank > 3) {
createSettingsCheckbox("WMEPH-AddAddresses" + devVersStr,"Add detected address fields to places with no address");
}
if (devUser) { // Override script regionality (devs only)
var phDevContentHtml = '<hr align="center" width="90%"><p>Dev Only Settings:</p></div></div>';
$("#PlaceHarmonizer" + devVersStr).append(phDevContentHtml);
createSettingsCheckbox("WMEPH-RegionOverride" + devVersStr,"Disable Region Specificity");
}
var feedbackString = 'Submit script feedback & suggestions';
var placesWikiStr = 'Open the WME Places Wiki page';
var phContentHtml2 = '<div class="tab-pane" id="sidepanel-ph' + devVersStr + '"><div id="PlaceHarmonizer' + devVersStr + '"><hr align="center" width="95%"><p><a href="' +
placesWikiURL + '" target="_blank" title="'+placesWikiStr+'">'+placesWikiStr+'</a><p><a href="' +
WMEPHurl + '" target="_blank" title="'+feedbackString+'">'+feedbackString+'</a></p><hr align="center" width="95%">Major features for v. '+WMEPHversionMeta+':<ul><li>'+WMEPHWhatsNewMetaHList+'</ul>Recent updates:<ul><li>'+WMEPHWhatsNewHList+'</ul></div></div>';
$("#PlaceHarmonizer" + devVersStr).append(phContentHtml2);
// $("#user-info div.tab-content:first").append(phContentHtml2);
phlog('Ready...!');
} // END Settings Tab
// This routine will create a checkbox in the #PlaceHarmonizer tab and will load the setting
// settingID: The #id of the checkbox being created.
// textDescription: The description of the checkbox that will be use
function createSettingsCheckbox(settingID, textDescription) {
//Create settings checkbox and append HTML to settings tab
var phTempHTML = '<input type="checkbox" id="' + settingID + '">'+ textDescription +'</input><br>';
$("#PlaceHarmonizer" + devVersStr).append(phTempHTML);
//phlogdev(settingID + ' checkbox created');
//Associate click event of new checkbox to call saveSettingToLocalStorage with proper ID
$("#" + settingID).click(function() {saveSettingToLocalStorage(settingID);});
//phlogdev('Callback Set');
//Load Setting for Local Storage, if it doesn't exist set it to NOT checked.
//If previously set to 1, then trigger "click" event.
if (!localStorage.getItem(settingID))
{
//phlogdev(settingID + ' not found.');
} else if (localStorage.getItem(settingID) === "1") {
//phlogdev(settingID + ' = 1 so invoking click');
$("#" + settingID).trigger('click');
}
//phlogdev('Setting Checked');
}
// Save settings prefs
function saveSettingToLocalStorage(settingID) {
if ($("#" + settingID).prop('checked')) {
// phlogdev(settingID + ' to 1');
localStorage.setItem(settingID, '1');
} else {
// phlogdev(settingID + ' to 0');
localStorage.setItem(settingID, '0');
}
}
// Get services checkbox status
function getServicesChecks() {
var servArrayCheck = [];
for (var wsix=0; wsix<WMEServicesArray.length; wsix++) {
if ($("#service-checkbox-" + WMEServicesArray[wsix]).prop('checked')) {
servArrayCheck[wsix] = true;
} else {
servArrayCheck[wsix] = false;
}
}
return servArrayCheck;
}
function updateServicesChecks(bannServ) {
var servArrayCheck = getServicesChecks(), wsix=0;
for (var keys in bannServ) {
if (bannServ.hasOwnProperty(keys)) {
bannServ[keys].checked = servArrayCheck[wsix]; // reset all icons to match any checked changes
bannServ[keys].active = bannServ[keys].active || servArrayCheck[wsix]; // display any manually checked non-active icons
wsix++;
}
}
}
// Focus away from the current cursor focus, to set text box changes
function blurAll() {
var tmp = document.createElement("input");
document.body.appendChild(tmp);
tmp.focus();
document.body.removeChild(tmp);
}
// Sets up a div for submitting forms
function WMEPH_initialiseFL() {
var wmephlinks = WMEPH_getId("WMEPH-forumlink");
var mapFooter = WMEPH_getElementsByClassName("WazeControlPermalink");
if (mapFooter.length === 0) {
phlog("Error, can't find permalink container");
setTimeout(WMEPH_initialiseFL, 1000);
return;
}
var WMEPH_divPerma = mapFooter[0];
var WMEPH_aPerma = null;
for (var i = 0; i < WMEPH_divPerma.children.length; i++) {
if (WMEPH_divPerma.children[i].className === 'icon-link') {
WMEPH_aPerma = WMEPH_divPerma.children[i];
break;
}
if (WMEPH_divPerma.children[i].className === 'fa fa-link') {
WMEPH_aPerma = WMEPH_divPerma.children[i];
break;
}
}
//WMEPH_aPerma.style.display = 'none';
if (wmephlinks !== null) {return WMEPH_aPerma.href;}
var WMEPH_nodeWMEPH = document.createElement('div');
WMEPH_nodeWMEPH.id = 'WMEPH-forumlink';
WMEPH_nodeWMEPH.style.display = 'inline';
WMEPH_divPerma.appendChild(WMEPH_nodeWMEPH);
return WMEPH_aPerma.href;
} // END WMEPH_initialiseFL function
function WMEPH_getElementsByClassName(classname, node) { // Get element by class name
if (!node) {node = document.getElementsByTagName("body")[0];}
var a = [];
var re = new RegExp('\\b' + classname + '\\b');
var els = node.getElementsByTagName("*");
for (var i = 0, j = els.length; i < j; i++) {
if (re.test(els[i].className)) { a.push(els[i]); }
}
return a;
} // END WMEPH_getElementsByClassName function
function WMEPH_getId(node) { // getID function
return document.getElementById(node);
}
// Make a populated post on a forum thread
function WMEPH_openPostDataInNewTab(url, data) {
var form = document.createElement('form');
form.target = '_blank';
form.action = url;
form.method = 'post';
form.style.display = 'none';
for (var k in data) {
if (data.hasOwnProperty(k)) {
var input;
if (k === 'message') {
input = document.createElement('textarea');
} else if (k === 'username') {
input = document.createElement('username_list');
} else {
input = document.createElement('input');
}
input.name = k;
input.value = data[k];
input.type = 'hidden';
form.appendChild(input);
}
}
WMEPH_getId('WMEPH-forumlink').appendChild(form);
form.submit();
WMEPH_getId('WMEPH-forumlink').removeChild(form);
return true;
} // END WMEPH_openPostDataInNewTab function
// Function that checks current place against the Harmonization Data. Returns place data or "NoMatch"
function harmoList(itemName,state2L,region3L,country,itemCats) {
var PNH_DATA_headers;
var ixendPNH_NAMES;
if (country === 'USA') {
PNH_DATA_headers = USA_PNH_DATA[0].split("|"); // pull the data header names
ixendPNH_NAMES = USA_PNH_NAMES.length;
} else if (country === 'CAN') {
PNH_DATA_headers = CAN_PNH_DATA[0].split("|"); // pull the data header names
ixendPNH_NAMES = CAN_PNH_NAMES.length;
} else {
alert("No PNH data exists for this country.");
return;
}
var ph_name_ix = PNH_DATA_headers.indexOf("ph_name");
var ph_category1_ix = PNH_DATA_headers.indexOf("ph_category1");
var ph_forcecat_ix = PNH_DATA_headers.indexOf("ph_forcecat"); // Force the category match
var ph_region_ix = PNH_DATA_headers.indexOf("ph_region"); // Find the index for regions
var ph_order_ix = PNH_DATA_headers.indexOf("ph_order");
var nameComps; // filled with search names to compare against place name
var PNHPriCat; // Primary category of PNH data
var PNHForceCat; // Primary category of PNH data
var approvedRegions; // filled with the regions that are approved for the place, when match is found
var matchPNHData = []; // array of matched data
var currMatchData;
var currMatchNum = 0; // index for multiple matches, currently returns on first match
var PNHOrderNum;
var PNHNameTemp;
var PNHNameMatch = false; // tracks match status
var PNHMatchProceed; // tracks match status
itemName = itemName.toUpperCase(); // UpperCase the current place name (The Holly And Ivy Pub #23 --> THE HOLLY AND IVY PUB #23 )
itemName = itemName.replace(/ AND /g, ''); // Clear the word " AND " from the name (THE HOLLY AND IVY PUB #23 --> THE HOLLYIVY PUB #23 )
itemName = itemName.replace(/^THE /g, ''); // Clear the word "THE " from the start of the name ( THE HOLLYIVY PUB #23 -- > HOLLYIVY PUB #23 )
itemName = itemName.replace(/[^A-Z0-9]/g, ''); // Clear all non-letter and non-number characters ( HOLLYIVY PUB #23 -- > HOLLYIVYPUB23 )
var itemNameNoNum = itemName.replace(/[^A-Z]/g, ''); // Clear non-letter characters for alternate match ( HOLLYIVYPUB23 --> HOLLYIVYPUB )
// Search performance stats
var t0; var t1;
if (devUser) {
t0 = performance.now(); // Speed check start
}
// for each place on the PNH list (skipping headers at index 0)
// phlogdev(ixendPNH_NAMES);
for (var phnum=1; phnum<ixendPNH_NAMES; phnum++) {
PNHMatchProceed = false;
if (country === 'USA') {
nameComps = USA_PNH_NAMES[phnum].split("|"); // splits all possible search names for the current PNH entry
} else if (country === 'CAN') {
nameComps = CAN_PNH_NAMES[phnum].split("|"); // splits all possible search names for the current PNH entry
}
if ( nameComps.indexOf(itemName) > -1 || nameComps.indexOf(itemNameNoNum) > -1 ) { // Compare WME place name to PNH search name list
if (country === 'USA') {
matchPNHData[currMatchNum] = USA_PNH_DATA[phnum]; // Pull the data line from the PNH data table. (**Set in array for future multimatch features)
} else if (country === 'CAN') {
matchPNHData[currMatchNum] = CAN_PNH_DATA[phnum]; // Pull the data line from the PNH data table. (**Set in array for future multimatch features)
}
currMatchData = matchPNHData[currMatchNum].split("|"); // Split the PNH place data into string array
PNHPriCat = catTranslate(currMatchData[ph_category1_ix]);
PNHForceCat = currMatchData[ph_forcecat_ix];
if (itemCats[0] === "GAS_STATION") { // Gas stations only harmonized if the WME place category is already gas station (prevents Costco Gas becoming Costco Store)
PNHForceCat = "1";
}
if ( PNHForceCat === "1" && itemCats.indexOf(PNHPriCat) === 0 ) { // Name and primary category match
PNHMatchProceed = true;
} else if ( PNHForceCat === "2" && itemCats.indexOf(PNHPriCat) > -1 ) { // Name and any category match
PNHMatchProceed = true;
} else if ( PNHForceCat === "0" || PNHForceCat === "") { // Name only match
PNHMatchProceed = true;
}
if (PNHMatchProceed) {
PNHNameMatch = true; // PNH match found (once true, stays true)
PNHNameTemp = currMatchData[ph_name_ix]; // temp name for approval return
PNHOrderNum = currMatchData[ph_order_ix]; // temp order number for approval return
approvedRegions = currMatchData[ph_region_ix].replace(/ /g, ''); // remove spaces from region field
approvedRegions = approvedRegions.toUpperCase().split(","); // upper case the approved regions and split by commas
if (approvedRegions.indexOf(state2L) > -1 || approvedRegions.indexOf(region3L) > -1 || // if the WME-selected item matches the region
approvedRegions.indexOf(country) > -1 || // OR if the country code is in the data then it is approved for all regions therein
$("#WMEPH-RegionOverride" + devVersStr).prop('checked')) { // OR if region override is selected
if (devUser) {
t1 = performance.now(); // log search time
phlogdev("Found place in " + (t1 - t0) + " milliseconds.");
}
bannMess.placeMatched.active = true;
return currMatchData; // Return the PNH data string array to the main script
}
currMatchNum++; // *** Multiple matches for future work
}
}
} // END loop through PNH places
// If NO (name & region) match was found:
if (PNHNameMatch) { // if a name match was found but not for region, prod the user to get it approved
bannButt.ApprovalSubmit.active = true;
phlogdev("PNH data exists but not approved for this area.");
if (devUser) {
t1 = performance.now(); // log search time
phlogdev("Searched all PNH entries in " + (t1 - t0) + " milliseconds.");
}
return ["ApprovalNeeded", PNHNameTemp, PNHOrderNum];
} else { // if no match was found, suggest adding the place to the sheet if it's a chain
bannButt.NewPlaceSubmit.active = true;
phlogdev("Place not found in the " + country + " PNH list.");
if (devUser) {
t1 = performance.now(); // log search time
phlogdev("Searched all PNH entries in " + (t1 - t0) + " milliseconds.");
}
return ["NoMatch"];
}
} // END harmoList function
// KB Shortcut object
var shortcut = {
'all_shortcuts': {}, //All the shortcuts are stored in this array
'add': function(shortcut_combination, callback, opt) {
//Provide a set of default options
var default_options = { 'type': 'keydown', 'propagate': false, 'disable_in_input': false, 'target': document, 'keycode': false };
if (!opt) {opt = default_options;}
else {
for (var dfo in default_options) {
if (typeof opt[dfo] === 'undefined') {opt[dfo] = default_options[dfo];}
}
}
var ele = opt.target;
if (typeof opt.target === 'string') {ele = document.getElementById(opt.target);}
// var ths = this;
shortcut_combination = shortcut_combination.toLowerCase();
//The function to be called at keypress
var func = function(e) {
e = e || window.event;
if (opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields
var element;
if (e.target) {element = e.target;}
else if (e.srcElement) {element = e.srcElement;}
if (element.nodeType === 3) {element = element.parentNode;}
if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {return;}
}
//Find Which key is pressed
var code;
if (e.keyCode) {code = e.keyCode;}
else if (e.which) {code = e.which;}
var character = String.fromCharCode(code).toLowerCase();
if (code === 188) {character = ",";} //If the user presses , when the type is onkeydown
if (code === 190) {character = ".";} //If the user presses , when the type is onkeydown
var keys = shortcut_combination.split("+");
//Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
var kp = 0;
//Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
var shift_nums = { "`": "~","1": "!","2": "@","3": "#","4": "$","5": "%","6": "^","7": "&",
"8": "*","9": "(","0": ")","-": "_","=": "+",";": ":","'": "\"",",": "<",".": ">","/": "?","\\": "|" };
//Special Keys - and their codes
var special_keys = { 'esc': 27,'escape': 27,'tab': 9,'space': 32,'return': 13,'enter': 13,'backspace': 8,'scrolllock': 145,
'scroll_lock': 145,'scroll': 145,'capslock': 20,'caps_lock': 20,'caps': 20,'numlock': 144,'num_lock': 144,'num': 144,
'pause': 19,'break': 19,'insert': 45,'home': 36,'delete': 46,'end': 35,'pageup': 33,'page_up': 33,'pu': 33,'pagedown': 34,
'page_down': 34,'pd': 34,'left': 37,'up': 38,'right': 39,'down': 40,'f1': 112,'f2': 113,'f3': 114,'f4': 115,'f5': 116,
'f6': 117,'f7': 118,'f8': 119,'f9': 120,'f10': 121,'f11': 122,'f12': 123 };
var modifiers = {
shift: { wanted: false, pressed: false },
ctrl: { wanted: false, pressed: false },
alt: { wanted: false, pressed: false },
meta: { wanted: false, pressed: false } //Meta is Mac specific
};
if (e.ctrlKey) {modifiers.ctrl.pressed = true;}
if (e.shiftKey) {modifiers.shift.pressed = true;}
if (e.altKey) {modifiers.alt.pressed = true;}
if (e.metaKey) {modifiers.meta.pressed = true;}
var k;
for (var i = 0; k = keys[i], i < keys.length; i++) {
//Modifiers
if (k === 'ctrl' || k === 'control') {
kp++;
modifiers.ctrl.wanted = true;
} else if (k === 'shift') {
kp++;
modifiers.shift.wanted = true;
} else if (k === 'alt') {
kp++;
modifiers.alt.wanted = true;
} else if (k === 'meta') {
kp++;
modifiers.meta.wanted = true;
} else if (k.length > 1) { //If it is a special key
if (special_keys[k] === code) {kp++;}
} else if (opt['keycode']) {
if (opt['keycode'] === code) {kp++;}
} else { //The special keys did not match
if (character === k) {kp++;}
else {
if (shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase
character = shift_nums[character];
if (character === k) {kp++;}
}
}
}
}
if (kp === keys.length && modifiers.ctrl.pressed === modifiers.ctrl.wanted && modifiers.shift.pressed === modifiers.shift.wanted &&
modifiers.alt.pressed === modifiers.alt.wanted && modifiers.meta.pressed === modifiers.meta.wanted) {
callback(e);
if (!opt['propagate']) { //Stop the event
//e.cancelBubble is supported by IE - this will kill the bubbling process.
e.cancelBubble = true;
e.returnValue = false;
//e.stopPropagation works in Firefox.
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
return false;
}
}
};
this.all_shortcuts[shortcut_combination] = { 'callback': func, 'target': ele, 'event': opt['type'] };
//Attach the function with the event
if (ele.addEventListener) {ele.addEventListener(opt['type'], func, false);}
else if (ele.attachEvent) {ele.attachEvent('on' + opt['type'], func);}
else {ele['on' + opt['type']] = func;}
},
//Remove the shortcut - just specify the shortcut and I will remove the binding
'remove': function(shortcut_combination) {
shortcut_combination = shortcut_combination.toLowerCase();
var binding = this.all_shortcuts[shortcut_combination];
delete(this.all_shortcuts[shortcut_combination]);
if (!binding) {return;}
var type = binding['event'];
var ele = binding['target'];
var callback = binding['callback'];
if (ele.detachEvent) {ele.detachEvent('on' + type, callback);}
else if (ele.removeEventListener) {ele.removeEventListener(type, callback, false);}
else {ele['on' + type] = false;}
}
}; // END Shortcut function
function phlogdev(m) {
if (devUser) {
console.log('WMEPH' + devVersStrDash + ': ' + m);
}
}
} // END runPH Function
// This function runs at script load, and splits the category dataset into the searchable categories.
function makeCatCheckList(CH_DATA) { // Builds the list of search names to match to the WME place name
var CH_CATS = [];
var CH_DATA_headers = CH_DATA[0].split("|"); // split the data headers out
var pc_wmecat_ix = CH_DATA_headers.indexOf("pc_wmecat"); // find the indices needed for the function
var chEntryTemp;
for (var chix=0; chix<CH_DATA.length; chix++) { // loop through all PNH places
chEntryTemp = CH_DATA[chix].split("|"); // split the current PNH data line
CH_CATS.push(chEntryTemp[pc_wmecat_ix]);
}
return CH_CATS;
} // END makeCatCheckList function
// This function runs at script load, and builds the search name dataset to compare the WME selected place name to.
function makeNameCheckList(PNH_DATA) { // Builds the list of search names to match to the WME place name
var PNH_NAMES = [];
var PNH_DATA_headers = PNH_DATA[0].split("|"); // split the data headers out
var ph_name_ix = PNH_DATA_headers.indexOf("ph_name"); // find the indices needed for the function
var ph_category1_ix = PNH_DATA_headers.indexOf("ph_category1");
var ph_searchnamebase_ix = PNH_DATA_headers.indexOf("ph_searchnamebase");
var ph_searchnamemid_ix = PNH_DATA_headers.indexOf("ph_searchnamemid");
var ph_searchnameend_ix = PNH_DATA_headers.indexOf("ph_searchnameend");
var ph_disable_ix = PNH_DATA_headers.indexOf("ph_disable");
var t0 = performance.now(); // Speed check start
var newNameListLength; // static list length
for (var pnhix=0; pnhix<PNH_DATA.length; pnhix++) { // loop through all PNH places
var pnhEntryTemp = PNH_DATA[pnhix].split("|"); // split the current PNH data line
if (pnhEntryTemp[ph_disable_ix] !== "1") {
var newNameList = pnhEntryTemp[ph_name_ix].toUpperCase(); // pull out the primary PNH name & upper case it
newNameList = newNameList.replace(/ AND /g, ''); // Clear the word "AND" from the name
newNameList = newNameList.replace(/^THE /g, ''); // Clear the word "THE" from the start of the name
newNameList = [newNameList.replace(/[^A-Z0-9]/g, '')]; // Clear non-letter and non-number characters, store in array
// The following code sets up alternate search names as outlined in the PNH dataset.
// Formula, with P = primary; B1, B2 = base terms; M1, M2 = mid terms; E1, E2 = end terms
// Search list will build: P, B, PM, BM, PE, BE, PME, BME.
// Multiple M terms are applied singly and in pairs (B1M2M1E2). Multiple B and E terms are applied singly (e.g B1B2M1 not used).
// Any doubles like B1E2=P are purged at the end to reduce search times.
if (pnhEntryTemp[ph_searchnamebase_ix] !== "0") { // If base terms exist, otherwise only the primary name is matched
var pnhSearchNameBase = pnhEntryTemp[ph_searchnamebase_ix].replace(/[^A-Za-z0-9,]/g, ''); // clear non-letter and non-number characters (keep commas)
pnhSearchNameBase = pnhSearchNameBase.toUpperCase().split(","); // upper case and split the base-name list
newNameList.push.apply(newNameList,pnhSearchNameBase); // add them to the search list
if (pnhEntryTemp[ph_searchnamemid_ix] !== "0") { // if middle search term add-ons exist
var pnhSearchNameMid = pnhEntryTemp[ph_searchnamemid_ix].replace(/[^A-Za-z0-9,]/g, ''); // clear non-letter and non-number characters
pnhSearchNameMid = pnhSearchNameMid.toUpperCase().split(","); // upper case and split
if (pnhSearchNameMid.length > 1) { // if there are more than one mid terms, it adds a permutation of the first 2
pnhSearchNameMid.push.apply( pnhSearchNameMid,[ pnhSearchNameMid[0]+pnhSearchNameMid[1],pnhSearchNameMid[1]+pnhSearchNameMid[0] ] );
}
newNameListLength = newNameList.length;
for (var extix=1; extix<newNameListLength; extix++) { // extend the list by adding Mid terms onto the SearchNameBase names
for (var altix=0; altix<pnhSearchNameMid.length; altix++) {
newNameList.push(newNameList[extix]+pnhSearchNameMid[altix] );
}
}
}
if (pnhEntryTemp[ph_searchnameend_ix] !== "0") { // if end search term add-ons exist
var pnhSearchNameEnd = pnhEntryTemp[ph_searchnameend_ix].replace(/[^A-Za-z0-9,]/g, ''); // clear non-letter and non-number characters
pnhSearchNameEnd = pnhSearchNameEnd.toUpperCase().split(","); // upper case and split
newNameListLength = newNameList.length;
for (var exetix=1; exetix<newNameListLength; exetix++) { // extend the list by adding End terms onto all the SearchNameBase & Base+Mid names
for (var aletix=0; aletix<pnhSearchNameEnd.length; aletix++) {
newNameList.push(newNameList[exetix]+pnhSearchNameEnd[aletix] );
}
}
}
}
// Next, add extensions to the search names based on the WME place category
newNameListLength = newNameList.length;
var catix;
if (pnhEntryTemp[ph_category1_ix].toUpperCase().replace(/[^A-Za-z0-9]/g, '') === "HOTEL") {
for ( catix=0; catix<newNameListLength; catix++) { // extend the list by adding Hotel to all items
newNameList.push(newNameList[catix]+"HOTEL");
}
} else if (pnhEntryTemp[ph_category1_ix].toUpperCase().replace(/[^A-Za-z0-9]/g, '') === "BANKFINANCIAL") {
for ( catix=0; catix<newNameListLength; catix++) { // extend the list by adding Bank and ATM to all items
newNameList.push(newNameList[catix]+"BANK");
newNameList.push(newNameList[catix]+"ATM");
}
} else if (pnhEntryTemp[ph_category1_ix].toUpperCase().replace(/[^A-Za-z0-9]/g, '') === "SUPERMARKETGROCERY") {
for ( catix=0; catix<newNameListLength; catix++) { // extend the list by adding Supermarket to all items
newNameList.push(newNameList[catix]+"SUPERMARKET");
}
} else if (pnhEntryTemp[ph_category1_ix].toUpperCase().replace(/[^A-Za-z0-9]/g, '') === "GYMFITNESS") {
for ( catix=0; catix<newNameListLength; catix++) { // extend the list by adding Gym to all items
newNameList.push(newNameList[catix]+"GYM");
}
} else if (pnhEntryTemp[ph_category1_ix].toUpperCase().replace(/[^A-Za-z0-9]/g, '') === "GASSTATION") {
for ( catix=0; catix<newNameListLength; catix++) { // extend the list by adding Gas terms to all items
newNameList.push(newNameList[catix]+"GAS");
newNameList.push(newNameList[catix]+"GASOLINE");
newNameList.push(newNameList[catix]+"FUEL");
newNameList.push(newNameList[catix]+"GASSTATION");
}
} else if (pnhEntryTemp[ph_category1_ix].toUpperCase().replace(/[^A-Za-z0-9]/g, '') === "CARRENTAL") {
for ( catix=0; catix<newNameListLength; catix++) { // extend the list by adding Car Rental terms to all items
newNameList.push(newNameList[catix]+"RENTAL");
newNameList.push(newNameList[catix]+"RENTACAR");
newNameList.push(newNameList[catix]+"CARRENTAL");
newNameList.push(newNameList[catix]+"RENTALCAR");
}
}
newNameList = uniq(newNameList); // remove any duplicate search names
newNameList = newNameList.join("|"); // join the list with |
PNH_NAMES.push(newNameList); // push the list to the master search list
} else { // END if valid line
PNH_NAMES.push('00');
}
}
var t1 = performance.now(); // log search time
phlog("Built search list of " + PNH_DATA.length + " PNH places in " + (t1 - t0) + " milliseconds.");
return PNH_NAMES;
} // END makeNameCheckList
// Removes duplicate strings from string array
function uniq(a) {
"use strict";
var seen = {};
return a.filter(function(item) {
return seen.hasOwnProperty(item) ? false : (seen[item] = true);
});
} // END uniq function
function phlog(m) {
console.log('WMEPH' + devVersStrDash + ': ' + m);
}
placeHarmonizer_bootstrap();
})();
// var DLscript = document.createElement("script");
// DLscript.textContent = runPH.toString() + ' \n' + 'runPH();';
// DLscript.setAttribute("type", "application/javascript");
// document.body.appendChild(DLscript);// JavaScript Document